diff --git a/client/main.cc b/client/main.cc index 201d86a..6b8bfb9 100644 --- a/client/main.cc +++ b/client/main.cc @@ -21,7 +21,7 @@ int main(){ drv = new fishbone::SoundDriver(); - snd = drv->mixer.open("betrayal.mod"); + snd = drv->mixer.open("shanghai.ogg"); snd->setLoop(true); snd->resume(); diff --git a/engine/include/fishbone/sound.h b/engine/include/fishbone/sound.h index fc3da8d..330de47 100644 --- a/engine/include/fishbone/sound.h +++ b/engine/include/fishbone/sound.h @@ -20,7 +20,12 @@ ~prefix##Sound(); \ } -#define FB_SOUND_LOADERS LOADER(XMP) +#define FB_SOUND_LOADERS \ + LOADER(XMP) \ + LOADER(Vorbis) \ + LOADER(MP3) \ + LOADER(FLAC) \ + LOADER(WAV) namespace fishbone { class SoundDriver; diff --git a/engine/src/sounddrv/sdl2.cc b/engine/src/sounddrv/sdl2.cc index f2f4361..91a5a85 100644 --- a/engine/src/sounddrv/sdl2.cc +++ b/engine/src/sounddrv/sdl2.cc @@ -35,7 +35,7 @@ fishbone::SoundDriver::SoundDriver() { this->impl = new fishbone::SoundDriver::Impl(); - if((this->impl->id = SDL_OpenAudioDevice(NULL, 0, &spec, NULL, 0)) > 0) { + if((this->impl->id = SDL_OpenAudioDevice(nullptr, 0, &spec, nullptr, 0)) > 0) { SDL_PauseAudioDevice(this->impl->id, 0); } } diff --git a/engine/src/soundldr/flac.cc b/engine/src/soundldr/flac.cc index 10e9255..f812160 100644 --- a/engine/src/soundldr/flac.cc +++ b/engine/src/soundldr/flac.cc @@ -1 +1,45 @@ #include + +struct fishbone::Sound::Impl { + drflac* ctx; + unsigned char* buffer; +}; + +fishbone::Sound* fishbone::FLACSoundLoader::open(fishbone::Mixer* mixer, void* buffer, size_t size) { + struct fishbone::Sound::Impl* impl; + fishbone::FLACSound* snd; + + if(size < 4 || memcmp(buffer, "fLaC", 4) != 0) return nullptr; + + impl = new struct fishbone::Sound::Impl(); + + impl->buffer = new unsigned char[size]; + memcpy(impl->buffer, buffer, size); + + if((impl->ctx = drflac_open_memory(impl->buffer, size, nullptr)) == nullptr) { + delete[] impl->buffer; + delete impl; + + return nullptr; + } + + snd = new fishbone::FLACSound(mixer, this, impl); + snd->rate = impl->ctx->sampleRate; + snd->channels = impl->ctx->channels; + + return snd; +} + +int fishbone::FLACSoundLoader::read(fishbone::Sound* sound, short* buffer, size_t frames) { + return drflac_read_pcm_frames_s16(sound->impl->ctx, frames, buffer); +} + +void fishbone::FLACSoundLoader::seek(fishbone::Sound* sound, size_t pos) { + drflac_seek_to_pcm_frame(sound->impl->ctx, pos); +} + +fishbone::FLACSound::~FLACSound() { + drflac_close(this->impl->ctx); + delete[] this->impl->buffer; + delete this->impl; +} diff --git a/engine/src/soundldr/mp3.cc b/engine/src/soundldr/mp3.cc index 10e9255..057330f 100644 --- a/engine/src/soundldr/mp3.cc +++ b/engine/src/soundldr/mp3.cc @@ -1 +1,50 @@ #include + +struct fishbone::Sound::Impl { + drmp3 ctx; + unsigned char* buffer; +}; + +fishbone::Sound* fishbone::MP3SoundLoader::open(fishbone::Mixer* mixer, void* buffer, size_t size) { + struct fishbone::Sound::Impl* impl; + fishbone::MP3Sound* snd; + unsigned char* buf = (unsigned char*)buffer; + + if(size > 2 && buf[0] == 0xff && (buf[1] == 0xfb || buf[1] == 0xf3 || buf[2] == 0xf2)) { + } else if(size > 3 && memcmp(buf, "ID3", 3) == 0) { + } else { + return nullptr; + } + + impl = new struct fishbone::Sound::Impl(); + + impl->buffer = new unsigned char[size]; + memcpy(impl->buffer, buffer, size); + + if(!drmp3_init_memory(&impl->ctx, impl->buffer, size, nullptr)) { + delete[] impl->buffer; + delete impl; + + return nullptr; + } + + snd = new fishbone::MP3Sound(mixer, this, impl); + snd->rate = impl->ctx.sampleRate; + snd->channels = impl->ctx.channels; + + return snd; +} + +int fishbone::MP3SoundLoader::read(fishbone::Sound* sound, short* buffer, size_t frames) { + return drmp3_read_pcm_frames_s16(&sound->impl->ctx, frames, buffer); +} + +void fishbone::MP3SoundLoader::seek(fishbone::Sound* sound, size_t pos) { + drmp3_seek_to_pcm_frame(&sound->impl->ctx, pos); +} + +fishbone::MP3Sound::~MP3Sound() { + drmp3_uninit(&this->impl->ctx); + delete[] this->impl->buffer; + delete this->impl; +} diff --git a/engine/src/soundldr/vorbis.cc b/engine/src/soundldr/vorbis.cc index 10e9255..56d3047 100644 --- a/engine/src/soundldr/vorbis.cc +++ b/engine/src/soundldr/vorbis.cc @@ -1 +1,47 @@ #include + +struct fishbone::Sound::Impl { + stb_vorbis* ctx; + unsigned char* buffer; +}; + +fishbone::Sound* fishbone::VorbisSoundLoader::open(fishbone::Mixer* mixer, void* buffer, size_t size) { + struct fishbone::Sound::Impl* impl; + fishbone::VorbisSound* snd; + int err; + stb_vorbis_info info; + + impl = new struct fishbone::Sound::Impl(); + + impl->buffer = new unsigned char[size]; + memcpy(impl->buffer, buffer, size); + + if((impl->ctx = stb_vorbis_open_memory(impl->buffer, size, &err, nullptr)) == nullptr) { + delete[] impl->buffer; + delete impl; + + return nullptr; + } + + info = stb_vorbis_get_info(impl->ctx); + + snd = new fishbone::VorbisSound(mixer, this, impl); + snd->rate = info.sample_rate; + snd->channels = info.channels; + + return snd; +} + +int fishbone::VorbisSoundLoader::read(fishbone::Sound* sound, short* buffer, size_t frames) { + return stb_vorbis_get_samples_short_interleaved(sound->impl->ctx, sound->channels, buffer, frames * sound->channels); +} + +void fishbone::VorbisSoundLoader::seek(fishbone::Sound* sound, size_t pos) { + if(pos == 0) stb_vorbis_seek_start(sound->impl->ctx); +} + +fishbone::VorbisSound::~VorbisSound() { + stb_vorbis_close(this->impl->ctx); + delete[] this->impl->buffer; + delete this->impl; +} diff --git a/engine/src/soundldr/wav.cc b/engine/src/soundldr/wav.cc index 10e9255..5703b68 100644 --- a/engine/src/soundldr/wav.cc +++ b/engine/src/soundldr/wav.cc @@ -1 +1,45 @@ #include + +struct fishbone::Sound::Impl { + drwav ctx; + unsigned char* buffer; +}; + +fishbone::Sound* fishbone::WAVSoundLoader::open(fishbone::Mixer* mixer, void* buffer, size_t size) { + struct fishbone::Sound::Impl* impl; + fishbone::WAVSound* snd; + + if(size < 4 || memcmp(buffer, "RIFF", 4) != 0) return nullptr; + + impl = new struct fishbone::Sound::Impl(); + + impl->buffer = new unsigned char[size]; + memcpy(impl->buffer, buffer, size); + + if(!drwav_init_memory(&impl->ctx, impl->buffer, size, nullptr)) { + delete[] impl->buffer; + delete impl; + + return nullptr; + } + + snd = new fishbone::WAVSound(mixer, this, impl); + snd->rate = impl->ctx.sampleRate; + snd->channels = impl->ctx.channels; + + return snd; +} + +int fishbone::WAVSoundLoader::read(fishbone::Sound* sound, short* buffer, size_t frames) { + return drwav_read_pcm_frames_s16(&sound->impl->ctx, frames, buffer); +} + +void fishbone::WAVSoundLoader::seek(fishbone::Sound* sound, size_t pos) { + drwav_seek_to_pcm_frame(&sound->impl->ctx, pos); +} + +fishbone::WAVSound::~WAVSound() { + drwav_uninit(&this->impl->ctx); + delete[] this->impl->buffer; + delete this->impl; +}