diff --git a/Kinc b/Kinc index 5697b8921..a07952637 160000 --- a/Kinc +++ b/Kinc @@ -1 +1 @@ -Subproject commit 5697b89214841482ba05e488492501ce584d1380 +Subproject commit a07952637c50ec2eabc0bbc0a9c2bd8770527288 diff --git a/Sources/Kore/Audio1/Audio.cpp b/Sources/Kore/Audio1/Audio.cpp index 965351ff5..27f6b483f 100644 --- a/Sources/Kore/Audio1/Audio.cpp +++ b/Sources/Kore/Audio1/Audio.cpp @@ -44,10 +44,10 @@ namespace { }*/ } -void Audio1::mix(int samples) { - for (int i = 0; i < samples; ++i) { - bool left = (i % 2) == 0; - float value = 0; +void Audio1::mix(uint32_t samples) { + for (uint32_t i = 0; i < samples; ++i) { + float leftValue = 0; + float rightValue = 0; #if 0 __m128 sseSamples[4]; for (int i = 0; i < channelCount; i += 4) { @@ -74,12 +74,11 @@ void Audio1::mix(int samples) { for (int i = 0; i < channelCount; ++i) { if (channels[i].sound != nullptr) { // value += *(s16*)&channels[i].sound->data[(int)channels[i].position] / 32767.0f * channels[i].sound->volume(); - if (left) - value += sampleLinear(channels[i].sound->left, channels[i].position) * channels[i].volume * channels[i].sound->volume(); - else - value += sampleLinear(channels[i].sound->right, channels[i].position) * channels[i].volume * channels[i].sound->volume(); - value = max(min(value, 1.0f), -1.0f); - if (!left) channels[i].position += channels[i].pitch / channels[i].sound->sampleRatePos; + leftValue += sampleLinear(channels[i].sound->left, channels[i].position) * channels[i].volume * channels[i].sound->volume(); + leftValue = max(min(leftValue, 1.0f), -1.0f); + rightValue += sampleLinear(channels[i].sound->right, channels[i].position) * channels[i].volume * channels[i].sound->volume(); + rightValue = max(min(rightValue, 1.0f), -1.0f); + channels[i].position += channels[i].pitch / channels[i].sound->sampleRatePos; // channels[i].position += 2; if (channels[i].position + 1 >= channels[i].sound->size) { if (channels[i].loop) { @@ -93,15 +92,23 @@ void Audio1::mix(int samples) { } for (int i = 0; i < channelCount; ++i) { if (streams[i].stream != nullptr) { - value += streams[i].stream->nextSample() * streams[i].stream->volume(); - value = max(min(value, 1.0f), -1.0f); - if (streams[i].stream->ended()) streams[i].stream = nullptr; + float *samples = streams[i].stream->nextFrame(); + leftValue += samples[0] * streams[i].stream->volume(); + leftValue = max(min(leftValue, 1.0f), -1.0f); + rightValue += samples[1] * streams[i].stream->volume(); + rightValue = max(min(rightValue, 1.0f), -1.0f); + if (streams[i].stream->ended()) { + streams[i].stream = nullptr; + } } } for (int i = 0; i < channelCount; ++i) { if (videos[i].stream != nullptr) { - value += kinc_internal_video_sound_stream_next_sample(videos[i].stream); - value = max(min(value, 1.0f), -1.0f); + float *samples = kinc_internal_video_sound_stream_next_frame(videos[i].stream); + leftValue += samples[0]; + leftValue = max(min(leftValue, 1.0f), -1.0f); + rightValue += samples[1]; + rightValue = max(min(rightValue, 1.0f), -1.0f); if (kinc_internal_video_sound_stream_ended(videos[i].stream)) { videos[i].stream = nullptr; } @@ -109,9 +116,12 @@ void Audio1::mix(int samples) { } mutex.unlock(); #endif - *(float *)&Audio2::buffer.data[Audio2::buffer.writeLocation] = value; - Audio2::buffer.writeLocation += 4; - if (Audio2::buffer.writeLocation >= Audio2::buffer.dataSize) Audio2::buffer.writeLocation = 0; + Audio2::buffer.channels[0][Audio2::buffer.writeLocation] = leftValue; + Audio2::buffer.channels[1][Audio2::buffer.writeLocation] = rightValue; + Audio2::buffer.writeLocation += 1; + if (Audio2::buffer.writeLocation >= Audio2::buffer.dataSize) { + Audio2::buffer.writeLocation = 0; + } } } diff --git a/Sources/Kore/Audio1/Audio.h b/Sources/Kore/Audio1/Audio.h index b527e5c1e..3c56c4350 100644 --- a/Sources/Kore/Audio1/Audio.h +++ b/Sources/Kore/Audio1/Audio.h @@ -33,6 +33,6 @@ namespace Kore { void stop(SoundStream *stream); void play(kinc_internal_video_sound_stream *stream); void stop(kinc_internal_video_sound_stream *stream); - void mix(int samples); + void mix(uint32_t samples); } } diff --git a/Sources/Kore/Audio1/Sound.h b/Sources/Kore/Audio1/Sound.h index 18f71ae0a..22e51dd4e 100644 --- a/Sources/Kore/Audio1/Sound.h +++ b/Sources/Kore/Audio1/Sound.h @@ -4,13 +4,19 @@ #include namespace Kore { + struct BufferFormat { + int channels; + int samplesPerSecond; + int bitsPerSample; + }; + struct Sound { public: Sound(const char *filename); Sound(Reader &file, const char *filename); ~Sound(); void load(Reader &file, const char *filename); - Audio2::BufferFormat format; + BufferFormat format; float volume(); void setVolume(float value); s16 *left; diff --git a/Sources/Kore/Audio1/SoundStream.cpp b/Sources/Kore/Audio1/SoundStream.cpp index bf1c5c50b..312d1d1f2 100644 --- a/Sources/Kore/Audio1/SoundStream.cpp +++ b/Sources/Kore/Audio1/SoundStream.cpp @@ -7,7 +7,7 @@ using namespace Kore; -SoundStream::SoundStream(const char *filename, bool looping) : myLooping(looping), myVolume(1), decoded(false), rateDecodedHack(false), end(false) { +SoundStream::SoundStream(const char *filename, bool looping) : myLooping(looping), myVolume(1), rateDecodedHack(false), end(false) { FileReader file(filename); buffer = new u8[file.size()]; u8 *filecontent = (u8 *)file.readAll(); @@ -66,47 +66,42 @@ void SoundStream::reset() { if (vorbis != nullptr) stb_vorbis_seek_start(vorbis); end = false; rateDecodedHack = false; - decoded = false; } -float SoundStream::nextSample() { - if (vorbis == nullptr) return 0; +float *SoundStream::nextFrame() { + if (vorbis == nullptr) { + for (int i = 0; i < chans; ++i) { + samples[i] = 0; + } + return samples; + } if (rate == 22050) { if (rateDecodedHack) { - if (decoded) { - decoded = false; - return samples[0]; - } - else { - rateDecodedHack = false; - decoded = true; - return samples[1]; - } + rateDecodedHack = false; + return samples; } } - if (decoded) { - decoded = false; - if (chans == 1) { - return samples[0]; + + float left, right; + float *samplesArray[2] = {&left, &right}; + int read = stb_vorbis_get_samples_float(vorbis, chans, samplesArray, 1); + if (read == 0) { + if (looping()) { + stb_vorbis_seek_start(vorbis); + stb_vorbis_get_samples_float(vorbis, chans, samplesArray, 1); } else { - return samples[1]; - } - } - else { - int read = stb_vorbis_get_samples_float_interleaved(vorbis, chans, &samples[0], chans); - if (read == 0) { - if (looping()) { - stb_vorbis_seek_start(vorbis); - stb_vorbis_get_samples_float_interleaved(vorbis, chans, &samples[0], chans); - } - else { - end = true; - return 0.0f; + end = true; + for (int i = 0; i < chans; ++i) { + samples[i] = 0; } + return samples; } - decoded = true; - rateDecodedHack = true; - return samples[0]; } + + samples[0] = samplesArray[0][0]; + samples[1] = samplesArray[1][0]; + + rateDecodedHack = true; + return samples; } diff --git a/Sources/Kore/Audio1/SoundStream.h b/Sources/Kore/Audio1/SoundStream.h index 97b949020..d95fdb70e 100644 --- a/Sources/Kore/Audio1/SoundStream.h +++ b/Sources/Kore/Audio1/SoundStream.h @@ -8,7 +8,7 @@ namespace Kore { class SoundStream { public: SoundStream(const char *filename, bool looping); - float nextSample(); + float *nextFrame(); int channels(); int sampleRate(); bool looping(); @@ -26,7 +26,6 @@ namespace Kore { int rate; bool myLooping; float myVolume; - bool decoded; bool rateDecodedHack; bool end; float samples[2]; diff --git a/Sources/Kore/Audio2/Audio.cpp b/Sources/Kore/Audio2/Audio.cpp index 334b93d36..423ca4641 100644 --- a/Sources/Kore/Audio2/Audio.cpp +++ b/Sources/Kore/Audio2/Audio.cpp @@ -1,49 +1,43 @@ #include "Audio.h" -#include - #include using namespace Kore; -void (*Audio2::audioCallback)(int samples) = nullptr; +void (*Audio2::audioCallback)(uint32_t samples) = nullptr; Audio2::Buffer Audio2::buffer; -int Audio2::samplesPerSecond = 44100; namespace { - void audio(kinc_a2_buffer_t *buffer, int samples) { + void audio(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata) { if (Audio2::audioCallback != nullptr) { Audio2::audioCallback(samples); } else { - for (int i = 0; i < samples; ++i) { - *(float *)&Audio2::buffer.data[Audio2::buffer.writeLocation] = 0.0f; - Audio2::buffer.writeLocation += 4; + for (uint32_t i = 0; i < samples; ++i) { + Audio2::buffer.channels[0][Audio2::buffer.writeLocation] = 0.0f; + Audio2::buffer.channels[1][Audio2::buffer.writeLocation] = 0.0f; + Audio2::buffer.writeLocation += 1; if (Audio2::buffer.writeLocation >= Audio2::buffer.dataSize) { Audio2::buffer.writeLocation = 0; } } } - for (int i = 0; i < samples; ++i) { - float sample = *(float *)&Audio2::buffer.data[Audio2::buffer.readLocation]; - Audio2::buffer.readLocation += 4; + for (uint32_t i = 0; i < samples; ++i) { + float leftSample = Audio2::buffer.channels[0][Audio2::buffer.readLocation]; + float rightSample = Audio2::buffer.channels[1][Audio2::buffer.readLocation]; + Audio2::buffer.readLocation += 1; if (Audio2::buffer.readLocation >= Audio2::buffer.dataSize) { Audio2::buffer.readLocation = 0; } - *(float *)&buffer->data[buffer->write_location] = sample; - buffer->write_location += 4; + buffer->channels[0][buffer->write_location] = leftSample; + buffer->channels[1][buffer->write_location] = rightSample; + buffer->write_location += 1; if (buffer->write_location >= buffer->data_size) { buffer->write_location = 0; } } } - -#if defined(KORE_IOS) || defined(KORE_MACOS) - void sample_rate_changed() { - Audio2::samplesPerSecond = kinc_a2_samples_per_second; - } -#endif } void Audio2::init() { @@ -51,12 +45,10 @@ void Audio2::init() { buffer.readLocation = 0; buffer.writeLocation = 0; buffer.dataSize = 128 * 1024; - buffer.data = new u8[buffer.dataSize]; - Audio2::samplesPerSecond = kinc_a2_samples_per_second; - kinc_a2_set_callback(audio); -#if defined(KORE_IOS) || defined(KORE_MACOS) - kinc_a2_set_sample_rate_callback(sample_rate_changed); -#endif + buffer.channelCount = 2; + buffer.channels[0] = new float[buffer.dataSize]; + buffer.channels[1] = new float[buffer.dataSize]; + kinc_a2_set_callback(audio, nullptr); } void Audio2::update() { @@ -66,3 +58,7 @@ void Audio2::update() { void Audio2::shutdown() { kinc_a2_shutdown(); } + +uint32_t Audio2::samplesPerSecond() { + return kinc_a2_samples_per_second(); +} diff --git a/Sources/Kore/Audio2/Audio.h b/Sources/Kore/Audio2/Audio.h index 3b9b7fc19..1d8bae2f4 100644 --- a/Sources/Kore/Audio2/Audio.h +++ b/Sources/Kore/Audio2/Audio.h @@ -2,28 +2,23 @@ #include +#include + namespace Kore { namespace Audio2 { void init(); void update(); void shutdown(); + uint32_t samplesPerSecond(); - extern int samplesPerSecond; - - extern void (*audioCallback)(int samples); - - struct BufferFormat { - int channels; - int samplesPerSecond; - int bitsPerSample; - }; + extern void (*audioCallback)(uint32_t samples); struct Buffer { - BufferFormat format; - u8 *data; - int dataSize; - int readLocation; - int writeLocation; + uint8_t channelCount; + float *channels[KINC_A2_MAX_CHANNELS]; + uint32_t dataSize; + uint32_t readLocation; + uint32_t writeLocation; }; extern Buffer buffer;