From 41c268f0192405e949d1513cbd086eb96aaa0f94 Mon Sep 17 00:00:00 2001 From: Alexander Baldeck Date: Wed, 29 Sep 2004 08:48:36 +0000 Subject: added simple soundpool for preloading sample data & bgm references --- src/sound/sound.cpp | 346 +++++++++++++++++++++++++++++----------------------- 1 file changed, 194 insertions(+), 152 deletions(-) (limited to 'src/sound/sound.cpp') diff --git a/src/sound/sound.cpp b/src/sound/sound.cpp index 078d0f91..9355dd4a 100644 --- a/src/sound/sound.cpp +++ b/src/sound/sound.cpp @@ -22,10 +22,10 @@ */ /** - rewrite of non-existend sdl-soundengine using allegro - - Author: kth5 aka Alexander Baldeck - pipe your question, suggestions and flames to: kth5@gawab.com + rewrite of non-existend sdl-soundengine using allegro + + Author: kth5 aka Alexander Baldeck + pipe your question, suggestions and flames to: kth5@gawab.com */ #ifdef WIN32 @@ -39,28 +39,28 @@ #include "sound.h" /** - install the sound engine - int voices -> overall reserved voices - int mod_voices -> voices dedicated for mod-playback - - NOTE: - overall voices must not be less or equal to the - specified amount of mod_voices! - if mod-voices is too low some mods will not sound - correctly since a couple of tracks are not going - to be played along w/ the others. so missing ins- - truments can be a result. - 32/20 sounds realistic here. + install the sound engine + int voices -> overall reserved voices + int mod_voices -> voices dedicated for mod-playback + + NOTE: + overall voices must not be less or equal to the + specified amount of mod_voices! + if mod-voices is too low some mods will not sound + correctly since a couple of tracks are not going + to be played along w/ the others. so missing ins- + truments can be a result. + 32/20 sounds realistic here. */ void TmwSound::Init(int voices, int mod_voices) { isOk = -1; - + if(mod_voices >= voices) throw("No voices left for SFX! Sound will be disabled!"); install_timer(); reserve_voices (voices, -1); - + #ifdef WIN32 if (install_sound (DIGI_AUTODETECT, MIDI_AUTODETECT, NULL) < 0) #else @@ -68,91 +68,91 @@ void TmwSound::Init(int voices, int mod_voices) { #endif throw("Could not initialize sound... :-("); - + if (install_mod (mod_voices) < 0) throw("Could not install MOD player... :-("); mod = NULL; mid = NULL; sfx = NULL; - + pan = 128; pitch=1000; - + items = 0; isOk = 0; } /** - set the volume value-range: 0-255 - int digi -> for digital playback - int mid -> for midi playback - int mod -> for... aw, you guess ^^ - - NOTE: - all values may only be between 0-255 where 0 means - muted. + set the volume value-range: 0-255 + int digi -> for digital playback + int mid -> for midi playback + int mod -> for... aw, you guess ^^ + + NOTE: + all values may only be between 0-255 where 0 means + muted. */ void TmwSound::SetVol(int digi, int mid, int mod) { - if(isOk==-1) - return; - set_volume(digi, mid); - set_mod_volume(mod); - set_hardware_volume(digi, mid); - - if(isMaxVol(vol_digi + digi)==false) vol_digi += digi; - if(isMaxVol(vol_midi + mid) ==false) vol_midi += mid; - if(isMaxVol(vol_mod + mod) ==false) vol_mod += mod; + if(isOk==-1) + return; + set_volume(digi, mid); + set_mod_volume(mod); + set_hardware_volume(digi, mid); + + if(isMaxVol(vol_digi + digi)==false) vol_digi += digi; + if(isMaxVol(vol_midi + mid) ==false) vol_midi += mid; + if(isMaxVol(vol_mod + mod) ==false) vol_mod += mod; } /** - adjusts current volume - int digi -> for digital playback - int mid -> for midi playback - int mod -> for... aw, you guess ^^ - - NOTE: - all values may only be between 0-255 where 0 means - muted. + adjusts current volume + int digi -> for digital playback + int mid -> for midi playback + int mod -> for... aw, you guess ^^ + + NOTE: + all values may only be between 0-255 where 0 means + muted. */ void TmwSound::SetAdjVol(int adigi, int amid, int amod) { - if(isOk==-1) - return; - set_volume(vol_digi + adigi, vol_midi + amid); - set_mod_volume(vol_mod + amod); - - if(isMaxVol(vol_digi + adigi)==false) vol_digi += adigi; - if(isMaxVol(vol_midi + amid) ==false) vol_midi += amid; - if(isMaxVol(vol_mod + amod) ==false) vol_mod += amod; + if(isOk==-1) + return; + set_volume(vol_digi + adigi, vol_midi + amid); + set_mod_volume(vol_mod + amod); + + if(isMaxVol(vol_digi + adigi)==false) vol_digi += adigi; + if(isMaxVol(vol_midi + amid) ==false) vol_midi += amid; + if(isMaxVol(vol_mod + amod) ==false) vol_mod += amod; } /** - start BGM using a midi file - char *in -> full path of midi file - int loop -> how many times should the midi be looped? (-1 = infinite) - - NOTE: - playing midi does not steal away any voices but - does not work w/ most soundcards w/o software - emulation. this means that *nix-users will most - probably be left out. do not use this unless we - find a way to always get it to work. :-) - - at this point of time only standard RMI midi files - can be played. so no m$ extensions like GS and such. + start BGM using a midi file + char *in -> full path of midi file + int loop -> how many times should the midi be looped? (-1 = infinite) + + NOTE: + playing midi does not steal away any voices but + does not work w/ most soundcards w/o software + emulation. this means that *nix-users will most + probably be left out. do not use this unless we + find a way to always get it to work. :-) + + at this point of time only standard RMI midi files + can be played. so no m$ extensions like GS and such. */ void TmwSound::StartMIDI(char *in, int loop) { - if(isOk==-1) - return; - - mid = load_midi(in); - if (!mid) { - isOk=-1; - throw("Could not load MIDI file!"); - } - - play_midi(mid, TRUE); + if(isOk==-1) + return; + + mid = load_midi(in); + if (!mid) { + isOk=-1; + throw("Could not load MIDI file!"); + } + + play_midi(mid, TRUE); } /** @@ -161,99 +161,99 @@ void TmwSound::StartMIDI(char *in, int loop) { int loop -> how many times should the midi be looped? (-1 = infinite) NOTE: - playing mod is a pretty good choice. most of the work - is being done by the cpu so it's not dependend on the - sound-card how things sound. if it works, it just - works! ;-) - - JGMOD supports several formats: - MOD - S3M - XM - Unreal - and S3M (in UMX extension) + playing mod is a pretty good choice. most of the work + is being done by the cpu so it's not dependend on the + sound-card how things sound. if it works, it just + works! ;-) + + JGMOD supports several formats: + MOD + S3M + XM + Unreal + and S3M (in UMX extension) */ void TmwSound::StartMOD(char * in, int loop) { if(isOk==-1) return; mod = load_mod(in); - if(!mod) { + if(!mod) { isOk=-1; throw("Error reading MOD file..."); } play_mod(mod, TRUE); -} +} /** - stop all currently running BGM tracks - - NOTE: - you need to stop all playback when you want to - switch from mod to midi. playing a new track is - usually possibe simply by calling StartMIDI() ir - SartMOD() again. - passing NULL to the playing functions only means - to make playback stop. + stop all currently running BGM tracks + + NOTE: + you need to stop all playback when you want to + switch from mod to midi. playing a new track is + usually possibe simply by calling StartMIDI() ir + SartMOD() again. + passing NULL to the playing functions only means + to make playback stop. */ void TmwSound::StopBGM() { - if(isOk==-1) - return; - - play_midi(NULL,-1); - stop_mod(); - - mod = NULL; - mid = NULL; + if(isOk==-1) + return; + + play_midi(NULL,-1); + stop_mod(); + + mod = NULL; + mid = NULL; } /** - play short sample usually for sfx - char * in -> full path to the sample file - (int wavid -> the id of the preloaded wav file (not implemented yet)) - int pan -> panning of the sound, values can be 0-255 where 128 is - the middle - - NOTE: - later on this will be a subsequent call to another - function that preloads all wavs corresponding to - the current area (e.g. monster screams) to memory. - right now the function loads the file from hdd - everytime you want it to be played. this is kind of - resource intensive even though most OS'ses cache a - already loaded file for some time. - - allegro supports different formats but this is not - stated clear enough - these will work for sure: - WAV - VOC - - i don't know what kind of samples are necessary so we - need to test this thoroughly. + play short sample usually for sfx + char * in -> full path to the sample file + (int wavid -> the id of the preloaded wav file (not implemented yet)) + int pan -> panning of the sound, values can be 0-255 where 128 is + the middle + + NOTE: + later on this will be a subsequent call to another + function that preloads all wavs corresponding to + the current area (e.g. monster screams) to memory. + right now the function loads the file from hdd + everytime you want it to be played. this is kind of + resource intensive even though most OS'ses cache a + already loaded file for some time. + + allegro supports different formats but this is not + stated clear enough - these will work for sure: + WAV + VOC + + i don't know what kind of samples are necessary so we + need to test this thoroughly. */ void TmwSound::StartWAV(char * in, int pan) { - if(isOk==-1) - return; - - sfx = load_sample(in); - if (!sfx) - throw("Error reading WAV file..."); - - play_sample(sfx, vol_digi, pan, pitch, FALSE); + if(isOk==-1) + return; + + sfx = load_sample(in); + if (!sfx) + throw("Error reading WAV file..."); + + play_sample(sfx, vol_digi, pan, pitch, FALSE); } /** preloads a sound-item into buffer char *fpath -> full path to file char type -> type of item (TMWSOUND_MOD, TMWSOUND_MID, TMWSOUND_SFX) - + NOTE: - only TMWSOUND_SFX items get preloaded. everything - else will only store the full path to the file. + only TMWSOUND_SFX items get preloaded. everything + else will only store the full path to the file. - please make sure that the object is not loaded more - than once since the function will not be able to run - checks for its own! + please make sure that the object is not loaded more + than once since the function will not be able to run + checks for its own! */ TMWSOUND_SID TmwSound::LoadItem(char *fpath, char type) { POOL_ITEM item; @@ -272,20 +272,62 @@ TMWSOUND_SID TmwSound::LoadItem(char *fpath, char type) { } /** - deinstall all sound functionality - - NOTE: - normally you won't need to call this since this is - done by allegro when shutting itself down. but if - you find a reason to delete the sound-engine from - memory (e.g. garbage-collection) feel free to use - it. :-P + unloads an item from the soundpool + TMWSOUND_SID id -> id returned by LoadItem() +*/ +void TmwSound::UnloadItem(TMWSOUND_SID id) { + int cnt = 0; + POOL_ITEM item; + for(sounditem = soundpool.begin(); sounditem != soundpool.end(); sounditem++) { + item = *sounditem; + if(item.id == id) { + destroy_sample((SAMPLE*)item.data); + soundpool.erase(sounditem); + return; + } + cnt++; + } +} + +/** + plays an item in soundpool + TMWSOUND_SID id -> id returned by LoadItem() +*/ +void TmwSound::PlayItem(TMWSOUND_SID id, int loop) { + POOL_ITEM item; + for(sounditem = soundpool.begin(); sounditem != soundpool.end(); sounditem++) { + item = *sounditem; + if(item.id = id) { + switch(item.type) { + case TMWSOUND_SFX : + play_sample((SAMPLE*)item.data, vol_digi, pan, pitch, FALSE); + break; + case TMWSOUND_MOD : + StartMOD((char*)item.fname.c_str(),loop); + break; + case TMWSOUND_MID : + StartMIDI((char*)item.fname.c_str(),loop); + break; + } + } + } +} + +/** + deinstall all sound functionality + + NOTE: + normally you won't need to call this since this is + done by allegro when shutting itself down. but if + you find a reason to delete the sound-engine from + memory (e.g. garbage-collection) feel free to use + it. :-P */ void TmwSound::Close(void) { mod = NULL; mid = NULL; sfx = NULL; - + remove_mod(); remove_sound(); isOk = -1; -- cgit v1.2.3-70-g09d2