From aa87dba34fc2db2cc747b501af4c5de2c147b718 Mon Sep 17 00:00:00 2001 From: Martmists Date: Sat, 31 Jul 2021 01:15:40 +0200 Subject: [PATCH] DiffSurround and WaveBuffer_I32 --- CMakeLists.txt | 2 + src/effects/DiffSurround.cpp | 68 ++++++++++++++ src/effects/DiffSurround.h | 29 ++++++ src/effects/SpeakerCorrection.cpp | 4 +- src/utils/WaveBuffer_I32.cpp | 149 ++++++++++++++++++++++++++++++ src/utils/WaveBuffer_I32.h | 33 +++++++ 6 files changed, 284 insertions(+), 1 deletion(-) create mode 100644 src/effects/DiffSurround.cpp create mode 100644 src/effects/DiffSurround.h create mode 100644 src/utils/WaveBuffer_I32.cpp create mode 100644 src/utils/WaveBuffer_I32.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 9541718..fe1456a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ set(FILES # Effects src/effects/AnalogX.cpp src/effects/Cure.cpp + src/effects/DiffSurround.cpp src/effects/DynamicSystem.cpp src/effects/Reverberation.cpp src/effects/SpeakerCorrection.cpp @@ -46,6 +47,7 @@ set(FILES src/utils/PolesFilter.cpp src/utils/Subwoofer.cpp src/utils/TimeConstDelay.cpp + src/utils/WaveBuffer_I32.cpp ) add_library( diff --git a/src/effects/DiffSurround.cpp b/src/effects/DiffSurround.cpp new file mode 100644 index 0000000..b9e810e --- /dev/null +++ b/src/effects/DiffSurround.cpp @@ -0,0 +1,68 @@ +// +// Created by mart on 7/31/21. +// + +#include +#include "DiffSurround.h" +#include "../constants.h" + +DiffSurround::DiffSurround() { + this->samplerate = DEFAULT_SAMPLERATE; + this->delayTime = 0.f; + this->enabled = false; + this->buffers[0] = new WaveBuffer_I32(1, 0x1000); + this->buffers[1] = new WaveBuffer_I32(1, 0x1000); +} + +DiffSurround::~DiffSurround() { + delete this->buffers[0]; + delete this->buffers[1]; +} + +void DiffSurround::Process(float *samples, uint32_t size) { + float* bufs[2]; + float* outbufs[2]; + + if (this->enabled) { + bufs[0] = this->buffers[0]->PushZerosGetBuffer(size); + bufs[1] = this->buffers[1]->PushZerosGetBuffer(size); + + for (int i = 0; i < size * 2; i++) { + bufs[i % 2][i / 2] = samples[i]; + } + + outbufs[0] = this->buffers[0]->GetCurrentBufferI32Ptr(); + outbufs[1] = this->buffers[1]->GetCurrentBufferI32Ptr(); + + for (int i = 0; i < size * 2; i++) { + samples[i] = outbufs[i % 2][i / 2]; + } + + this->buffers[0]->PopSamples(size, false); + this->buffers[1]->PopSamples(size, false); + } +} + +void DiffSurround::Reset() { + this->buffers[0]->Reset(); + this->buffers[1]->Reset(); + + this->buffers[1]->PushZeros((uint32_t)(this->delayTime / 1000.f * (float)this->samplerate)); +} + +void DiffSurround::SetDelayTime(float value) { + this->delayTime = value; + Reset(); +} + +void DiffSurround::SetEnable(bool enabled) { + this->enabled = enabled; + if (this->enabled) { + Reset(); + } +} + +void DiffSurround::SetSamplingRate(uint32_t samplerate) { + this->samplerate = samplerate; + Reset(); +} diff --git a/src/effects/DiffSurround.h b/src/effects/DiffSurround.h new file mode 100644 index 0000000..045bf00 --- /dev/null +++ b/src/effects/DiffSurround.h @@ -0,0 +1,29 @@ +// +// Created by mart on 7/31/21. +// + +#pragma once + + +#include +#include "../utils/WaveBuffer_I32.h" + +class DiffSurround { +public: + DiffSurround(); + ~DiffSurround(); + + void Process(float* samples, uint32_t size); + void Reset(); + + void SetDelayTime(float value); + void SetEnable(bool enabled); + void SetSamplingRate(uint32_t samplerate); + + uint32_t samplerate; + bool enabled; + float delayTime; + WaveBuffer_I32* buffers[2]; +}; + + diff --git a/src/effects/SpeakerCorrection.cpp b/src/effects/SpeakerCorrection.cpp index 885f214..dce65a0 100644 --- a/src/effects/SpeakerCorrection.cpp +++ b/src/effects/SpeakerCorrection.cpp @@ -38,7 +38,9 @@ void SpeakerCorrection::Reset() { void SpeakerCorrection::SetEnable(bool enabled) { this->enabled = enabled; - Reset(); + if (this->enabled) { + Reset(); + } } void SpeakerCorrection::SetSamplingRate(uint32_t samplerate) { diff --git a/src/utils/WaveBuffer_I32.cpp b/src/utils/WaveBuffer_I32.cpp new file mode 100644 index 0000000..8e30d20 --- /dev/null +++ b/src/utils/WaveBuffer_I32.cpp @@ -0,0 +1,149 @@ +// +// Created by mart on 7/31/21. +// + +#include +#include +#include "WaveBuffer_I32.h" + +WaveBuffer_I32::WaveBuffer_I32(int channels, uint32_t size) { + this->channels = channels; + this->size = size * channels; + this->index = 0; + this->buffer = (float*)malloc(this->size * sizeof(float)); +} + +WaveBuffer_I32::~WaveBuffer_I32() { + free(this->buffer); +} + +void WaveBuffer_I32::Reset() { + this->index = 0; +} + +uint32_t WaveBuffer_I32::GetBufferOffset() { + return this->index / this->channels; +} + +uint32_t WaveBuffer_I32::GetBufferSize() { + return this->size / this->channels; +} + +float *WaveBuffer_I32::GetCurrentBufferI32Ptr() { + return this->buffer; +} + +uint32_t WaveBuffer_I32::PopSamples(uint32_t size, bool resetIndex) { + if (this->buffer == nullptr || this->size == 0) { + return 0; + } + + if (this->channels * size <= this->index) { + this->index -= this->channels * size; + memmove(this->buffer, &this->buffer[this->channels*size], this->index * sizeof(float)); + return size; + } + + if (resetIndex) { + uint32_t idx = this->index; + this->index = 0; + return idx / this->channels; + } + + return 0; +} + +uint32_t WaveBuffer_I32::PopSamples(float *dest, uint32_t size, bool resetIndex) { + if (this->buffer == nullptr || this->size == 0 || dest == nullptr) { + return 0; + } + + if (this->channels * size <= this->index) { + memcpy(dest, this->buffer, this->index * sizeof(float)); + this->index -= this->channels * size; + memmove(this->buffer, &this->buffer[this->channels*size], this->index * sizeof(float)); + return size; + } + + if (resetIndex) { + uint32_t idx = this->index; + memcpy(dest, this->buffer, this->index * sizeof(float)); + this->index = 0; + return idx / this->channels; + } + + return 0; +} + +int WaveBuffer_I32::PushSamples(float *source, uint32_t size) { + if (this->buffer == nullptr) { + return 0; + } + + if (size > 0) { + if (this->size < this->channels * size + this->index) { + float* buf = (float*)malloc((this->channels * size + this->index) * sizeof(float)); + if (buf == nullptr) { + return 0; + } + memcpy(buf, this->buffer, this->index * sizeof(float)); + free(this->buffer); + this->buffer = buf; + this->size = this->channels * size + this->index; + } + memcpy(&this->buffer[this->index], source, this->channels * size * sizeof(float)); + this->index += this->channels * size; + } + + return 1; +} + +int WaveBuffer_I32::PushZeros(uint32_t size) { + if (this->buffer == nullptr) { + return 0; + } + + if (size > 0) { + if (this->size < this->channels * size + this->index) { + float* buf = (float*)malloc((this->channels * size + this->index) * sizeof(float)); + if (buf == nullptr) { + return 0; + } + memcpy(buf, this->buffer, this->index * sizeof(float)); + free(this->buffer); + this->buffer = buf; + this->size = this->channels * size + this->index; + } + memset(&this->buffer[this->index], 0, this->channels * size * sizeof(float)); + this->index += this->channels * size; + } + + return 1; +} + +float *WaveBuffer_I32::PushZerosGetBuffer(uint32_t size) { + if (this->buffer == nullptr) { + return nullptr; + } + + if (size > 0) { + if (this->size < this->channels * size + this->index) { + float* buf = (float*)malloc((this->channels * size + this->index) * sizeof(float)); + if (buf == nullptr) { + return nullptr; + } + memcpy(buf, this->buffer, this->index * sizeof(float)); + free(this->buffer); + this->buffer = buf; + this->size = this->channels * size + this->index; + } + memset(&this->buffer[this->index], 0, this->channels * size * sizeof(float)); + this->index += this->channels * size; + } + + return &this->buffer[this->index]; +} + +void WaveBuffer_I32::SetBufferOffset(uint32_t offset) { + this->index = offset; +} diff --git a/src/utils/WaveBuffer_I32.h b/src/utils/WaveBuffer_I32.h new file mode 100644 index 0000000..eb6646b --- /dev/null +++ b/src/utils/WaveBuffer_I32.h @@ -0,0 +1,33 @@ +// +// Created by mart on 7/31/21. +// + +#pragma once + + +#include + +class WaveBuffer_I32 { +public: + WaveBuffer_I32(int channels, uint32_t size); + ~WaveBuffer_I32(); + + void Reset(); + + uint32_t GetBufferOffset(); + uint32_t GetBufferSize(); + float* GetCurrentBufferI32Ptr(); + uint32_t PopSamples(uint32_t size, bool resetIndex); + uint32_t PopSamples(float* dest, uint32_t size, bool resetIndex); + int PushSamples(float* source, uint32_t size); + int PushZeros(uint32_t size); + float* PushZerosGetBuffer(uint32_t size); + void SetBufferOffset(uint32_t offset); + + float* buffer; + uint32_t size; + uint32_t index; + int channels; +}; + +