1
0
Fork 0
blockofighter/src/audio.cpp

271 lines
7 KiB
C++
Raw Normal View History

2014-02-16 10:41:12 +00:00
#include "main.h"
#include <string.h>
#include <stdio.h>
#include "audio.h"
#define SOUND_FADENONE 0
#define SOUND_FADEIN 1
#define SOUND_FADEOUT 2
struct soundlist{
Sound *sound;
soundlist *next;
2014-02-16 10:41:12 +00:00
};
soundlist *allsounds = NULL;
Sound::Sound(Sound *source){
memcpy(this, source, sizeof(Sound));
soundlist *node = new soundlist;
node->sound = this;
node->next = allsounds;
allsounds = node;
2014-02-16 10:41:12 +00:00
}
Sound::Sound(char *filename){
load(filename, SOUNDTYPE_AUTODETECT, false);
//printf("%s: %p, %p, %p, %p\n", filename, this, stream, sample, module);
2014-02-16 10:41:12 +00:00
}
Sound::Sound(char *filename, int type){
load(filename, type, false);
2014-02-16 10:41:12 +00:00
}
Sound::Sound(char *filename, bool loops){
load(filename, SOUNDTYPE_AUTODETECT, loops);
//printf("%s: %p, %p, %p, %p\n", filename, this, stream, sample, module);
2014-02-16 10:41:12 +00:00
}
Sound::Sound(char *filename, int type, bool loops){
load(filename, type, loops);
2014-02-16 10:41:12 +00:00
}
bool endsWith(char *str1, char *str2){
char *str3 = str1 + strlen(str1) - strlen(str2);
2014-02-16 10:41:12 +00:00
#ifdef WIN32
if (stricmp(str3, str2)) return false;
2014-02-16 10:41:12 +00:00
#else
if (strcasecmp(str3, str2)) return false;
2014-02-16 10:41:12 +00:00
#endif
else return true;
2014-02-16 10:41:12 +00:00
}
void Sound::load(char *filename, int type, bool loops){
this->filename = filename;
if (type == SOUNDTYPE_AUTODETECT){
if (endsWith(filename, "mp3") ||
endsWith(filename, "mp2") ||
endsWith(filename, "ogg")) type = SOUNDTYPE_STREAM;
if (endsWith(filename, "wav") ||
endsWith(filename, "raw")) type = SOUNDTYPE_SAMPLE;
if (endsWith(filename, "s3m") ||
endsWith(filename, "xm") ||
endsWith(filename, "it") ||
endsWith(filename, "mid") ||
endsWith(filename, "rmi") ||
endsWith(filename, "sgr") ||
endsWith(filename, "mod")) type = SOUNDTYPE_MODULE;
}
2014-02-16 10:41:12 +00:00
#ifdef AUDIO_FMOD
sample = NULL;
module = NULL;
stream = NULL;
this->type = type;
if (type == SOUNDTYPE_MODULE){
module = FMUSIC_LoadSong(filename);
this->loops = false;
} else if (type == SOUNDTYPE_SAMPLE){
if (loops){
sample = FSOUND_Sample_Load(FSOUND_FREE, filename, FSOUND_LOOP_NORMAL, 0);
FSOUND_Sample_SetLoopMode(sample, FSOUND_LOOP_NORMAL);
} else{
sample = FSOUND_Sample_Load(FSOUND_FREE, filename, FSOUND_LOOP_OFF, 0);
FSOUND_Sample_SetLoopMode(sample, FSOUND_LOOP_OFF);
}
this->loops = loops;
} else if (type == SOUNDTYPE_STREAM){
if (loops){
stream = FSOUND_Stream_OpenFile(filename, FSOUND_LOOP_NORMAL, 0);
} else{
stream = FSOUND_Stream_OpenFile(filename, FSOUND_LOOP_OFF, 0);
}
this->loops = loops;
}
2014-02-16 10:41:12 +00:00
#endif
stopcallback = NULL;
soundlist *node = new soundlist;
node->sound = this;
node->next = allsounds;
allsounds = node;
minduration = 0;
setVolume(1.0);
2014-02-16 10:41:12 +00:00
}
bool Sound::play(){
//printf("Playing %s: %p, %p, %p, %p\n", filename, this, stream, sample, module);
if (minduration > 0) return false;
running = true;
finished = false;
fademode = SOUND_FADENONE;
minduration = 0;
2014-02-16 10:41:12 +00:00
#ifdef AUDIO_FMOD
if (type == SOUNDTYPE_MODULE){
FMUSIC_PlaySong(module);
FMUSIC_SetMasterVolume(module, volume*256);
} else if (type == SOUNDTYPE_SAMPLE){
channel = FSOUND_PlaySound(FSOUND_FREE, sample);
FSOUND_SetVolume(channel, volume*256);
if (!loops){
running = false;
finished = false;
}
} else if (type == SOUNDTYPE_STREAM){
channel = FSOUND_Stream_Play(FSOUND_FREE, stream);
FSOUND_SetVolume(channel, volume*256);
}
2014-02-16 10:41:12 +00:00
#endif
//printf("Done: %f\n", volume);
return true;
2014-02-16 10:41:12 +00:00
}
void Sound::play(int minduration){
if (play()) this->minduration = minduration;
2014-02-16 10:41:12 +00:00
}
void Sound::stop(){
#ifdef AUDIO_FMOD
if (type == SOUNDTYPE_MODULE){
FMUSIC_StopSong(module);
} else if (type == SOUNDTYPE_SAMPLE){
FSOUND_StopSound(channel);
} else if (type == SOUNDTYPE_STREAM){
FSOUND_Stream_Stop(stream);
}
2014-02-16 10:41:12 +00:00
#endif
}
void Sound::setVolume(float volume){
//printf("Volume %s: %f\n", filename, volume);
2014-02-16 10:41:12 +00:00
#ifdef AUDIO_FMOD
if (type == SOUNDTYPE_MODULE){
FMUSIC_SetMasterVolume(module, volume*256);
} else if (type == SOUNDTYPE_SAMPLE){
FSOUND_SetVolume(channel, volume*256);
} else if (type == SOUNDTYPE_STREAM){
FSOUND_SetVolume(channel, volume*256);
}
2014-02-16 10:41:12 +00:00
#endif
this->volume = volume;
2014-02-16 10:41:12 +00:00
}
#ifdef AUDIO_FMOD
signed char streamendcallback(FSOUND_STREAM *stream, void *buff, int len, int param){
Sound *sound = (Sound *)param;
sound->setFinished();
return true;
2014-02-16 10:41:12 +00:00
}
#endif
void Sound::setStopCallback(STOPCALLBACK callback){
stopcallback = callback;
2014-02-16 10:41:12 +00:00
#ifdef AUDIO_FMOD
if (type == SOUNDTYPE_MODULE){
} else if (type == SOUNDTYPE_SAMPLE){
//NOT SUPPORTED
} else if (type == SOUNDTYPE_STREAM){
FSOUND_Stream_SetEndCallback(stream, streamendcallback, (int)this);
}
2014-02-16 10:41:12 +00:00
#endif
}
void Sound::setFinished(void){
finished = true;
2014-02-16 10:41:12 +00:00
}
bool Sound::isFinished(void){
#ifdef AUDIO_FMOD
if (type == SOUNDTYPE_MODULE){
if (FMUSIC_IsFinished(module)) return true;
} else if (type == SOUNDTYPE_SAMPLE){
//NOT SUPPORTED
} else if (type == SOUNDTYPE_STREAM){
if (finished) return true;
}
2014-02-16 10:41:12 +00:00
#endif
return false;
2014-02-16 10:41:12 +00:00
}
void Sound::update(void){
if (running){
if (isFinished()){
running = false;
if (stopcallback != NULL) stopcallback(this);
} else{
if (fademode == SOUND_FADEIN){
if (fadepos < fadetarget){
fadepos++;
setVolume((float)fadepos/fadetarget);
} else fademode = SOUND_FADENONE;
}
if (fademode == SOUND_FADEOUT){
if (fadepos < fadetarget){
fadepos++;
setVolume(1.0 - (float)fadepos/fadetarget);
} else{
fademode = SOUND_FADENONE;
stop();
}
}
}
}
if (minduration > 0) minduration--;
2014-02-16 10:41:12 +00:00
}
void Sound::fadeIn(int length){
fademode = SOUND_FADEIN;
fadepos = 0;
fadetarget = length;
2014-02-16 10:41:12 +00:00
}
void Sound::fadeOut(int length){
if (fademode == SOUND_FADEIN){
float percent = 1.0 - (float)fadepos/fadetarget;
fadepos = fadetarget * percent;
}
fadepos = 0;
fadetarget = length;
fademode = SOUND_FADEOUT;
2014-02-16 10:41:12 +00:00
}
void initAudio(void){
#ifdef AUDIO_FMOD
FSOUND_Init(44100, 32, 0);
2014-02-16 10:41:12 +00:00
#endif
}
void uninitAudio(void){
#ifdef AUDIO_FMOD
FSOUND_Close();
2014-02-16 10:41:12 +00:00
#endif
}
void updateAudio(void){
soundlist *node = allsounds;
while (node != NULL){
Sound *sound = node->sound;
sound->update();
node = node->next;
}
}