diff --git a/dsp_types.hpp b/common/dsp_types.hpp similarity index 100% rename from dsp_types.hpp rename to common/dsp_types.hpp diff --git a/mix.hpp b/common/mix.hpp similarity index 66% rename from mix.hpp rename to common/mix.hpp index 8007d6a..faf5003 100644 --- a/mix.hpp +++ b/common/mix.hpp @@ -1,10 +1,7 @@ -#include "delay/buffer_multi.hpp" -#include - #ifndef MIX_HPP #define MIX_HPP -#include +#include // Use like `Householder::inPlace(data)` - size must be ≥ 1 template @@ -69,22 +66,22 @@ class Hadamard } }; -template +template class Shuffle { public: - static inline void outOfPlace(dsp::Buffer &in, dsp::Buffer &out, dsp::Buffer &shuffle_spec) + static inline void outOfPlace(T *in, T *out, const int *shuffle_spec) { - for (int c=0; c < shuffle_spec.capacity(); c++) + for (int c=0; c < numCh; c++) { T sign = 1; - int s = (int)shuffle_spec[c]; + int s = shuffle_spec[c]; if (s < 0) { sign = -1; s *= -1; } - if (s >= shuffle_spec.capacity()) + if (s >= numCh) { s = 0; } @@ -92,28 +89,6 @@ class Shuffle out[s] = sign * in[c]; } }; - static inline void outOfPlace(dsp::BufferMulti &in, dsp::BufferMulti &out, dsp::Buffer &shuffle_spec) - { - for (int c=0; c < shuffle_spec.capacity(); c++) - { - T sign = 1; - int s = (int)shuffle_spec[c]; - if (s < 0) - { - sign = -1; - s *= -1; - } - if (s >= shuffle_spec.capacity()) - { - s = 0; - } - - for (int n=0; n < in.capacity(); n++) - { - out[c][n] = sign * in[s][n]; - } - } - }; }; #endif diff --git a/delay/buffer.hpp b/delay/buffer.hpp index 613e98f..b454173 100644 --- a/delay/buffer.hpp +++ b/delay/buffer.hpp @@ -27,12 +27,10 @@ #define DSP_BUFFER_H #include -#include #include #include #include #include -#include namespace dsp { diff --git a/delay/buffer_multi.hpp b/delay/buffer_multi.hpp index 9eab0cd..7a2ffea 100644 --- a/delay/buffer_multi.hpp +++ b/delay/buffer_multi.hpp @@ -27,23 +27,22 @@ #define DSP_BUFFER_MULTI_H #include "buffer.hpp" +#include namespace dsp { -template +template class BufferMulti { Buffer *m_buffer; - uint m_numChannels; size_t m_capacity; public: - BufferMulti(size_t numChannels, size_t capacity) - : m_buffer(new Buffer[numChannels]) - , m_numChannels(numChannels) + BufferMulti(size_t capacity) + : m_buffer(new Buffer[numCh]) , m_capacity(capacity) { - for (int c=0; c < numChannels; c++) + for (int c=0; c < numCh; c++) { m_buffer[c].resize(capacity); } @@ -56,7 +55,7 @@ class BufferMulti void reset() { - for (int c=0; c < m_numChannels; c++) + for (int c=0; c < numCh; c++) { m_buffer[c].reset(); } @@ -69,7 +68,7 @@ class BufferMulti size_t numChannels() { - return m_numChannels; + return numCh; } Buffer operator[](uint channel) @@ -84,7 +83,7 @@ class BufferMulti BufferMulti & operator ++() { - for (int c=0; c < m_numChannels; c++) + for (int c=0; c < numCh; c++) { ++(m_buffer[c]); } @@ -93,7 +92,7 @@ class BufferMulti BufferMulti & operator +=(int i) { - for (int c=0; c < m_numChannels; c++) + for (int c=0; c < numCh; c++) { m_buffer[c] += i; } @@ -102,7 +101,7 @@ class BufferMulti BufferMulti & operator --() { - for (int c=0; c < m_numChannels; c++) + for (int c=0; c < numCh; c++) { --(m_buffer[c]); } @@ -111,68 +110,37 @@ class BufferMulti BufferMulti & operator -=(int i) { - for (int c=0; c < m_numChannels; c++) + for (int c=0; c < numCh; c++) { m_buffer[c] -= i; } return *this; } - BufferMulti & operator = (const T& value) + BufferMulti & operator =(const T& value) { - for (uint c=0; c < m_numChannels; c++) + for (uint c=0; c < numCh; c++) { m_buffer[c][0] = value; } return *this; } - dsp::Buffer quer(int offset=0) + void quer(T *out, int offset=0) const { - Buffer querBuffer(numChannels()); - for (int c=0; c < m_numChannels; c++) + for (int c=0; c < numCh; c++) { - querBuffer[c] = m_buffer[c][offset]; + out[c] = m_buffer[c][offset]; } - return querBuffer; } - const dsp::Buffer quer(int offset=0) const + void quer(T *out, const int *offsets) const { - Buffer querBuffer(numChannels()); - for (int c=0; c < m_numChannels; c++) + for (int c=0; c < numCh; c++) { - querBuffer[c] = m_buffer[c][offset]; + out[c] = m_buffer[c][offsets[c]]; } - return querBuffer; } - - dsp::Buffer quer(std::initializer_list offsets) - { - Buffer querBuffer(offsets.size()); - - uint ch = 0; - for (int offset: offsets) - { - querBuffer[ch] = m_buffer[ch][offset]; - ch++; - } - return querBuffer; - } - - const dsp::Buffer quer(std::initializer_list offsets) const - { - Buffer querBuffer(offsets.size()); - - uint ch = 0; - for (int offset: offsets) - { - querBuffer[ch] = m_buffer[ch][offset]; - ch++; - } - return querBuffer; - } - Buffer at(uint channel) { diff --git a/delay/tests/test_mix.cpp b/delay/tests/test_mix.cpp deleted file mode 100644 index d99259e..0000000 --- a/delay/tests/test_mix.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include "delay/buffer_multi.hpp" -#include "test_common.hpp" -#include -#include - -#include -#include -#include - - -int test_mix_1() -{ - std::cout << "----------------------------------------------" << std::endl; - std::cout << "Start test_mix_1::shuffle" << std::endl; - std::cout << "----------------------------------------------" << std::endl; - - { - dsp::Buffer r_buf(5); - dsp::Buffer t_buf{105, 106, 107, 108, 109}; - t_buf = {105, 106, 107, 108, 109}; - - dsp::Buffer s_spec = {1, 3, 2, 4, 0}; - Shuffle::outOfPlace(t_buf, r_buf, s_spec); - print(r_buf, 5, "r-buf"); - } - { - dsp::BufferMulti r_buf(5, 5); - dsp::BufferMulti t_buf{5, 5}; - t_buf[0] = {105, 106, 107, 108, 109}; - t_buf[1] = {205, 206, 207, 208, 209}; - t_buf[2] = {305, 306, 307, 308, 309}; - t_buf[3] = {405, 406, 407, 408, 409}; - t_buf[4] = {505, 506, 507, 508, 509}; - print(t_buf[0], 5, "t-buf 0"); - print(t_buf[1], 5, "t-buf 1"); - - dsp::Buffer s_spec = {-1, 0, -3, 2, -4}; - Shuffle::outOfPlace(t_buf, r_buf, s_spec); - print(r_buf[0], 5, "r-buf 0"); - print(r_buf[1], 5, "r-buf 1"); - print(r_buf[2], 5, "r-buf 2"); - print(r_buf[3], 5, "r-buf 3"); - print(r_buf[4], 5, "r-buf 4"); - } - return 0; -} - -int test_mix_2() -{ - dsp::BufferMulti r_buf(5, 20); - - for (int i=0; i < 20; i++) - { - r_buf = 100 +i ; - ++r_buf; - } - - r_buf.reset(); - for (int c=0; c < r_buf.numChannels(); c++) - { - print(r_buf[c], 20, "r-buf"); - std::cout << "----------------------------------------------" << std::endl; - } - - for (int c=0; c < r_buf.numChannels(); c++) - { - dsp::Buffer v(r_buf[c], c); - print(v, 20, "v-buf"); - std::cout << "----------------------------------------------" << std::endl; - } - - return 0; -} - -int test_mix_3() -{ - const int nCh = 5; - dsp::BufferMulti r_buf(nCh, 10); - for (int i=0; i < r_buf.capacity(); i++) - { - r_buf = (double)i/10 ; - ++r_buf; - } -// r_buf.reset(); - - dsp::Buffer qbuf(r_buf.quer({-2, -10, -4, 3, -3})); - dsp::Buffer sbuf(nCh); - dsp::Buffer s_spec = {-1, 0, -3, 2, -4}; - Shuffle::outOfPlace(qbuf, sbuf, s_spec); - - double *q = sbuf.raw(); - - for (int i=0; i < nCh; i++) - { - std::cout << q[i] << " "; - } - std::cout << std::endl; - - Hadamard::inPlace(q); - for (int i=0; i < nCh; i++) - { - std::cout << q[i] << " "; - } - std::cout << std::endl; - - Householder::inPlace(q); - for (int i=0; i < nCh; i++) - { - std::cout << q[i] << " "; - } - std::cout << std::endl; - return 0; -} - -int test_mix() -{ - test_mix_1(); - test_mix_2(); - test_mix_3(); - return 0; -} \ No newline at end of file diff --git a/reverb/reverb.hpp b/reverb/reverb.hpp new file mode 100644 index 0000000..c45e25b --- /dev/null +++ b/reverb/reverb.hpp @@ -0,0 +1,106 @@ +#ifndef REVERB_H +#define REVERB_H + +#include +#include +#include + +template +class Diffusor +{ + dsp::BufferMulti m_dly; + int m_delay_spec[numCh]; + int m_shuffle_spec[numCh]; + + public: + Diffusor(uint maxDelaySize) + : m_dly(maxDelaySize) + { + float delayRagePerWindow = (float)maxDelaySize/(float)numCh; + + // Delay spec + for (int i=0; i < numCh; i++) + { + float base_delay = i*delayRagePerWindow; + float z = (float)rand()/(float)RAND_MAX; + int delay = (int)(base_delay + z*delayRagePerWindow); + + m_delay_spec[i] = -delay; + } + + // Shuffle spec + for (int i=0; i < numCh; i++) + { + m_shuffle_spec[i] = i; + } + + // Shuffle values + for (int i=0; i < 2*numCh; i++) + { + int i1 = rand() & (numCh-1); + int i2 = rand() & (numCh-1); + int temp = m_shuffle_spec[i1]; + m_shuffle_spec[i1] = m_shuffle_spec[i2]; + m_shuffle_spec[i2] = temp; + } + + // Shuffle signs + float p = 0.3; + for (int i=0; i < numCh; i++) + { + float z = (float)rand()/(float)RAND_MAX; + if (z <= p) + { + m_shuffle_spec[i] *= (T)-1; + } + } + + } + + inline T process(T in) + { + m_dly = in; + + T qbuf[numCh]; + m_dly.quer(qbuf, m_delay_spec); + + T sbuf[numCh]; + Shuffle::outOfPlace(qbuf, sbuf, m_shuffle_spec); + + Hadamard::inPlace(sbuf); + Householder::inPlace(sbuf); + ++m_dly; + + return sbuf[0]; + + } + +}; + +template +class Reverb +{ + std::array, 3> m_diffusors; + + public: + Reverb(uint maxDelay) + : m_diffusors({maxDelay, maxDelay, maxDelay}) + { + + } + + void process(float *in, float *out, unsigned numPoints) + { + for (int i=0; i < numPoints; i++) + { + T temp = in[i]; + for (auto diffusor: m_diffusors) + { + temp = diffusor.process(temp); + } + out[i] = temp; + } + } +}; + +#endif diff --git a/delay/tests/.gitignore b/tests/.gitignore similarity index 100% rename from delay/tests/.gitignore rename to tests/.gitignore diff --git a/delay/tests/Makefile b/tests/Makefile similarity index 88% rename from delay/tests/Makefile rename to tests/Makefile index 183f62c..2519246 100644 --- a/delay/tests/Makefile +++ b/tests/Makefile @@ -11,7 +11,7 @@ TARGET ?= $(NAME) CXXFLAGS += -std=c++20 -INCLUDES += -I $(realpath .) -I $(realpath ../../) +INCLUDES += -I $(realpath .) -I $(realpath ../) CXX_SRCS := test_main.cpp test_buffer.cpp test_buffer_multi.cpp test_mix.cpp diff --git a/delay/tests/test_buffer.cpp b/tests/test_buffer.cpp similarity index 99% rename from delay/tests/test_buffer.cpp rename to tests/test_buffer.cpp index 25bc857..ba1f3d1 100644 --- a/delay/tests/test_buffer.cpp +++ b/tests/test_buffer.cpp @@ -3,7 +3,6 @@ #include #include -#include int test_buffer_1() diff --git a/delay/tests/test_buffer_multi.cpp b/tests/test_buffer_multi.cpp similarity index 89% rename from delay/tests/test_buffer_multi.cpp rename to tests/test_buffer_multi.cpp index 9c130ab..31ec0d0 100644 --- a/delay/tests/test_buffer_multi.cpp +++ b/tests/test_buffer_multi.cpp @@ -13,7 +13,7 @@ int test_buffer_multi_1() std::cout << "Start test_buffer_multi_1()" << std::endl; std::cout << "----------------------------------------------" << std::endl; - dsp::BufferMultibuffer(5, 10); + dsp::BufferMultibuffer(10); printf("Buffer capacity = %zu\n", buffer.capacity()); for (int i=0; i < 10; i++) @@ -49,7 +49,7 @@ int test_buffer_multi_2() std::cout << "Start test_buffer_multi_2()" << std::endl; std::cout << "----------------------------------------------" << std::endl; - dsp::BufferMultibuffer(5, 3); + dsp::BufferMultibuffer(3); printf("Buffer capacity = %zu\n", buffer.capacity()); for (int i=0; i < 10; i++) @@ -84,7 +84,7 @@ int test_buffer_multi_3() std::cout << "Start test_buffer_multi_3()" << std::endl; std::cout << "----------------------------------------------" << std::endl; - dsp::BufferMultibuffer(5, 10); + dsp::BufferMultibuffer(10); printf("Buffer capacity = %zu\n", buffer.capacity()); for (int i=0; i < 20; i++) @@ -105,7 +105,7 @@ int test_buffer_multi_4() std::cout << "Start test_buffer_multi_4()" << std::endl; std::cout << "----------------------------------------------" << std::endl; - dsp::BufferMultibuffer(5, 10); + dsp::BufferMultibuffer(10); printf("Buffer capacity = %zu\n", buffer.capacity()); dsp::Buffer *mbv[6]; @@ -126,7 +126,7 @@ int test_buffer_multi_4() buffer.reset(); for (int c=0; c < 5; c++) { - print(*mbv[c], 10, "mbv[c]"); + print(*mbv[c], 10); } return 0; } @@ -137,7 +137,7 @@ int test_buffer_multi_5() std::cout << "Start test_buffer_multi_5()" << std::endl; std::cout << "----------------------------------------------" << std::endl; - dsp::BufferMultibuffer(5, 10); + dsp::BufferMultibuffer(10); printf("Buffer capacity = %zu\n", buffer.capacity()); for (int i=0; i < 10; i++) @@ -149,7 +149,9 @@ int test_buffer_multi_5() buffer.reset(); for (int i=0; i < 10; i++) { - print(buffer.quer(i), buffer.quer().capacity(), "Title here 5"); + int qbuf[5]; + buffer.quer(qbuf, i); + print(qbuf, 5); } return 0; @@ -161,7 +163,7 @@ int test_buffer_multi_6() std::cout << "Start test_buffer_multi_6()" << std::endl; std::cout << "----------------------------------------------" << std::endl; - dsp::BufferMultibuffer(5, 10); + dsp::BufferMultibuffer(10); printf("Buffer capacity = %zu\n", buffer.capacity()); for (int i=0; i < 10; i++) @@ -171,9 +173,12 @@ int test_buffer_multi_6() } buffer.reset(); + int qbuf[5]; + int delays[] = {-2, -1, -4, -5, 0}; for (int i=0; i < 10; i++) { - print(buffer.quer({-2, -1, -4, -5, 0}), buffer.quer().capacity(), "Title here 6"); + buffer.quer(qbuf, delays); + print(qbuf, 5); buffer += 1; } diff --git a/delay/tests/test_common.hpp b/tests/test_common.hpp similarity index 70% rename from delay/tests/test_common.hpp rename to tests/test_common.hpp index 66735b8..f6e4c1d 100644 --- a/delay/tests/test_common.hpp +++ b/tests/test_common.hpp @@ -10,10 +10,18 @@ #define TEST_COMMON_H template -void print(const dsp::Buffer &v, size_t size, std::string name=std::string("")) +void print(const dsp::Buffer &v, size_t size) +{ + for(int i=0; i < size; i++) + { + std::cout << v[i] << " "; + } + std::cout << std::endl; +} + +template +void print(T *v, size_t size) { - std::cout << "----------------------------------------------" << std::endl; - std::cout << "- " << name << ", " << size << std::endl; for(int i=0; i < size; i++) { std::cout << v[i] << " "; @@ -50,8 +58,10 @@ void check(const dsp::Buffer &target, const dsp::Buffer &actual, size_t si if (!success) { std::cout << "Check failed" << std::endl; - print(target, target.capacity(), "Target"); - print(actual, actual.capacity(), "Actual"); + std::cout << "Target" << std::endl; + print(target, target.capacity()); + std::cout << "Actual" << std::endl; + print(actual, actual.capacity()); } assert(success); } diff --git a/delay/tests/test_main.cpp b/tests/test_main.cpp similarity index 100% rename from delay/tests/test_main.cpp rename to tests/test_main.cpp diff --git a/tests/test_mix.cpp b/tests/test_mix.cpp new file mode 100644 index 0000000..3ac0e9d --- /dev/null +++ b/tests/test_mix.cpp @@ -0,0 +1,157 @@ +#include "delay/buffer_multi.hpp" +#include "test_common.hpp" +#include +#include +#include + +#include +#include +#include + + +int test_mix_1() +{ + std::cout << "----------------------------------------------" << std::endl; + std::cout << "Start test_mix_1::shuffle" << std::endl; + std::cout << "----------------------------------------------" << std::endl; + const int numCh = 5; + { + dsp::Buffer r_buf(5); + dsp::Buffer t_buf{105, 106, 107, 108, 109}; + t_buf = {105, 106, 107, 108, 109}; + + int s_spec[numCh] = {1, 3, 2, 4, 0}; + int sbuf[numCh]; + Shuffle::outOfPlace(t_buf.raw(), sbuf, s_spec); + print(r_buf, 5); + } + { + int sbuf[numCh]; + int s_spec[numCh] = {-1, 0, -3, 2, -4}; + + dsp::BufferMulti r_buf(5); + dsp::BufferMulti t_buf{5}; + t_buf[0] = {105, 106, 107, 108, 109}; + t_buf[1] = {205, 206, 207, 208, 209}; + t_buf[2] = {305, 306, 307, 308, 309}; + t_buf[3] = {405, 406, 407, 408, 409}; + t_buf[4] = {505, 506, 507, 508, 509}; + print(t_buf[0], 5); + print(t_buf[1], 5); + + for (int i=0; i < numCh; i++) + { + Shuffle::outOfPlace(t_buf[i].raw(), sbuf, s_spec); + print(r_buf[i], 5); + } + } + return 0; +} + +int test_mix_2() +{ + dsp::BufferMulti r_buf(20); + + for (int i=0; i < 20; i++) + { + r_buf = 100 +i ; + ++r_buf; + } + + r_buf.reset(); + for (int c=0; c < r_buf.numChannels(); c++) + { + print(r_buf[c], 20); + std::cout << "----------------------------------------------" << std::endl; + } + + for (int c=0; c < r_buf.numChannels(); c++) + { + dsp::Buffer v(r_buf[c], c); + print(v, 20); + std::cout << "----------------------------------------------" << std::endl; + } + + return 0; +} + +int test_mix_3() +{ + const int nCh = 5; + dsp::BufferMulti r_buf(10); + for (int i=0; i < r_buf.capacity(); i++) + { + r_buf = (double)i/10 ; + ++r_buf; + } +// r_buf.reset(); + double sbuf[nCh]; + double qbuf[nCh]; + int delays[nCh] = {-2, -10, -4, 3, -3}; + r_buf.quer(qbuf, delays); + int s_spec[nCh] = {-1, 0, -3, 2, -4}; + + Shuffle::outOfPlace(qbuf, sbuf, s_spec); + + for (int i=0; i < nCh; i++) + { + std::cout << sbuf[i] << " "; + } + std::cout << std::endl; + + Hadamard::inPlace(sbuf); + for (int i=0; i < nCh; i++) + { + std::cout << sbuf[i] << " "; + } + std::cout << std::endl; + + Householder::inPlace(sbuf); + for (int i=0; i < nCh; i++) + { + std::cout << sbuf[i] << " "; + } + std::cout << std::endl; + return 0; +} + +void test_diffusor() +{ + std::cout << "----------------------------------------------" << std::endl; + std::cout << "test_diffusor()" << std::endl; + + Diffusor diff(5); + + double data_in[10] = {0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7,0.8, 0.9, 1.0}; + double data_out[10] = {0, 0, 0, 0, 0, 0, 0,0, 0, 0}; + for (int i=0; i < 10; i++) + { + data_out[i] = diff.process(data_in[i]); + } + print(data_out, 10); +} + +void test_reverb() +{ + std::cout << "----------------------------------------------" << std::endl; + std::cout << "test_reverb()" << std::endl; + + Reverb rev(32); + + float data_in[10] = {1, 2, 3, 4, 5, 6, 7,8, 9, 10}; + float data_out[10] = {0, 0, 0, 0, 0, 0, 0,0, 0, 0}; + rev.process(data_in, data_out, 10); + print(data_out, 10); + +} + +int test_mix() +{ + test_mix_1(); + test_mix_2(); + test_mix_3(); + test_reverb(); + test_diffusor(); + return 0; +} +