audio formats

This commit is contained in:
Nishi 2026-05-28 00:53:37 +09:00
commit d214a59592
7 changed files with 191 additions and 3 deletions

View file

@ -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();

View file

@ -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;

View file

@ -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);
}
}

View file

@ -1 +1,45 @@
#include <fishbone/foundation.h>
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;
}

View file

@ -1 +1,50 @@
#include <fishbone/foundation.h>
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;
}

View file

@ -1 +1,47 @@
#include <fishbone/foundation.h>
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;
}

View file

@ -1 +1,45 @@
#include <fishbone/foundation.h>
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;
}