From 2a875b129b4150a2aef7146107c7f4b09f3a6f18 Mon Sep 17 00:00:00 2001 From: Nevyn Bengtsson Date: Thu, 10 Dec 2020 11:59:04 +0100 Subject: [PATCH] Fix a few bugs and style fixes * We can't realloc converters, that'll break internal pointers * inverted condition in an assert * less magic numbers * can't loop streams --- src/modules/audio/audio.c | 8 +++++--- src/modules/data/soundData.c | 19 ++++++++++--------- src/modules/data/soundData.h | 2 ++ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/modules/audio/audio.c b/src/modules/audio/audio.c index e1317e4b..c975a135 100644 --- a/src/modules/audio/audio.c +++ b/src/modules/audio/audio.c @@ -62,7 +62,6 @@ static bool mix(Source* source, float* output, uint32_t count) { ma_data_converter_get_required_input_frame_count(source->converter, count)); // ^^^ Note need to min `count` with 'capacity of aux buffer' and 'capacity of mix buffer' // could skip min-ing with one of the buffers if you can guarantee that one is bigger/equal to the other (you can because their formats are known) - ma_uint64 framesIn = source->sound->read(source->sound, source->offset, chunk, raw); ma_uint64 framesOut = sizeof(aux) / (sizeof(float) * outputChannelCountForSource(source)); @@ -71,7 +70,7 @@ static bool mix(Source* source, float* output, uint32_t count) { if (source->spatial) { state.spatializer->apply(source, source->transform, aux, mix, framesOut); } else { - memcpy(mix, aux, framesOut * OUTPUT_CHANNELS * sizeof(float)); + memcpy(mix, aux, framesOut * bytesPerAudioFrame(OUTPUT_CHANNELS, SAMPLE_F32)); } for (uint32_t i = 0; i < framesOut * OUTPUT_CHANNELS; i++) { @@ -180,6 +179,7 @@ bool lovrAudioInit(AudioConfig config[2]) { lovrAssert(state.spatializer != NULL, "Must have at least one spatializer"); arr_init(&state.converters); + arr_reserve(&state.converters, 16); return state.initialized = true; } @@ -287,7 +287,8 @@ static void _lovrSourceAssignConverter(Source *source) { config.channelsOut = outputChannelCountForSource(source); config.sampleRateIn = source->sound->sampleRate; config.sampleRateOut = LOVR_AUDIO_SAMPLE_RATE; - arr_expand(&state.converters, 1); + // can't use arr_expand because that will destroy the internal pointers inside the converter + lovrAssert(state.converters.length+1 < state.converters.capacity, "Out of space for converters"); ma_data_converter* converter = &state.converters.data[state.converters.length++]; lovrAssert(!ma_data_converter_init(&config, converter), "Problem creating Source data converter"); source->converter = converter; @@ -344,6 +345,7 @@ bool lovrSourceIsLooping(Source* source) { } void lovrSourceSetLooping(Source* source, bool loop) { + lovrAssert(loop == false || lovrSoundDataIsStream(source->sound) == false, "Can't loop streams"); source->looping = loop; } diff --git a/src/modules/data/soundData.c b/src/modules/data/soundData.c index 0fd584d6..15f02371 100644 --- a/src/modules/data/soundData.c +++ b/src/modules/data/soundData.c @@ -60,10 +60,9 @@ static uint32_t lovrSoundDataReadRing(SoundData* soundData, uint32_t offset, uin lovrAssert(acquire_status == MA_SUCCESS, "Failed to acquire ring buffer for read: %d\n", acquire_status); memcpy(data, store, availableFramesInRing * bytesPerFrame); ma_result commit_status = ma_pcm_rb_commit_read(soundData->ring, availableFramesInRing, store); - lovrAssert(commit_status != MA_SUCCESS, "Failed to commit ring buffer for read: %d\n", acquire_status); + lovrAssert(commit_status == MA_SUCCESS, "Failed to commit ring buffer for read: %d\n", acquire_status); - if (availableFramesInRing == 0 && count > 0) { - memset(data, 0, count * bytesPerFrame); + if (availableFramesInRing == 0) { return totalRead; } @@ -74,6 +73,7 @@ static uint32_t lovrSoundDataReadRing(SoundData* soundData, uint32_t offset, uin return totalRead; } + SoundData* lovrSoundDataCreateRaw(uint32_t frameCount, uint32_t channelCount, uint32_t sampleRate, SampleFormat format, struct Blob* blob) { SoundData* soundData = lovrAlloc(SoundData); soundData->format = format; @@ -95,8 +95,7 @@ SoundData* lovrSoundDataCreateRaw(uint32_t frameCount, uint32_t channelCount, ui return soundData; } -SoundData* lovrSoundDataCreateStream(uint32_t bufferSizeInFrames, uint32_t channels, uint32_t sampleRate, SampleFormat format) -{ +SoundData* lovrSoundDataCreateStream(uint32_t bufferSizeInFrames, uint32_t channels, uint32_t sampleRate, SampleFormat format) { SoundData* soundData = lovrAlloc(SoundData); soundData->format = format; soundData->sampleRate = sampleRate; @@ -176,12 +175,14 @@ size_t lovrSoundDataStreamAppendSound(SoundData *dest, SoundData *src) { return lovrSoundDataStreamAppendBlob(dest, src->blob); } +bool lovrSoundDataIsStream(SoundData *soundData) { + return soundData->read == lovrSoundDataReadRing; +} + void lovrSoundDataDestroy(void* ref) { SoundData* soundData = (SoundData*) ref; stb_vorbis_close(soundData->decoder); lovrRelease(Blob, soundData->blob); - if (soundData->ring) { - ma_pcm_rb_uninit(soundData->ring); - free(soundData->ring); - } + ma_pcm_rb_uninit(soundData->ring); + free(soundData->ring); } diff --git a/src/modules/data/soundData.h b/src/modules/data/soundData.h index 880748ad..ef49ac40 100644 --- a/src/modules/data/soundData.h +++ b/src/modules/data/soundData.h @@ -34,4 +34,6 @@ SoundData* lovrSoundDataCreateFromFile(struct Blob* blob, bool decode); // returns the number of frames successfully appended (if it's less than the size of blob, the internal ring buffer is full) size_t lovrSoundDataStreamAppendBlob(SoundData *dest, struct Blob* blob); size_t lovrSoundDataStreamAppendSound(SoundData *dest, SoundData *src); + +bool lovrSoundDataIsStream(SoundData *soundData); void lovrSoundDataDestroy(void* ref);