From 3acfe2ccf2ed3ae4ef47e575cd44ec0409f8379f Mon Sep 17 00:00:00 2001 From: Igor Bochkariov Date: Mon, 6 Jun 2022 05:16:03 +0400 Subject: [PATCH] rewrite buffers using interleaved format, fix distortion on AAC with 7 channels --- Builds/VisualStudio2019/resources.aps | Bin 57148 -> 95532 bytes Builds/VisualStudio2019/resources.rc | 8 ++-- Source/asio_api.cpp | 63 ++++++-------------------- Source/asio_api.h | 6 +-- Source/writer.cpp | 34 +++++++------- Source/writer.h | 5 +- 6 files changed, 40 insertions(+), 76 deletions(-) diff --git a/Builds/VisualStudio2019/resources.aps b/Builds/VisualStudio2019/resources.aps index 89faecc07b7f26c6908e15291bdd6d92bfd3aa10..606a6a0ae688f21c800317c5fd3b42aa21406fbb 100644 GIT binary patch delta 28016 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

T$nN|(y#uBc!E|ztrm7QtPVI(POGuVBf&Ll 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, input_channels_number + output_channels_number, preferred_buffer_size, &callbacks[index]); refuse(error); - for (int i = 0; i < input_channels_number; i += 1) { - sample_type_buffers[i] = (float*)calloc(preferred_buffer_size, sizeof(float)); + for (int i = 0; i < MAX_INPUT_CHANNELS; i++) { + circlebuf_init(&input_buffers[i]); + input_buffer_pointers[i] = &input_buffers[i]; } - circlebuf_init(&input_buffer); - circlebuf_init(&interleaved_buffer); driver_buffers_allocated = true; initialize_latencies(); @@ -197,17 +196,7 @@ void AsioDevice::close() { if (driver_buffers_allocated) { driver->disposeBuffers(); - - for (int i = 0; i < input_channels_number; i += 1) { - if (sample_type_buffers[i]) { - free(sample_type_buffers[i]); - sample_type_buffers[i] = NULL; - } - } - - circlebuf_free(&input_buffer); - circlebuf_free(&interleaved_buffer); - + for (int i = 0; i < MAX_INPUT_CHANNELS; i++) circlebuf_free(&input_buffers[i]); driver_buffers_allocated = false; } @@ -291,7 +280,7 @@ DWORD WINAPI AsioDevice::CaptureThread(void* data) { int wait_result = WaitForMultipleObjects(2, signals, false, INFINITE); if (wait_result == WAIT_OBJECT_0) { EnterCriticalSection(&device->buffer_section); - if (writer) writer->write_packet(&device->input_buffer); + if (writer) writer->write_packet(device->input_buffer_pointers); LeaveCriticalSection(&device->buffer_section); } else if (wait_result == WAIT_OBJECT_0 + 1) { @@ -394,45 +383,20 @@ ASIOTime* AsioDevice::buffer_switch_time_info(int device_index, ASIOTime* timeIn UNREFERENCED_PARAMETER(processNow); } -static inline void* fill_interleaved_buffer(size_t channels, size_t samples, float** fdata, struct circlebuf* interleaved_buffer) { - circlebuf_upsize(interleaved_buffer, channels * samples * BYTES_PER_SAMPLE); - float* buffer = (float*)circlebuf_data(interleaved_buffer, 0); - extern float last_buffer_magnitude[MAX_INPUT_CHANNELS]; - - for (size_t c = 0; c < channels; c++) { - if (fdata[c]) { - float sum_of_squares = 0.0f; - for (size_t i = 0; i < samples; i++) { - float sample = buffer[i * channels + c] = fdata[c][i]; - sum_of_squares += sample * sample; - } - last_buffer_magnitude[c] = sqrtf(sum_of_squares / samples); - } - else { - for (size_t i = 0; i < samples; i++) { - buffer[i * channels + c] = 0.0f; - } - last_buffer_magnitude[c] = 0.0f; - } - } - for (size_t c = channels; c < MAX_INPUT_CHANNELS; c++) { - last_buffer_magnitude[c] = 0.0f; - } - - return buffer; -} - static ULONGLONG last_time = 0; void AsioDevice::push_received_buffers(int buffer_index) { int skipped = 0; + for (int channel = 0; channel < input_channels_number; channel += 1) { if (active_channels[channel]) { + size_t data_size = input_buffers[channel - skipped].size; + circlebuf_upsize(&input_buffers[channel - skipped], data_size + (size_t)preferred_buffer_size * BYTES_PER_SAMPLE); if (sample_type == ASIOSTInt32LSB) { - convertInt32ToFloat((const char*)buffer_infos[channel].buffers[buffer_index], sample_type_buffers[channel - skipped], preferred_buffer_size); + convertInt32ToFloat((const char*)buffer_infos[channel].buffers[buffer_index], (float*)circlebuf_data(&input_buffers[channel - skipped], data_size), preferred_buffer_size); } else { - memcpy(sample_type_buffers[channel - skipped], buffer_infos[channel].buffers[buffer_index], preferred_buffer_size * BYTES_PER_SAMPLE); + memcpy(circlebuf_data(&input_buffers[channel - skipped], data_size), buffer_infos[channel].buffers[buffer_index], (size_t)preferred_buffer_size * BYTES_PER_SAMPLE); } } else { @@ -440,12 +404,13 @@ void AsioDevice::push_received_buffers(int buffer_index) { } } - fill_interleaved_buffer(active_channels_count, preferred_buffer_size, sample_type_buffers, &interleaved_buffer); - circlebuf_push_back(&input_buffer, circlebuf_data(&interleaved_buffer, 0), active_channels_count * preferred_buffer_size * BYTES_PER_SAMPLE); - extern float last_buffer_magnitude[MAX_INPUT_CHANNELS]; extern float buffer_magnitude[MAX_INPUT_CHANNELS]; + for (int channel = 0; channel < active_channels_count; channel++) { + last_buffer_magnitude[channel] = ((float*)circlebuf_data(&input_buffers[channel], 0))[0]; + } + for (int channel = 0; channel < input_channels_number; channel += 1) { if (buffer_magnitude[channel] < last_buffer_magnitude[channel]) { buffer_magnitude[channel] = last_buffer_magnitude[channel]; diff --git a/Source/asio_api.h b/Source/asio_api.h index ac6a565..f0ad6a5 100644 --- a/Source/asio_api.h +++ b/Source/asio_api.h @@ -33,10 +33,8 @@ class AsioDevice { int output_samples_per_10ms = 0; - float* sample_type_buffers[MAX_INPUT_CHANNELS] = { 0 }; - - struct circlebuf input_buffer = { 0 }; - struct circlebuf interleaved_buffer = { 0 }; + circlebuf input_buffers[MAX_INPUT_CHANNELS] = { 0 }; + circlebuf *input_buffer_pointers[MAX_INPUT_CHANNELS] = { 0 }; WinHandle stop_signal, receive_signal; WinHandle capture_thread; diff --git a/Source/writer.cpp b/Source/writer.cpp index bf8df35..3ff2db9 100644 --- a/Source/writer.cpp +++ b/Source/writer.cpp @@ -12,14 +12,12 @@ Writer::Writer(class AsioDevice *_device) { core_audio_ready = load_core_audio(); - circlebuf_init(&encode_buffer); circlebuf_init(&output_buffer); } Writer::~Writer() { uninit(); - circlebuf_free(&encode_buffer); circlebuf_free(&output_buffer); DeleteCriticalSection(&file_section); @@ -53,8 +51,8 @@ void Writer::init(double _sample_rate) { in.mSampleRate = sample_rate; in.mChannelsPerFrame = channels; in.mFormatID = kAudioFormatLinearPCM; - in.mFormatFlags = kAudioFormatFlagIsPacked | kAudioFormatFlagIsFloat; - in.mBytesPerFrame = channels * BYTES_PER_SAMPLE; + in.mFormatFlags = kAudioFormatFlagIsPacked | kAudioFormatFlagIsFloat | kAudioFormatFlagIsNonInterleaved; + in.mBytesPerFrame = BYTES_PER_SAMPLE; in.mFramesPerPacket = 1; in.mBytesPerPacket = in.mFramesPerPacket * in.mBytesPerFrame; in.mBitsPerChannel = BYTES_PER_SAMPLE * 8; @@ -100,7 +98,7 @@ void Writer::init(double _sample_rate) { kAudioChannelLayoutTag_AAC_4_0, kAudioChannelLayoutTag_AAC_5_0, kAudioChannelLayoutTag_AAC_6_0, - kAudioChannelLayoutTag_AAC_7_0, //distortion + kAudioChannelLayoutTag_AAC_7_0, kAudioChannelLayoutTag_AAC_Octagonal, }; @@ -220,18 +218,20 @@ OSStatus Writer::input_data_provider(AudioConverterRef inAudioConverter, UInt32* UInt32 bytes_required = (*ioNumberDataPackets) * active_writer->bytes_per_input_packet; - if (active_writer->input_buffer->size < bytes_required) { + if (active_writer->input_buffers[0]->size < bytes_required) { *ioNumberDataPackets = 0; return MORE_DATA_REQUIRED; } - circlebuf_upsize(&active_writer->encode_buffer, bytes_required); - - ioData->mBuffers[0].mNumberChannels = active_writer->channels; - ioData->mBuffers[0].mDataByteSize = bytes_required; - ioData->mBuffers[0].mData = circlebuf_data(&active_writer->encode_buffer, 0); - - circlebuf_pop_front(active_writer->input_buffer, ioData->mBuffers[0].mData, bytes_required); + for (int channel = 0; channel < active_writer->channels; channel++) { + ioData->mBuffers[channel].mNumberChannels = 1; + ioData->mBuffers[channel].mDataByteSize = bytes_required; + if (active_writer->input_buffers[channel]->size < bytes_required) { + circlebuf_push_back_zero(active_writer->input_buffers[channel], bytes_required); + } + ioData->mBuffers[channel].mData = circlebuf_data(active_writer->input_buffers[channel], 0); + circlebuf_pop_front(active_writer->input_buffers[channel], ioData->mBuffers[channel].mData, bytes_required); + } return 0; @@ -239,7 +239,7 @@ OSStatus Writer::input_data_provider(AudioConverterRef inAudioConverter, UInt32* UNUSED_PARAMETER(outDataPacketDescription); } -void Writer::write_packet(circlebuf* _input_buffer) { +void Writer::write_packet(circlebuf **_input_buffers) { if (!core_audio_ready) { message = "MCAC: AAC library not available"; PostMessage(message_window, WM_USER_WRITER_ERROR, 0, 0); @@ -247,11 +247,13 @@ void Writer::write_packet(circlebuf* _input_buffer) { } if (stop) { - circlebuf_pop_front(_input_buffer, nullptr, _input_buffer->size); + for (int i = 0; i < MAX_INPUT_CHANNELS; i++) { + circlebuf_pop_front(_input_buffers[i], nullptr, _input_buffers[i]->size); + } return; } - input_buffer = _input_buffer; + input_buffers = _input_buffers; UInt32 packets_count = 1; AudioBufferList output_buffers = { 0 }; diff --git a/Source/writer.h b/Source/writer.h index 9f78d75..0bc18c0 100644 --- a/Source/writer.h +++ b/Source/writer.h @@ -40,9 +40,8 @@ class Writer { AudioConverterRef converter = nullptr; unsigned bytes_per_input_packet = 0; unsigned sample_rate = 0; - struct circlebuf encode_buffer = { 0 }; struct circlebuf output_buffer = { 0 }; - circlebuf* input_buffer = nullptr; + circlebuf** input_buffers = nullptr; FILE* file = nullptr; bool stop = true; CRITICAL_SECTION file_section; @@ -63,5 +62,5 @@ class Writer { bool open(); void close(bool report = true); static OSStatus input_data_provider(AudioConverterRef inAudioConverter, UInt32* ioNumberDataPackets, AudioBufferList* ioData, AudioStreamPacketDescription** outDataPacketDescription, void* inUserData); - void write_packet(circlebuf* _input_buffer); + void write_packet(circlebuf **_input_buffers); };