1
0
Fork 0
blockofighter/src/audio.cpp

238 lines
5.3 KiB
C++
Raw Normal View History

2014-02-16 14:32:28 +00:00
#include "main.h"
#include <string.h>
#include <stdio.h>
2021-06-10 18:06:20 +00:00
#include <functional>
2014-02-16 14:32:28 +00:00
#include "audio.h"
#define SOUND_FADENONE 0
#define SOUND_FADEIN 1
#define SOUND_FADEOUT 2
2015-06-03 12:29:34 +00:00
struct soundlist {
Sound *sound;
soundlist *next;
2014-02-16 14:32:28 +00:00
};
soundlist *allsounds = NULL;
2021-06-10 18:06:20 +00:00
Sound *current_music = NULL;
2014-02-16 14:32:28 +00:00
2015-06-03 12:29:34 +00:00
Sound::Sound(Sound *source) {
memcpy(this, source, sizeof(Sound));
soundlist *node = new soundlist;
node->sound = this;
node->next = allsounds;
allsounds = node;
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +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 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
Sound::Sound(char *filename, int type) { load(filename, type, false); }
2014-02-16 14:32:28 +00:00
2015-06-03 12:29:34 +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 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
Sound::Sound(char *filename, int type, bool loops) {
load(filename, type, loops);
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
bool endsWith(char *str1, char *str2) {
char *str3 = str1 + strlen(str1) - strlen(str2);
2014-02-16 14:32:28 +00:00
#ifdef WIN32
2015-06-03 12:29:34 +00:00
if (stricmp(str3, str2))
return false;
2014-02-16 14:32:28 +00:00
#else
2015-06-03 12:29:34 +00:00
if (strcasecmp(str3, str2))
return false;
2014-02-16 14:32:28 +00:00
#endif
2015-06-03 12:29:34 +00:00
else
return true;
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
void Sound::load(char *filename, int type, bool loops) {
this->filename = filename;
if (type == SOUNDTYPE_AUTODETECT) {
2021-06-10 18:06:20 +00:00
if (endsWith(filename, "mp3") || endsWith(filename, "ogg"))
2015-06-03 12:29:34 +00:00
type = SOUNDTYPE_STREAM;
if (endsWith(filename, "wav") || endsWith(filename, "raw"))
type = SOUNDTYPE_SAMPLE;
}
2021-06-10 18:06:20 +00:00
this->chunk = NULL;
this->music = NULL;
if (type == SOUNDTYPE_SAMPLE) {
this->chunk = Mix_LoadWAV(filename);
if (this->chunk) {
2015-06-03 12:29:34 +00:00
} else {
2021-06-10 18:06:20 +00:00
printf("Error while loading sample %s: %s\n", filename, Mix_GetError());
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
} else if (type == SOUNDTYPE_STREAM) {
2021-06-10 18:06:20 +00:00
this->music = Mix_LoadMUS(filename);
if (!this->music) {
printf("Error while loading music %s: %s\n", filename, Mix_GetError());
2015-06-03 12:29:34 +00:00
}
}
2021-06-10 18:06:20 +00:00
this->loops = loops;
2015-06-03 12:29:34 +00:00
stopcallback = NULL;
soundlist *node = new soundlist;
node->sound = this;
node->next = allsounds;
allsounds = node;
minduration = 0;
setVolume(1.0);
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +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;
2021-06-10 18:06:20 +00:00
if (chunk) {
channel = -1;
/*channel = FSOUND_PlaySound(FSOUND_FREE, sample);
FSOUND_SetVolume(channel, (int)(volume * 256));
2015-06-03 12:29:34 +00:00
if (!loops) {
running = false;
finished = false;
2021-06-10 18:06:20 +00:00
}*/
} else if (music) {
if (Mix_PlayMusic(music, loops)) {
printf("Failed to play music\n");
} else {
current_music = this;
2014-02-16 14:32:28 +00:00
}
2021-06-10 18:06:20 +00:00
Mix_VolumeMusic((int)(volume * MIX_MAX_VOLUME));
2015-06-03 12:29:34 +00:00
}
// printf("Done: %f\n", volume);
return true;
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
void Sound::play(int minduration) {
if (play())
this->minduration = minduration;
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
void Sound::stop() {
2021-06-10 18:06:20 +00:00
if (chunk && channel >= 0) {
Mix_HaltChannel(channel);
} else if (music && current_music == this) {
// FIXME only if it is THIS music playing
Mix_HaltMusic();
2015-06-03 12:29:34 +00:00
}
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
void Sound::setVolume(float volume) {
2021-06-10 18:06:20 +00:00
if (chunk && channel >= 0) {
Mix_Volume(channel, (int)(volume * MIX_MAX_VOLUME));
} else if (music && current_music == this) {
Mix_VolumeMusic((int)(volume * MIX_MAX_VOLUME));
2015-06-03 12:29:34 +00:00
}
this->volume = volume;
2014-02-16 14:32:28 +00:00
}
2021-06-10 18:06:20 +00:00
void streamendcallback(Sound* sound) {
2015-06-03 12:29:34 +00:00
sound->setFinished();
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
void Sound::setStopCallback(STOPCALLBACK callback) {
stopcallback = callback;
2021-06-10 18:06:20 +00:00
if (chunk && channel >= 0) {
2015-06-03 12:29:34 +00:00
// NOT SUPPORTED
2021-06-10 18:06:20 +00:00
} else if (music) {
//Mix_HookMusicFinished(std::bind(callback, this));
2015-06-03 12:29:34 +00:00
}
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
void Sound::setFinished(void) { finished = true; }
2014-02-16 14:32:28 +00:00
2015-06-03 12:29:34 +00:00
bool Sound::isFinished(void) {
2014-02-16 14:32:28 +00:00
#ifdef AUDIO_FMOD
2015-06-03 12:29:34 +00:00
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 14:32:28 +00:00
#endif
2015-06-03 12:29:34 +00:00
return false;
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +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();
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
}
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
}
if (minduration > 0)
minduration--;
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
void Sound::fadeIn(int length) {
fademode = SOUND_FADEIN;
fadepos = 0;
fadetarget = length;
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
void Sound::fadeOut(int length) {
if (fademode == SOUND_FADEIN) {
float percent = 1.0 - (float)fadepos / fadetarget;
fadepos = (int)(fadetarget * percent);
2015-06-03 12:29:34 +00:00
}
fadepos = 0;
fadetarget = length;
fademode = SOUND_FADEOUT;
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
void initAudio(void) {
2021-06-10 18:06:20 +00:00
Mix_Init(MIX_INIT_MP3 | MIX_INIT_OGG);
Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024);
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
void uninitAudio(void) {
2021-06-10 18:06:20 +00:00
Mix_CloseAudio();
Mix_Quit();
2014-02-16 14:32:28 +00:00
}
2015-06-03 12:29:34 +00:00
void updateAudio(void) {
soundlist *node = allsounds;
while (node != NULL) {
Sound *sound = node->sound;
sound->update();
node = node->next;
}
2014-02-16 14:32:28 +00:00
}