diff options
| author | KonAki <konaki@anokonaki.org> | 2026-10-14 18:42:50 +0800 |
|---|---|---|
| committer | KonAki <konaki@anokonaki.org> | 2026-10-14 18:42:50 +0800 |
| commit | de2bbfb85b1fab3055bf91bfcbdddc6303d9fadf (patch) | |
| tree | a07c28cf6f04de76fd31f6ec676c84c13ad1d28b /kon | |
| parent | 1daa5b5f2d712490e4518729726fe0efa606d6bc (diff) | |
load ogg through stb_vorbis when it is in ext
Diffstat (limited to 'kon')
| -rw-r--r-- | kon/konassets.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/kon/konassets.c b/kon/konassets.c index 026f052..f857d1f 100644 --- a/kon/konassets.c +++ b/kon/konassets.c @@ -117,6 +117,42 @@ static void kon_unloadImageAsset_(void *object) { #define KON_SOUND_MAX_BYTES_ ((uint64_t)1 << 30) +#ifdef KON_VORBIS + +/* from ext/stb_vorbis.c, which is built on its own. returns frames per channel or -1, output comes from malloc */ +extern int stb_vorbis_decode_memory(const unsigned char *mem, int len, int *channels, int *sample_rate, short **output); + +static void *kon_loadOggAsset_(const uint8_t *data, size_t size, size_t *bytes) { + kon_sound_t *sound; + short *frames = NULL; + int channels = 0, rate = 0, count; + + if (size == 0 || size > (size_t)INT_MAX) return NULL; + count = stb_vorbis_decode_memory(data, (int)size, &channels, &rate, &frames); + if (count <= 0 || !frames) { + free(frames); + return NULL; + } + if (channels < 1 || channels > 2 || rate < 1 || (uint64_t)count * (uint64_t)channels * sizeof(int16_t) > KON_SOUND_MAX_BYTES_) { + free(frames); + return NULL; + } + + sound = malloc(sizeof(kon_sound_t)); + if (!sound) { + free(frames); + return NULL; + } + sound->frames = frames; + sound->frameCount = (uint64_t)count; + sound->channels = (uint32_t)channels; + sound->sampleRate = (uint32_t)rate; + *bytes = (size_t)count * (size_t)channels * sizeof(int16_t); + return sound; +} + +#endif + static void *kon_loadSoundAsset_(const uint8_t *data, size_t size, size_t *bytes) { ma_decoder_config config = ma_decoder_config_init(ma_format_s16, 0, 0); ma_decoder decoder; @@ -125,6 +161,10 @@ static void *kon_loadSoundAsset_(const uint8_t *data, size_t size, size_t *bytes uint64_t total = 0, capacity = 0; uint32_t channels; +#ifdef KON_VORBIS + if (size >= 4 && memcmp(data, "OggS", 4) == 0) return kon_loadOggAsset_(data, size, bytes); +#endif + if (ma_decoder_init_memory(data, size, &config, &decoder) != MA_SUCCESS) return NULL; channels = (uint32_t)decoder.outputChannels; @@ -395,8 +435,12 @@ kon_assets_t *kon_assetsCreate(kon_pack_t *pack, const char *looseDir) { kon_addLoader_(assets, KON_ASSET_IMAGE, "image", ".png .jpg .jpeg .bmp .tga .gif", kon_loadImageAsset_, kon_unloadImageAsset_); #endif #ifdef KON_MODULE_AUDIO +#ifdef KON_VORBIS + kon_addLoader_(assets, KON_ASSET_SOUND, "sound", ".wav .mp3 .flac .ogg", kon_loadSoundAsset_, kon_unloadSoundAsset_); +#else kon_addLoader_(assets, KON_ASSET_SOUND, "sound", ".wav .mp3 .flac", kon_loadSoundAsset_, kon_unloadSoundAsset_); #endif +#endif return assets; } |
