summaryrefslogtreecommitdiff
path: root/kon/konassets.c
diff options
context:
space:
mode:
Diffstat (limited to 'kon/konassets.c')
-rw-r--r--kon/konassets.c44
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;
}