sound pt1

master
darkrose 2017-06-19 03:56:34 +10:00
parent 5d519799e6
commit 81cf0e0719
31 changed files with 1131 additions and 217 deletions

View File

@ -46,7 +46,7 @@ if(SOUND_PROBLEM)
"To continue, either fill in the required paths or disable sound. (-DENABLE_AUDIO=0)")
endif()
if(USE_AUDIO)
set(audio_SRCS sound.cpp sound_openal.cpp)
set(audio_SRCS sound.c sound_ogg.c sound_wav.c)
set(AUDIO_INCLUDE_DIRS
${OPENAL_INCLUDE_DIR}
${VORBIS_INCLUDE_DIR}
@ -56,8 +56,6 @@ if(USE_AUDIO)
${OPENAL_LIBRARY}
${VORBIS_LIBRARIES}
)
else()
set(audio_SRCS sound.cpp)
endif()
option(ENABLE_FREETYPE "Enable freetype2 (truetype fonts and basic unicode support)" ON)
@ -279,7 +277,6 @@ set(voxelands_SRCS
# Server sources
set(voxelandsserver_SRCS
${common_SRCS}
${audio_SRCS}
servermain.cpp
)
@ -415,7 +412,7 @@ else()
set(CMAKE_CXX_FLAGS_RELEASE "${OPT_FLAGS} ${SAFETY_FLAGS} -Wall -DNDEBUG -pipe -fpermissive -Wno-write-strings")
set(CMAKE_C_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
set(CMAKE_C_FLAGS_RELEASE "${OPT_FLAGS} ${SAFETY_FLAGS} -Wall -DNDEBUG -pipe -ansi -pedantic")
set(CMAKE_CXX_FLAGS_DEBUG "${SAFETY_FLAGS} -Wall -O0 -g3 -ggdb -fpermissive -Wno-write-strings")
set(CMAKE_C_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})

View File

@ -17,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#include "array.h"
#include <stdlib.h>

View File

@ -17,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#include "ban.h"
#include "file.h"

View File

@ -202,8 +202,7 @@ void * MeshUpdateThread::Thread()
Client::Client(
IrrlichtDevice *device,
std::string password,
MapDrawControl &control,
ISoundManager *sound):
MapDrawControl &control):
m_mesh_update_thread(),
m_env(
this,
@ -216,7 +215,6 @@ Client::Client(
m_server_suffocation(false),
m_server_hunger(false),
m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
m_sound(sound),
m_device(device),
m_server_ser_ver(SER_FMT_VER_INVALID),
m_inventory_updated(false),
@ -1624,7 +1622,8 @@ void Client::useItem()
// Send as reliable
Send(0, data, true);
if (g_sound) {
#if USE_AUDIO == 1
{
InventoryItem *item = (InventoryItem*)m_env.getLocalPlayer()->getWieldItem();
if (!item)
return;
@ -1633,8 +1632,9 @@ void Client::useItem()
if ((w&CONTENT_CRAFTITEM_MASK) == CONTENT_CRAFTITEM_MASK)
snd = content_craftitem_features(w)->sound_use;
if (snd != "")
g_sound->playSound(snd,false);
sound_play_effect(snd.c_str(),1.0,NULL);
}
#endif
}
void Client::clickActiveObject(u8 button, u16 id, u16 item_i)
@ -2284,27 +2284,14 @@ float Client::getRTT(void)
}
}
ISoundManager* Client::getSoundManager()
{
if (m_sound == NULL)
return &dummySoundManager;
return m_sound;
}
// foot: 0 = left, 1 = right
void Client::playStepSound(int foot)
{
if (!g_sound)
return;
sound_playStep(&m_env.getMap(),m_env.getLocalPlayer()->getPosition(),foot);
//sound_playStep(&m_env.getMap(),m_env.getLocalPlayer()->getPosition(),foot);
}
void Client::playDigSound(content_t c)
{
if (!g_sound)
return;
if (c == CONTENT_IGNORE) {
c = getPointedContent();
if ((c&CONTENT_MOB_MASK) != 0)
@ -2313,41 +2300,37 @@ void Client::playDigSound(content_t c)
if (c == CONTENT_IGNORE)
c = CONTENT_AIR;
sound_playDig(c,m_env.getLocalPlayer()->getPosition());
//sound_playDig(c,m_env.getLocalPlayer()->getPosition());
}
void Client::playPlaceSound(content_t c)
{
if (!m_sound)
return;
if (c == CONTENT_IGNORE)
c = getPointedContent();
ContentFeatures *f = &content_features(c);
if (f->sound_place != "") {
m_sound->playSound(f->sound_place,false);
sound_play_effect((char*)f->sound_place.c_str(),1.0,NULL);
return;
}
switch (f->type) {
case CMT_LIQUID:
m_sound->playSound("liquid-place",false);
sound_play_effect("liquid-place",1.0,NULL);
break;
default:
m_sound->playSound("place",false);
sound_play_effect("place",1.0,NULL);
}
}
void Client::playSound(std::string &name, bool loop)
{
if (!m_sound)
return;
m_sound->playSound(name,loop);
/* TODO: looping */
sound_play_effect((char*)name.c_str(),1.0,NULL);
}
void Client::playSoundAt(std::string &name, v3f pos, bool loop)
{
if (!m_sound)
return;
m_sound->playSoundAt(name,loop,pos);
v3_t p = {pos.X,pos.Y,pos.Z};
/* TODO: looping */
sound_play_effect((char*)name.c_str(),1.0,&p);
}

View File

@ -170,8 +170,7 @@ public:
Client(
IrrlichtDevice *device,
std::string password,
MapDrawControl &control,
ISoundManager *sound
MapDrawControl &control
);
~Client();
@ -323,7 +322,6 @@ public:
}
float getRTT(void);
virtual ISoundManager* getSoundManager();
void playStepSound(int foot);
void playDigSound(content_t c);
@ -385,7 +383,6 @@ private:
bool m_server_hunger;
con::Connection m_con;
ISoundManager *m_sound;
IrrlichtDevice *m_device;

View File

@ -95,7 +95,7 @@ void config_set_float(char* name, float value);
void config_set_default(char* name, char* value, int (*setter)(char* v));
void config_set_default_int(char* name, int value, int (*setter)(char* v));
void config_set_default_float(char* name, float value, int (*setter)(char* v));
void config_load(char* file);
void config_load(char* type, char* file);
int config_load_command(command_context_t *ctx, array_t *args);
int config_ignore_command(command_context_t *ctx, array_t *args);
void config_init(int argc, char** argv);

View File

@ -241,14 +241,18 @@ void config_set_default_float(char* name, float value, int (*setter)(char* v))
}
/* load a config file */
void config_load(char* file)
void config_load(char* type, char* file)
{
char buff[2048];
int s;
char* l;
file_t *f;
command_context_t ctx;
file_t *f = file_load("config",file);
if (!type)
type = "config";
f = file_load(type,file);
if (!f)
return;
@ -284,7 +288,7 @@ int config_load_command(command_context_t *ctx, array_t *args)
f = array_get_string(args,0);
nvp_set(&config.files,f,"true",NULL);
config_load(f);
config_load("config",f);
return 0;
}
@ -332,7 +336,7 @@ void config_init(int argc, char** argv)
n = config.files;
while (n) {
if (n->value && !strcmp(n->value,"true"))
config_load(n->name);
config_load("config",n->name);
n = n->next;
}

View File

@ -19,6 +19,9 @@
#include "common.h"
#include "path.h"
#ifndef SERVER
#include "sound.h"
#endif
#include <string.h>
@ -53,7 +56,9 @@ void config_default_init()
config_set_default("client.video.driver","opengl",NULL);
config_set_default("client.video.hpfpu","true",NULL);
config_set_default("client.sound.volume","50",NULL);
config_set_default("client.sound.volume","50",sound_master_setter);
config_set_default("client.sound.volume.effects","50",sound_effects_setter);
config_set_default("client.sound.volume.music","50",sound_music_setter);
config_set_default("client.graphics.mesh.lod","3",NULL);
config_set_default("client.graphics.texture.animations","true",NULL);

View File

@ -272,7 +272,7 @@ void MobCAO::step(float dtime, ClientEnvironment *env)
/* roughly sort of when a step sound should probably be heard, maybe */
if (m_last_step > 0.5) {
m_last_step -= 0.5;
sound_playStep(&env->getMap(),m_position,m_next_foot, 0.3);
//sound_playStep(&env->getMap(),m_position,m_next_foot, 0.3);
m_next_foot = !m_next_foot;
}
}

View File

@ -17,6 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#include <stdlib.h>
#include <string.h>

View File

@ -17,6 +17,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#include "file.h"
#include "path.h"

View File

@ -642,8 +642,7 @@ void the_game(
IrrlichtDevice *device,
gui::IGUIFont* font,
std::string password,
std::wstring &error_message,
ISoundManager *sound
std::wstring &error_message
)
{
video::IVideoDriver* driver = device->getVideoDriver();
@ -689,7 +688,7 @@ void the_game(
drawLoadingScreen(device,narrow_to_wide(gettext("Creating client...")));
infostream<<"Creating client"<<std::endl;
MapDrawControl draw_control;
Client client(device, password, draw_control, sound);
Client client(device, password, draw_control);
bridge_register_client(&client);
@ -1482,12 +1481,6 @@ void the_game(
client.step(dtime);
}
#if USE_AUDIO == 1
{
sound->maintain(dtime);
}
#endif
{
// Read client events
while (1) {
@ -1499,7 +1492,8 @@ void the_game(
if (event.player_damage.amount >= 2) {
damage_flash_timer += 0.05 * event.player_damage.amount;
}
if (g_sound) {
#if USE_AUDIO == 1
{
char* v;
std::string ch = std::string(PLAYER_DEFAULT_CHARDEF);
v = config_get("client.character");
@ -1509,8 +1503,9 @@ void the_game(
std::string gender = f.next(":");
std::string snd("player-hurt-");
snd += gender;
g_sound->playSound(snd,false);
sound_play_effect((char*)snd.c_str(),1.0,NULL);
}
#endif
}else if (event.type == CE_PLAYER_FORCE_MOVE) {
camera_yaw = event.player_force_move.yaw;
camera_pitch = event.player_force_move.pitch;
@ -1541,16 +1536,18 @@ void the_game(
v3f player_position = player->getPosition();
v3f camera_position = camera.getPosition();
v3f camera_direction = camera.getDirection();
v3f camera_up = camera.getCameraNode()->getUpVector();
f32 camera_fov = camera.getFovMax();
v3s16 camera_offset = camera.getOffset();
#if USE_AUDIO == 1
{
ISoundManager *snd = client.getSoundManager();
if (snd)
snd->updateListener(camera_position,v3f(0,0,0),camera_direction,camera.getCameraNode()->getUpVector());
v3_t pos = {camera_position.X,camera_position.Y,camera_position.Z};
v3_t at = {camera_direction.X,camera_direction.Y,camera_direction.Z};
v3_t up = {camera_up.X,camera_up.Y,camera_up.Z};
sound_step(dtime,&pos,&at,&up);
}
//bool camera_offset_changed = (camera_offset != old_camera_offset);
#endif
if (!disable_camera_update) {
client.updateCamera(camera_position, camera_direction, camera_fov, camera_offset);

View File

@ -139,8 +139,7 @@ void the_game(
IrrlichtDevice *device,
gui::IGUIFont* font,
std::string password,
std::wstring &error_message,
ISoundManager *sound
std::wstring &error_message
);
#endif

View File

@ -52,15 +52,11 @@ GUIMainMenu::GUIMainMenu(gui::IGUIEnvironment* env,
gui::IGUIElement* parent, s32 id,
IMenuManager *menumgr,
MainMenuData *data,
IGameCallback *gamecallback,
ISoundManager *sound
IGameCallback *gamecallback
):
GUIModalMenu(env, parent, id, menumgr),
m_data(data),
m_accepted(false),
#if USE_SOUND == 1
m_sound(sound),
#endif
m_gamecallback(gamecallback)
{
assert(m_data);
@ -223,7 +219,7 @@ void GUIMainMenu::regenerateGui(v2u32 screensize)
txt += "\ndarkrose, sdzen, Menche, tiemay, JHeaton, MavJS, mcnalu.\n\n";
txt += gettext("Music and Sound Effects Composers");
txt += "\ndarkrose, Jordach, AudioRichter, OwlStorm, DjDust, Taira Komori.\n\n";
txt += "\ndarkrose, Jordach, AudioRichter, Tom Peter, OwlStorm, DjDust, Taira Komori.\n\n";
txt += gettext("Other Contributers, and Special Thanks");
txt += "\nnadnadnad, Honeypaw, tiemay, stormchaser3000, MichaelEh?, NCC74656.\n\n";
@ -362,6 +358,7 @@ bool GUIMainMenu::OnEvent(const SEvent& event)
acceptInput();
m_accepted = false;
m_data->selected_tab = TAB_CREDITS;
config_set("client.ui.mainmenu.tab","credits");
regenerateGui(m_screensize);
return true;
case GUI_ID_TAB_QUIT:

View File

@ -118,8 +118,7 @@ public:
gui::IGUIElement* parent, s32 id,
IMenuManager *menumgr,
MainMenuData *data,
IGameCallback *gamecallback,
ISoundManager *sound);
IGameCallback *gamecallback);
~GUIMainMenu();
void removeChildren();
@ -148,9 +147,6 @@ private:
MainMenuData *m_data;
bool m_accepted;
IGameCallback *m_gamecallback;
#if USE_SOUND == 1
ISoundManager *m_sound;
#endif
gui::IGUIEnvironment* env;
gui::IGUIElement* parent;

View File

@ -66,7 +66,9 @@ GUISettingsMenu::GUISettingsMenu(
m_data.trilinear_filter = config_get_bool("client.video.trilinear");
m_data.hotbar = config_get_bool("client.ui.hud.old");
m_data.wield_index = config_get_bool("client.ui.hud.wieldindex");
m_data.volume = config_get_float("client.sound.volume");
m_data.volume_master = config_get_float("client.sound.volume");
m_data.volume_effects = config_get_float("client.sound.volume.effects");
m_data.volume_music = config_get_float("client.sound.volume.music");
m_data.texture_animation = config_get_bool("client.graphics.texture.animations");
keynames[VLKC_FORWARD] = narrow_to_wide(gettext("Forward"));
@ -135,7 +137,6 @@ void GUISettingsMenu::save()
config_set_int("client.video.trilinear",m_data.trilinear_filter);
config_set_int("client.ui.hud.old",m_data.hotbar);
config_set_int("client.ui.hud.wieldindex",m_data.wield_index);
config_set_float("client.sound.volume",m_data.volume);
config_set_int("client.graphics.texture.animations",m_data.texture_animation);
Environment->getVideoDriver()->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, m_data.mip_map);
}
@ -154,7 +155,9 @@ void GUISettingsMenu::regenerateGui(v2u32 screensize)
bool hotbar;
bool wield_index;
bool texture_animation;
f32 volume;
f32 volume_master;
f32 volume_effects;
f32 volume_music;
m_screensize = screensize;
@ -285,11 +288,25 @@ void GUISettingsMenu::regenerateGui(v2u32 screensize)
wield_index = m_data.wield_index;
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_VOLUME_SB);
gui::IGUIElement *e = getElementFromId(GUI_ID_VOLUME_MASTER_SB);
if(e != NULL && e->getType() == gui::EGUIET_SCROLL_BAR)
volume = (float)((gui::IGUIScrollBar*)e)->getPos();
volume_master = (float)((gui::IGUIScrollBar*)e)->getPos();
else
volume = m_data.volume;
volume_master = m_data.volume_master;
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_VOLUME_EFFECTS_SB);
if(e != NULL && e->getType() == gui::EGUIET_SCROLL_BAR)
volume_effects = (float)((gui::IGUIScrollBar*)e)->getPos();
else
volume_effects = m_data.volume_effects;
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_VOLUME_MUSIC_SB);
if(e != NULL && e->getType() == gui::EGUIET_SCROLL_BAR)
volume_music = (float)((gui::IGUIScrollBar*)e)->getPos();
else
volume_music = m_data.volume_music;
}
/*
Remove stuff
@ -534,15 +551,41 @@ void GUISettingsMenu::regenerateGui(v2u32 screensize)
{
core::rect<s32> rect(0, 0, 200, 15);
rect += topleft_content + v2s32(80, 60);
Environment->addStaticText(narrow_to_wide(gettext("Volume:")).c_str(), rect, false, false, this, -1);
Environment->addStaticText(narrow_to_wide(gettext("Master Volume:")).c_str(), rect, false, false, this, -1);
}
{
core::rect<s32> rect(0, 0, 200, 15);
rect += topleft_content + v2s32(290, 60);
gui::IGUIScrollBar *sb = Environment->addScrollBar(true, rect, this, GUI_ID_VOLUME_SB);
gui::IGUIScrollBar *sb = Environment->addScrollBar(true, rect, this, GUI_ID_VOLUME_MASTER_SB);
sb->setMin(0);
sb->setMax(100);
sb->setPos(volume);
sb->setPos(volume_master);
}
{
core::rect<s32> rect(0, 0, 200, 15);
rect += topleft_content + v2s32(80, 90);
Environment->addStaticText(narrow_to_wide(gettext("Effects Volume:")).c_str(), rect, false, false, this, -1);
}
{
core::rect<s32> rect(0, 0, 200, 15);
rect += topleft_content + v2s32(290, 90);
gui::IGUIScrollBar *sb = Environment->addScrollBar(true, rect, this, GUI_ID_VOLUME_EFFECTS_SB);
sb->setMin(0);
sb->setMax(100);
sb->setPos(volume_effects);
}
{
core::rect<s32> rect(0, 0, 200, 15);
rect += topleft_content + v2s32(80, 120);
Environment->addStaticText(narrow_to_wide(gettext("Music Volume:")).c_str(), rect, false, false, this, -1);
}
{
core::rect<s32> rect(0, 0, 200, 15);
rect += topleft_content + v2s32(290, 120);
gui::IGUIScrollBar *sb = Environment->addScrollBar(true, rect, this, GUI_ID_VOLUME_MUSIC_SB);
sb->setMin(0);
sb->setMax(100);
sb->setPos(volume_music);
}
}
}
@ -693,9 +736,19 @@ bool GUISettingsMenu::acceptInput()
m_data.wield_index = ((gui::IGUICheckBox*)e)->isChecked();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_VOLUME_SB);
gui::IGUIElement *e = getElementFromId(GUI_ID_VOLUME_MASTER_SB);
if(e != NULL && e->getType() == gui::EGUIET_SCROLL_BAR)
m_data.volume = (float)((gui::IGUIScrollBar*)e)->getPos();
m_data.volume_master = (float)((gui::IGUIScrollBar*)e)->getPos();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_VOLUME_EFFECTS_SB);
if(e != NULL && e->getType() == gui::EGUIET_SCROLL_BAR)
m_data.volume_effects = (float)((gui::IGUIScrollBar*)e)->getPos();
}
{
gui::IGUIElement *e = getElementFromId(GUI_ID_VOLUME_MUSIC_SB);
if(e != NULL && e->getType() == gui::EGUIET_SCROLL_BAR)
m_data.volume_music = (float)((gui::IGUIScrollBar*)e)->getPos();
}
return true;
}
@ -794,15 +847,34 @@ bool GUISettingsMenu::OnEvent(const SEvent& event)
}
if (event.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED) {
switch (event.GUIEvent.Caller->getID()) {
case GUI_ID_VOLUME_SB:
gui::IGUIElement *vsb = getElementFromId(GUI_ID_VOLUME_SB);
case GUI_ID_VOLUME_MASTER_SB:
{
gui::IGUIElement *vsb = getElementFromId(GUI_ID_VOLUME_MASTER_SB);
if(vsb != NULL && vsb->getType() == gui::EGUIET_SCROLL_BAR) {
m_data.volume = (float)((gui::IGUIScrollBar*)vsb)->getPos();
if (g_sound)
g_sound->setListenerGain(m_data.volume/100.0);
m_data.volume_master = (float)((gui::IGUIScrollBar*)vsb)->getPos();
config_set_int("client.sound.volume",m_data.volume_master);
}
return true;
}
case GUI_ID_VOLUME_EFFECTS_SB:
{
gui::IGUIElement *vsb = getElementFromId(GUI_ID_VOLUME_EFFECTS_SB);
if(vsb != NULL && vsb->getType() == gui::EGUIET_SCROLL_BAR) {
m_data.volume_effects = (float)((gui::IGUIScrollBar*)vsb)->getPos();
config_set_int("client.sound.volume.effects",m_data.volume_effects);
}
return true;
}
case GUI_ID_VOLUME_MUSIC_SB:
{
gui::IGUIElement *vsb = getElementFromId(GUI_ID_VOLUME_MUSIC_SB);
if(vsb != NULL && vsb->getType() == gui::EGUIET_SCROLL_BAR) {
m_data.volume_music = (float)((gui::IGUIScrollBar*)vsb)->getPos();
config_set_int("client.sound.volume.music",m_data.volume_music);
}
return true;
}
}
}
if (event.GUIEvent.EventType == gui::EGET_COMBO_BOX_CHANGED) {
switch (event.GUIEvent.Caller->getID()) {

View File

@ -64,7 +64,9 @@ enum
GUI_ID_PARTICLES_CB,
GUI_ID_FULLSCREEN_CB,
// sound
GUI_ID_VOLUME_SB,
GUI_ID_VOLUME_MASTER_SB,
GUI_ID_VOLUME_EFFECTS_SB,
GUI_ID_VOLUME_MUSIC_SB,
// tabs
GUI_ID_TAB_MAINMENU,
GUI_ID_TAB_SETTINGS_CONTROLS,
@ -93,7 +95,9 @@ struct SettingsMenuData
light_detail(3),
hotbar(false),
wield_index(false),
volume(0.0f),
volume_master(0.0f),
volume_effects(0.0f),
volume_music(0.0f),
particles(true),
fullscreen(false),
texture_animation(true)
@ -113,7 +117,9 @@ struct SettingsMenuData
bool trilinear_filter;
bool hotbar;
bool wield_index;
f32 volume;
f32 volume_master;
f32 volume_effects;
f32 volume_music;
//int enable_shaders;
bool particles;
bool fullscreen;

View File

@ -16,6 +16,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#include "file.h"
#include "crypto.h"

View File

@ -10,7 +10,7 @@ char* ngettext(const char* s1, const char* s2, int n);
void intl_init();
#ifndef SERVER
// Initialise KeyNamesLang array
/* Initialise KeyNamesLang array */
void init_KeyNamesLang();
#endif

View File

@ -79,6 +79,7 @@
#if USE_FREETYPE
#include "xCGUITTFont.h"
#endif
#include "sound.h"
// This makes textures
ITextureSource *g_texturesource = NULL;
@ -826,8 +827,6 @@ int main(int argc, char *argv[])
// (for texture atlas making)
init_mineral();
ISoundManager *sound = NULL;
/*
Game parameters
*/
@ -849,6 +848,8 @@ int main(int argc, char *argv[])
// Run server
dedicated_server_loop(server, kill);
config_save(NULL,NULL,NULL);
return 0;
}
@ -862,8 +863,6 @@ int main(int argc, char *argv[])
u16 screenW = config_get_int("client.video.size.width");
u16 screenH = config_get_int("client.video.size.height");
vlprintf(CN_INFO,"size %dx%d",screenW,screenH);
// bpp, fsaa, vsync
bool vsync = config_get_bool("client.video.vsync");
@ -989,7 +988,7 @@ int main(int argc, char *argv[])
drawLoadingScreen(device,narrow_to_wide(gettext("Setting Up Sound")));
#if USE_AUDIO == 1
sound = createSoundManager();
sound_init();
#endif
/*
@ -1084,8 +1083,7 @@ int main(int argc, char *argv[])
-1,
&g_menumgr,
&menudata,
g_gamecallback,
sound
g_gamecallback
);
menu->allowFocusRemoval(true);
@ -1105,7 +1103,7 @@ int main(int argc, char *argv[])
infostream<<"Created main menu"<<std::endl;
#if USE_AUDIO == 1
sound->playMusic("bg-mainmenu",true);
sound_play_music("bg-mainmenu",1.0);
#endif
while (device->run() && kill == false) {
@ -1126,7 +1124,7 @@ int main(int argc, char *argv[])
driver->endScene();
#if USE_AUDIO == 1
sound->maintain(0.02);
sound_step(0.02,NULL,NULL,NULL);
#endif
// On some computers framerate doesn't seem to be
@ -1135,7 +1133,7 @@ int main(int argc, char *argv[])
}
#if USE_AUDIO == 1
sound->stopMusic();
sound_stop_music(1.0);
#endif
// Break out of menu-game loop to shut down cleanly
@ -1210,7 +1208,7 @@ int main(int argc, char *argv[])
menu->allowFocusRemoval(true);
#if USE_AUDIO == 1
sound->playMusic("bg-charcreator",true);
sound_play_music("bg-charcreator",1.0);
#endif
while (device->run() && kill == false) {
@ -1225,7 +1223,7 @@ int main(int argc, char *argv[])
driver->endScene();
#if USE_AUDIO == 1
sound->maintain(0.02);
sound_step(0.02,NULL,NULL,NULL);
#endif
// On some computers framerate doesn't seem to be
@ -1234,7 +1232,7 @@ int main(int argc, char *argv[])
}
#if USE_AUDIO == 1
sound->stopMusic();
sound_stop_music(1.0);
#endif
menu->drop();
@ -1253,8 +1251,7 @@ int main(int argc, char *argv[])
device,
font,
password,
error_message,
sound
error_message
);
} //try
@ -1285,8 +1282,9 @@ int main(int argc, char *argv[])
delete input;
if (sound != NULL)
delete sound;
#if USE_AUDIO == 1
sound_exit();
#endif
/*
In the end, delete the Irrlicht device.

View File

@ -1693,6 +1693,8 @@ ServerMap::ServerMap():
char b[1024];
infostream<<__FUNCTION_NAME<<std::endl;
config_load("world","world.cfg");
loadMapMeta();
/*

View File

@ -74,11 +74,11 @@ MapBlock::~MapBlock()
delete mesh;
mesh = NULL;
}
if (g_sound) {
for (std::map<v3s16,MapBlockSound>::iterator i = m_sounds.begin(); i != m_sounds.end(); i++) {
g_sound->stopSound(i->second.id);
}
#if USE_AUDIO == 1
for (std::map<v3s16,MapBlockSound>::iterator i = m_sounds.begin(); i != m_sounds.end(); i++) {
sound_stop_single(i->second.id);
}
#endif
}
#endif

View File

@ -528,7 +528,9 @@ void MapBlockMesh::generate(MeshMakeData *data, v3s16 camera_offset, JMutex *mut
MapNode n = data->m_vmanip.getNodeNoEx(data->m_blockpos_nodes+p);
if (g_sound) {
#if USE_AUDIO == 1
{
std::string snd = content_features(n).sound_ambient;
std::map<v3s16,MapBlockSound>::iterator i = data->m_sounds->find(p);
if (snd != "") {
@ -576,6 +578,7 @@ void MapBlockMesh::generate(MeshMakeData *data, v3s16 camera_offset, JMutex *mut
data->m_sounds->erase(i);
}
}
#endif
if (data->light_detail > 1 && !selected.is_coloured)
meshgen_preset_smooth_lights(data,p);
switch (content_features(n).draw_type) {

View File

@ -760,12 +760,12 @@ void RemotePlayer::move(f32 dtime, Map &map, f32 pos_max_d)
int frame = m_node->getFrameNr();
/* roughly sort of when a step sound should probably be heard, maybe */
if (frame == 218 || frame == 186 || frame == 209 || frame == 177) {
sound_playStep(&map,m_showpos,m_next_foot);
//sound_playStep(&map,m_showpos,m_next_foot);
m_next_foot = !m_next_foot;
}
/* roughly sort of when a dig sound should probably be heard, maybe */
if (frame == 214 || frame == 205 || frame == 193) {
sound_playDig(m_pointed,m_showpos);
//sound_playDig(m_pointed,m_showpos);
}
if (m_anim_id == PLAYERANIM_DIE) {
@ -1224,7 +1224,8 @@ void LocalPlayer::applyControl(float dtime)
}else if (m_energy < -0.1) {
m_can_use_energy = false;
m_energy = -0.1;
if (g_sound && m_low_energy_effect == 0) {
#if USE_AUDIO == 1
if (m_low_energy_effect == 0) {
if (m_character == "")
m_character = std::string(PLAYER_DEFAULT_CHARDEF);
Strfnd f(m_character);
@ -1232,14 +1233,18 @@ void LocalPlayer::applyControl(float dtime)
std::string snd("low-energy-");
snd += gender;
m_low_energy_effect = g_sound->playSound(snd,true);
/* TODO: looping */
m_low_energy_effect = sound_play_effect(snd.c_str(),1.0,NULL);
}
#endif
}else if (m_energy > 9.8) {
m_can_use_energy = true;
if (g_sound && m_low_energy_effect) {
g_sound->stopSound(m_low_energy_effect);
#if USE_AUDIO == 1
if (m_low_energy_effect) {
sound_stop_single(m_low_energy_effect);
m_low_energy_effect = 0;
}
#endif
}
if (energy_effectf > 0.0)

View File

@ -48,7 +48,6 @@
#include "profiler.h"
#include "log.h"
#include "base64.h"
#include "sound.h"
#include "http.h"
#include "enchantment.h"
#include "path.h"
@ -6038,11 +6037,6 @@ uint64_t Server::getPlayerPrivs(Player *player)
return getPlayerAuthPrivs(playername);
}
ISoundManager* Server::getSoundManager()
{
return &dummySoundManager;
}
void dedicated_server_loop(Server &server, bool &kill)
{
DSTACK(__FUNCTION_NAME);

View File

@ -36,7 +36,6 @@
#include "inventory.h"
#include "auth.h"
#include "ban.h"
#include "sound.h"
/*
Some random functions
@ -465,7 +464,6 @@ public:
// Envlock and conlock should be locked when calling this
void notifyPlayer(const char *name, const std::wstring msg);
void notifyPlayers(const std::wstring msg);
virtual ISoundManager* getSoundManager();
private:

647
src/sound.c Normal file
View File

@ -0,0 +1,647 @@
/************************************************************************
* sound.c
* voxelands - 3d voxel world sandbox game
* Copyright (C) Lisa 'darkrose' Milne 2017 <lisa@ltmnet.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#include "list.h"
#include "file.h"
#define _VL_SOUND_EXPOSE_INTERNAL
#include "sound.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static struct {
int init;
float volume;
struct {
float volume;
float fade;
float fadev;
sound_t *sounds;
sound_instance_t *playing;
} effects;
struct {
float volume;
sound_t *sounds;
sound_instance_t *playing;
} music;
ALCdevice *device;
ALCcontext *context;
} sound_data = {
0,
0.5,
{
0.5,
-1.0,
1.0,
NULL,
NULL
},
{
0.5,
NULL,
NULL
},
NULL,
NULL
};
/* initialise sound */
int sound_init()
{
/* initialise audio */
sound_data.device = alcOpenDevice(NULL);
if (!sound_data.device)
return 1;
sound_data.context = alcCreateContext(sound_data.device, NULL);
if (!sound_data.context) {
alcCloseDevice(sound_data.device);
return 1;
}
if (!alcMakeContextCurrent(sound_data.context) || (alcGetError(sound_data.device) != ALC_NO_ERROR)) {
alcDestroyContext(sound_data.context);
alcCloseDevice(sound_data.device);
return 1;
}
alDistanceModel(AL_EXPONENT_DISTANCE);
alListenerf(AL_GAIN, 1.0);
sound_data.init = 1;
/* sounds must be mono sounds, stereo will not work right!
* exceptions: background music */
/* walking */
/* CMT_DIRT */
sound_load_effect("step_dirt.1.ogg","dirt-step-left");
sound_load_effect("step_dirt.2.ogg","dirt-step-right");
/* CMT_STONE */
sound_load_effect("step_stone.1.ogg","stone-step-left");
sound_load_effect("step_stone.2.ogg","stone-step-right");
sound_load_effect("step_stone.3.ogg","stone-step-left");
sound_load_effect("step_stone.4.ogg","stone-step-right");
/* CMT_PLANT */
sound_load_effect("step_plant.1.ogg","plant-step-left");
sound_load_effect("step_plant.2.ogg","plant-step-right");
/* CMT_LIQUID */
sound_load_effect("step_liquid.1.ogg","liquid-step-left");
sound_load_effect("step_liquid.2.ogg","liquid-step-right");
/* CMT_WOOD */
sound_load_effect("step_wood.1.ogg","wood-step-left");
sound_load_effect("step_wood.2.ogg","wood-step-right");
sound_load_effect("step_wood.3.ogg","wood-step-left");
sound_load_effect("step_wood.4.ogg","wood-step-right");
/* CMT_GLASS */
sound_load_effect("step_glass.1.ogg","glass-step-left");
sound_load_effect("step_glass.1.ogg","glass-step-right");
/* special for grass */
sound_load_effect("step_grass.1.ogg","grass-step-left");
sound_load_effect("step_grass.2.ogg","grass-step-right");
/* digging */
/* CMT_DIRT */
sound_load_effect("dig_dirt.1.ogg","dirt-dig");
/* CMT_STONE */
sound_load_effect("dig_stone.1.ogg","stone-dig");
/* CMT_PLANT */
sound_load_effect("dig_plant.1.ogg","plant-dig");
/* CMT_LIQUID */
sound_load_effect("dig_liquid.1.ogg","liquid-dig");
/* CMT_WOOD */
sound_load_effect("dig_wood.1.ogg","wood-dig");
/* CMT_GLASS */
sound_load_effect("dig_glass.1.ogg","glass-dig");
/* mobs */
sound_load_effect("dig_mob.ogg","mob-dig");
/* miss */
sound_load_effect("dig_miss.ogg","miss-dig");
/* placing */
sound_load_effect("place_node.1.ogg","place");
sound_load_effect("place_node.2.ogg","place");
sound_load_effect("place_node.3.ogg","place");
/* CMT_DIRT */
/* CMT_STONE */
/* CMT_PLANT */
/* CMT_LIQUID */
sound_load_effect("place_liquid.1.ogg","liquid-place");
/* CMT_WOOD */
/* CMT_GLASS */
/* open formspec */
sound_load_effect("open_menu.ogg","open-menu");
sound_load_effect("open_book.ogg","open-book");
sound_load_effect("open_chest.ogg","open-chest");
/* environment and node sounds */
sound_load_effect("env_piston.ogg","env-piston");
sound_load_effect("env_dooropen.ogg","env-dooropen");
sound_load_effect("env_doorclose.ogg","env-doorclose");
sound_load_effect("env_fire.ogg","env-fire");
sound_load_effect("env_lava.ogg","env-lava");
sound_load_effect("env_water.ogg","env-water");
sound_load_effect("env_steam.ogg","env-steam");
sound_load_effect("env_tnt.ogg","env-tnt");
sound_load_effect("env_teleport.ogg","env-teleport");
/* mobs */
sound_load_effect("mob_oerkki_spawn.ogg","mob-oerkki-spawn");
sound_load_effect("mob_wolf_hit.ogg","mob-wolf-hit");
sound_load_effect("mob_wolf_spawn.ogg","mob-wolf-spawn");
sound_load_effect("mob_sheep_env.ogg","mob-sheep-env");
sound_load_effect("mob_ducksheep_env.ogg","mob-ducksheep-env");
sound_load_effect("mob_deer_env.ogg","mob-deer-env");
/* special */
sound_load_effect("wield_item.ogg","wield");
sound_load_effect("low_energy_F.ogg","low-energy-F");
sound_load_effect("low_energy_M.ogg","low-energy-M");
sound_load_effect("player_hurt_F.ogg","player-hurt-F");
sound_load_effect("player_hurt_M.ogg","player-hurt-M");
/* use */
sound_load_effect("use_eat.ogg","use-eat");
sound_load_effect("use_drink.ogg","use-drink");
/* menu backgrounds */
sound_load_music("bg_mainmenu.ogg","bg-mainmenu");
sound_load_music("bg_charcreator.ogg","bg-charcreator");
return 0;
}
/* exit sound */
void sound_exit()
{
if (!sound_data.init)
return;
sound_stop(0);
alcMakeContextCurrent(NULL);
alcDestroyContext(sound_data.context);
alcCloseDevice(sound_data.device);
sound_data.init = 0;
/* TODO: unload sounds */
}
/* do stuff */
void sound_process(float dtime)
{
ALint state;
float v;
sound_instance_t *d;
sound_instance_t *i;
/* factor = dtime / fade */
if (sound_data.effects.fade > -0.5) {
v = dtime/sound_data.effects.fade;
sound_data.effects.fadev -= v*sound_data.effects.volume*sound_data.volume;
if (sound_data.effects.fadev < 0.01)
sound_stop_effects(0);
}
i = sound_data.effects.playing;
while (i) {
alGetSourcei(i->id, AL_SOURCE_STATE, &state);
if (state != AL_PLAYING) {
d = i;
i = i->next;
sound_data.effects.playing = list_remove(&sound_data.effects.playing,d);
alDeleteSources(1, &d->id);
free(d);
continue;
}
if (i->fade > -0.5) {
if (i->fade > 0.01 && i->volume > 0.01) {
v = dtime/i->fade;
i->volume -= v*sound_data.music.volume*sound_data.volume;
if (i->volume > 0.01)
alSourcef(i->id, AL_GAIN, i->volume);
}else{
d = i;
i = i->next;
sound_data.effects.playing = list_remove(&sound_data.effects.playing,d);
alDeleteSources(1, &d->id);
free(d);
continue;
}
}
if (sound_data.effects.fade > -0.5)
alSourcef(i->id, AL_GAIN, sound_data.effects.fadev);
i = i->next;
}
}
/* */
void sound_step(float dtime, v3_t *pos, v3_t *at, v3_t *up)
{
float orientation[6] = {0.0,0.0,0.0,0.0,0.0,0.0};
sound_process(dtime);
if (pos) {
alListenerfv(AL_POSITION, (float*)pos);
}else{
alListener3f(AL_POSITION, 0.0,0.0,0.0);
}
alListener3f(AL_VELOCITY, 0.0,0.0,0.0);
if (at) {
orientation[0] = at->x;
orientation[1] = at->y;
orientation[2] = at->z;
}
if (up) {
orientation[3] = up->x;
orientation[4] = up->y;
orientation[5] = up->z;
}
alListenerfv(AL_ORIENTATION, orientation);
}
/* get/set sound effect volume */
float sound_volume_effects(float v)
{
if (v > -0.5) {
if (v > 1.0)
v = 1.0;
sound_data.effects.volume = v;
if (sound_data.init) {
float ev;
sound_instance_t *i = sound_data.effects.playing;
ev = v*sound_data.volume;
while (i) {
alSourcef(i->id, AL_GAIN, ev);
i = i->next;
}
}
}
return sound_data.effects.volume;
}
/* get/set sound music volume */
float sound_volume_music(float v)
{
if (v > -0.5) {
if (v > 1.0)
v = 1.0;
sound_data.music.volume = v;
if (sound_data.init && sound_data.music.playing) {
float ev;
ev = v*sound_data.volume;
alSourcef(sound_data.music.playing->id, AL_GAIN, ev);
}
}
return sound_data.music.volume;
}
/* get/set sound master volume */
float sound_volume_master(float v)
{
if (v > -0.5) {
if (v > 1.0)
v = 1.0;
sound_data.volume = v;
sound_volume_effects(sound_data.effects.volume);
sound_volume_music(sound_data.music.volume);
}
return sound_data.volume;
}
/* load a sound identified by token from a file */
static sound_t *sound_load(char* file, char* token)
{
file_t *f;
sound_t *e = malloc(sizeof(sound_t));
e->file = strdup(file);
e->token = strdup(token);
e->data = NULL;
e->d_len = 0;
f = file_load("sound",file);
if (sound_is_ogg(f)) {
if (sound_load_ogg(f,e))
goto sound_load_fail;
}else if (sound_is_wav(f)) {
if (sound_load_wav(f,e))
goto sound_load_fail;
}else{
goto sound_load_fail;
}
file_free(f);
return e;
sound_load_fail:
file_free(f);
free(e->file);
free(e->token);
if (e->data)
free(e->data);
free(e);
vlprintf(CN_ERROR, "failed to load sound data for file '%s'",file);
return NULL;
}
/* load a sound effect identifed by token */
int sound_load_effect(char* file, char* token)
{
sound_t *e = sound_load(file,token);
if (!e)
return 1;
sound_data.effects.sounds = list_push(&sound_data.effects.sounds,e);
return 0;
}
/* load music identifed by token */
int sound_load_music(char* file, char* token)
{
sound_t *e = sound_load(file,token);
if (!e)
return 1;
sound_data.music.sounds = list_push(&sound_data.music.sounds,e);
return 0;
}
/* unload a sound effect */
void sound_free_effect(char* token)
{
sound_t *e = sound_data.effects.sounds;
if (!e)
return;
while (e) {
if (!strcmp(e->token,token))
break;
e = e->next;
}
if (!e)
return;
sound_data.effects.sounds = list_remove(&sound_data.effects.sounds,e);
alDeleteBuffers(1,&e->id);
free(e->data);
free(e->file);
free(e->token);
free(e);
}
/* unload a music */
void sound_free_music(char* token)
{
sound_t *e = sound_data.music.sounds;
if (!e)
return;
while (e) {
if (!strcmp(e->token,token))
break;
e = e->next;
}
if (!e)
return;
sound_data.music.sounds = list_remove(&sound_data.music.sounds,e);
alDeleteBuffers(1,&e->id);
free(e->data);
free(e->file);
free(e->token);
free(e);
}
/* play sound effect */
uint32_t sound_play_effect(char* token, float volume, v3_t *pos)
{
sound_instance_t *i;
sound_t *e = sound_data.effects.sounds;
if (!sound_data.init || !e)
return 0;
while (e) {
if (!strcmp(e->token,token))
break;
e = e->next;
}
if (!e)
return 0;
i = malloc(sizeof(sound_instance_t));
if (!i)
return 0;
alGenSources(1, &i->id);
alSourcei(i->id, AL_BUFFER, e->id);
i->volume = volume;
i->fade = -1.0;
if (pos) {
alSourcei(i->id, AL_SOURCE_RELATIVE, AL_FALSE);
alSource3f(i->id, AL_POSITION, pos->x, pos->y, pos->z);
alSourcef(i->id, AL_REFERENCE_DISTANCE, 30.0);
}else{
alSourcei(i->id, AL_SOURCE_RELATIVE, AL_TRUE);
alSource3f(i->id, AL_POSITION, 0, 0, 0);
}
alSource3f(i->id, AL_VELOCITY, 0, 0, 0);
alSourcei(i->id, AL_LOOPING, AL_FALSE);
alSourcef(i->id, AL_GAIN, sound_data.effects.volume*sound_data.volume*volume);
alSourcePlay(i->id);
if (alGetError() != AL_NO_ERROR) {
alDeleteSources(1, &i->id);
free(i);
return 0;
}
sound_data.effects.playing = list_push(&sound_data.effects.playing,i);
return i->id;
}
/* play music */
uint32_t sound_play_music(char* token, float volume)
{
sound_t *e = sound_data.music.sounds;
if (!sound_data.init || !e)
return 0;
while (e) {
if (!strcmp(e->token,token))
break;
e = e->next;
}
if (!e)
return 0;
if (sound_data.music.playing) {
sound_data.effects.playing->fade = 1.0;
sound_data.effects.playing = list_push(&sound_data.effects.playing,sound_data.music.playing);
}
sound_data.music.playing = malloc(sizeof(sound_instance_t));
if (!sound_data.music.playing)
return 0;
alGenSources(1, &sound_data.music.playing->id);
alSourcei(sound_data.music.playing->id, AL_BUFFER, e->id);
sound_data.music.playing->volume = volume;
sound_data.music.playing->fade = -1.0;
alSourcei(sound_data.music.playing->id, AL_SOURCE_RELATIVE, AL_TRUE);
alSource3f(sound_data.music.playing->id, AL_POSITION, 0, 0, 0);
alSource3f(sound_data.music.playing->id, AL_VELOCITY, 0, 0, 0);
alSourcei(sound_data.music.playing->id, AL_LOOPING, AL_TRUE);
alSourcef(sound_data.music.playing->id, AL_GAIN, sound_data.music.volume*sound_data.volume*volume);
alSourcePlay(sound_data.music.playing->id);
if (alGetError() != AL_NO_ERROR) {
alDeleteSources(1, &sound_data.music.playing->id);
free(sound_data.music.playing);
return 0;
}
return sound_data.music.playing->id;
}
/* stop sound effects, optionally fading out in fade seconds */
void sound_stop_effects(int fade)
{
if (fade) {
sound_data.effects.fade = fade;
sound_data.effects.fadev = sound_data.effects.volume;
}else{
sound_instance_t *i = sound_data.effects.playing;
while (i) {
alSourceStop(i->id);
i = i->next;
}
sound_data.effects.fade = -1.0;
}
}
/* stop music, optionally fading out in fade seconds */
void sound_stop_music(int fade)
{
if (!sound_data.music.playing)
return;
if (!fade)
alSourceStop(sound_data.music.playing->id);
sound_data.music.playing->fade = fade;
sound_data.music.playing->volume = sound_data.music.volume;
sound_data.effects.playing = list_push(&sound_data.effects.playing,sound_data.music.playing);
sound_data.music.playing = NULL;
}
void sound_stop_single(uint32_t id)
{
sound_instance_t *i = sound_data.effects.playing;
while (i) {
if (i->id == id) {
alSourceStop(i->id);
break;
}
i = i->next;
}
}
/* stop all sounds, optionally fading out in fade seconds */
void sound_stop(int fade)
{
sound_stop_music(fade);
sound_stop_effects(fade);
}
/* command setter for sound effects volume */
int sound_effects_setter(char* value)
{
float vf;
int v = strtol(value,NULL,10);
vf = (float)v/100.0;
sound_volume_effects(vf);
return 0;
}
/* command setter for music volume */
int sound_music_setter(char* value)
{
float vf;
int v = strtol(value,NULL,10);
vf = (float)v/100.0;
sound_volume_music(vf);
return 0;
}
/* command setter for master volume */
int sound_master_setter(char* value)
{
int v = strtol(value,NULL,10);
if (v < 0)
v = 0;
if (v > 100)
v = 100;
sound_data.volume = (float)v/100.0;
sound_volume_effects(sound_data.effects.volume);
sound_volume_music(sound_data.music.volume);
return 0;
}

View File

@ -1,96 +1,73 @@
/************************************************************************
* Minetest-c55
* Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
*
* sound.h
* voxelands - 3d voxel world sandbox game
* Copyright (C) Lisa 'darkrose' Milne 2014 <lisa@ltmnet.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*
* License updated from GPLv2 or later to GPLv3 or later by Lisa Milne
* for Voxelands.
************************************************************************/
#ifndef _SOUND_H_
#define _SOUND_H_
#ifndef SOUND_HEADER
#define SOUND_HEADER
#include "common.h"
#include "nvp.h"
#include "common_irrlicht.h"
#include <string>
#include <vector>
#include <set>
#include "mapnode.h"
#include <AL/al.h>
#include <AL/alc.h>
#include <AL/alext.h>
class ISoundManager
{
public:
virtual ~ISoundManager(){}
#ifdef __cplusplus
extern "C" {
#endif
// Multiple sounds can be loaded per name; when played, the sound
// should be chosen randomly from alternatives
// Return value determines success/failure
virtual bool loadSound(const std::string &name, const std::string &filepath, float gain=1.0) = 0;
typedef struct sound_s {
struct sound_s *prev;
struct sound_s *next;
char* file;
char* token;
ALenum format;
ALsizei freq;
ALuint id;
char* data;
int d_len;
} sound_t;
virtual void updateListener(v3f pos, v3f vel, v3f at, v3f up) = 0;
virtual void setListenerGain(float gain) = 0;
typedef struct sound_instance_s {
struct sound_instance_s *prev;
struct sound_instance_s *next;
ALuint id;
float volume;
float fade;
} sound_instance_t;
// playSound functions return -1 on failure, otherwise a handle to the
// sound. If name=="", call should be ignored without error.
virtual int playSound(const std::string &name, bool loop) = 0;
virtual int playSoundAt(const std::string &name, bool loop, v3f pos, float gain=1.0, bool queue=false) = 0;
virtual void stopSound(int sound) = 0;
virtual bool soundExists(int sound) = 0;
/* defined in sound.c */
int sound_init(void);
void sound_exit(void);
void sound_step(float dtime, v3_t *pos, v3_t *at, v3_t *up);
int sound_load_effect(char* file, char* token);
int sound_load_music(char* file, char* token);
void sound_free_effect(char* token);
void sound_free_music(char* token);
uint32_t sound_play_effect(char* token, float volume, v3_t *pos);
uint32_t sound_play_music(char* token, float volume);
void sound_stop_effects(int fade);
void sound_stop_music(int fade);
void sound_stop_single(uint32_t id);
void sound_stop(int fade);
int sound_master_setter(char* value);
int sound_effects_setter(char* value);
int sound_music_setter(char* value);
virtual bool playMusic(const std::string &name, bool loop) = 0;
virtual void stopMusic() = 0;
#ifdef _VL_SOUND_EXPOSE_INTERNAL
/* defined in sound.c */
void sound_process(float dtime);
float sound_volume_master(float v);
float sound_volume_effects(float v);
float sound_volume_music(float v);
virtual void updateSoundPosition(int sound, v3f pos) = 0;
/* defined in sound_ogg.c */
int sound_is_ogg(file_t *f);
int sound_load_ogg(file_t *f, sound_t *e);
virtual void maintain(float dtime) = 0;
};
/* defined in sound_wav.c */
int sound_is_wav(file_t *f);
int sound_load_wav(file_t *f, sound_t *e);
#endif
class DummySoundManager: public ISoundManager
{
public:
virtual bool loadSound(const std::string &name, const std::string &filepath, float gain) {return true;}
void updateListener(v3f pos, v3f vel, v3f at, v3f up) {}
void setListenerGain(float gain) {}
int playSound(const std::string &name, bool loop) {return 0;}
int playSoundAt(const std::string &name, bool loop, v3f pos, float gain, bool queue) {return 0;}
void stopSound(int sound) {}
bool soundExists(int sound) {return false;}
bool playMusic(const std::string &name, bool loop) {return false;}
void stopMusic() {}
void updateSoundPosition(int sound, v3f pos) {}
void maintain(float dtime) {}
};
ISoundManager *createSoundManager();
void init_sounds(ISoundManager *sound);
class Map;
// Global DummySoundManager singleton
extern DummySoundManager dummySoundManager;
extern ISoundManager *g_sound;
void sound_playStep(Map *map, v3f pos, int foot, float gain=1.0);
void sound_playDig(content_t c, v3f pos);
#ifdef __cplusplus
}
#endif
#endif

123
src/sound_ogg.c Normal file
View File

@ -0,0 +1,123 @@
/************************************************************************
* sound_ogg.c
* voxelands - 3d voxel world sandbox game
* Copyright (C) Lisa 'darkrose' Milne 2017 <lisa@ltmnet.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#include "sound.h"
#include "file.h"
#include <stdlib.h>
#include <string.h>
#include <vorbis/vorbisfile.h>
static size_t sound_ogg_read(void* dst, size_t byte_size, size_t l, void* src)
{
return file_read(src,dst,(l*byte_size));
}
static int sound_ogg_seek(void* src, ogg_int64_t offset, int origin)
{
return file_seek(src,offset,origin);
}
static int sound_ogg_close(void* src)
{
return 0;
}
static long sound_ogg_tell(void* src)
{
return file_tell(src);
}
/* is it an ogg? */
int sound_is_ogg(file_t *f)
{
int r;
OggVorbis_File oggfile;
ov_callbacks cb;
cb.read_func = sound_ogg_read;
cb.close_func = sound_ogg_close;
cb.seek_func = sound_ogg_seek;
cb.tell_func = sound_ogg_tell;
r = !ov_test_callbacks(f, &oggfile, NULL, 0, cb);
if (r)
ov_clear(&oggfile);
file_seek(f,0,SEEK_SET);
return r;
}
/* load an ogg file */
int sound_load_ogg(file_t *f, sound_t *e)
{
int endian = 0;
int bitStream;
int s;
char buff[30000];
vorbis_info *ogginfo;
OggVorbis_File oggfile;
ov_callbacks cb;
cb.read_func = sound_ogg_read;
cb.close_func = sound_ogg_close;
cb.seek_func = sound_ogg_seek;
cb.tell_func = sound_ogg_tell;
if (ov_open_callbacks(f, &oggfile, NULL, 0, cb))
return 1;
ogginfo = ov_info(&oggfile, -1);
/* always use 16-bit samples */
if (ogginfo->channels == 1) {
e->format = AL_FORMAT_MONO16;
}else{
e->format = AL_FORMAT_STEREO16;
}
e->freq = ogginfo->rate;
do{
s = ov_read(&oggfile, buff, 30000, endian, 2, 1, &bitStream);
if (s < 0) {
ov_clear(&oggfile);
return 1;
}
e->data = realloc(e->data,e->d_len+s);
memcpy(e->data+e->d_len,buff,s);
e->d_len += s;
} while (s > 0);
alGenBuffers(1, &e->id);
alBufferData(e->id, e->format, e->data, e->d_len, e->freq);
if (alGetError() != AL_NO_ERROR)
return 1;
ov_clear(&oggfile);
return 0;
}

105
src/sound_wav.c Normal file
View File

@ -0,0 +1,105 @@
/************************************************************************
* sound_wav.c
* voxelands - 3d voxel world sandbox game
* Copyright (C) Lisa 'darkrose' Milne 2017 <lisa@ltmnet.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#include "sound.h"
#include "file.h"
#include <string.h>
typedef struct wav_file_header_s {
char riff[4]; /* 'RIFF' */
int size;
char wave[4]; /* 'WAVE' */
char fmt[4]; /* 'fmt ' */
int f_len;
short int f_tag;
} __attribute__((packed)) wav_file_header_t;
typedef struct wav_format_header_s {
short int channels;
int freq;
int bytes_per_second;
short int block_align;
short int bps;
char data[4]; /* 'data' */
int d_len;
} __attribute__((packed)) wav_format_header_t;
/* is it a wav file? */
int sound_is_wav(file_t *f)
{
int r = 0;
wav_file_header_t h;
file_read(f,&h,sizeof(wav_file_header_t));
if (!strncmp("RIFF",h.riff,4) && !strncmp("WAVE",h.wave,4))
r = 1;
file_seek(f,0,SEEK_SET);
return r;
}
/* load a wav file */
int sound_load_wav(file_t *f, sound_t *e)
{
wav_file_header_t h;
wav_format_header_t fmt;
unsigned char* data;
file_read(f,&h,sizeof(wav_file_header_t));
file_read(f,&fmt,sizeof(wav_format_header_t));
data = file_get(f);
if (h.f_tag != 1) {
return 1;
}else if (fmt.bps == 8) {
if (fmt.channels == 1) {
e->format = AL_FORMAT_MONO8;
}else{
e->format = AL_FORMAT_STEREO8;
}
}else if (fmt.bps == 16) {
if (fmt.channels == 1) {
e->format = AL_FORMAT_MONO16;
}else{
e->format = AL_FORMAT_STEREO16;
}
}else{
return 1;
}
e->freq = fmt.freq;
e->d_len = fmt.d_len;
e->data = malloc(e->d_len);
memcpy(e->data,data,e->d_len);
alGenBuffers(1, &e->id);
alBufferData(e->id, e->format, e->data, e->d_len, e->freq);
if (alGetError() != AL_NO_ERROR)
return 1;
return 0;
}

View File

@ -17,6 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>
************************************************************************/
#include "common.h"
#include "thread.h"
#include "list.h"
#include "array.h"