zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

commit e32f764899ba62caefecc26f42c666c7a8269803
parent ff1cedddaa7a601df63905cd4d3ec5fa13237960
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Sun,  5 Feb 2012 15:09:18 -0500

Samples: removed old sample code

- Sample code removed from codebase
- This should fix minor clicking originating in Effects/Chorus

Diffstat:
Msrc/CMakeLists.txt | 2--
Msrc/Effects/Chorus.cpp | 26+++++++++++++++-----------
Msrc/Effects/Chorus.h | 6++----
Msrc/Effects/Echo.h | 1-
Msrc/Misc/Util.cpp | 18++++++++++++++++++
Msrc/Misc/Util.h | 5+++++
Msrc/Nio/OutMgr.cpp | 11-----------
Dsrc/Samples/CMakeLists.txt | 11-----------
Dsrc/Samples/Sample.cpp | 201-------------------------------------------------------------------------------
Dsrc/Samples/Sample.h | 78------------------------------------------------------------------------------
Dsrc/Tests/SampleTest.h | 101-------------------------------------------------------------------------------
11 files changed, 40 insertions(+), 420 deletions(-)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt @@ -220,7 +220,6 @@ set(NONGUI_LIBRARIES zynaddsubfx_effect zynaddsubfx_params zynaddsubfx_dsp - zynaddsubfx_samples zynaddsubfx_nio ) @@ -229,7 +228,6 @@ add_subdirectory(Synth) add_subdirectory(Effects) add_subdirectory(Params) add_subdirectory(DSP) -add_subdirectory(Samples) if(CompileTests) add_subdirectory(Tests) endif(CompileTests) diff --git a/src/Effects/Chorus.cpp b/src/Effects/Chorus.cpp @@ -29,7 +29,7 @@ using namespace std; Chorus::Chorus(bool insertion_, float *const efxoutl_, float *efxoutr_) :Effect(insertion_, efxoutl_, efxoutr_, NULL, 0), maxdelay((int)(MAX_CHORUS_DELAY / 1000.0f * synth->samplerate_f)), - delaySample(maxdelay) + delaySample(new float[maxdelay], new float[maxdelay]) { dlk = 0; drk = 0; @@ -41,7 +41,11 @@ Chorus::Chorus(bool insertion_, float *const efxoutl_, float *efxoutr_) cleanup(); } -Chorus::~Chorus() {} +Chorus::~Chorus() +{ + delete [] delaySample.l; + delete [] delaySample.r; +} //get the delay value in samples; xlfo is the current lfo value float Chorus::getdelay(float xlfo) @@ -81,7 +85,7 @@ void Chorus::out(const Stereo<float *> &input) //Left channel //compute the delay in samples using linear interpolation between the lfo delays - mdel = (dl1 * (synth->buffersize - i) + dl2 * i) / synth->buffersize; + float mdel = (dl1 * (synth->buffersize - i) + dl2 * i) / synth->buffersize_f; if(++dlk >= maxdelay) dlk = 0; float tmp = dlk - mdel + maxdelay * 2.0f; //where should I get the sample from @@ -89,10 +93,10 @@ void Chorus::out(const Stereo<float *> &input) F2I(tmp, dlhi); dlhi %= maxdelay; - dlhi2 = (dlhi - 1 + maxdelay) % maxdelay; - dllo = 1.0f - fmod(tmp, one); - efxoutl[i] = delaySample.l[dlhi2] * dllo + delaySample.l[dlhi] - * (1.0f - dllo); + float dlhi2 = (dlhi - 1 + maxdelay) % maxdelay; + float dllo = 1.0f - fmod(tmp, one); + efxoutl[i] = cinterpolate(delaySample.l, maxdelay, dlhi2) * dllo + + cinterpolate(delaySample.l, maxdelay, dlhi) * (1.0f - dllo); delaySample.l[dlk] = inL + efxoutl[i] * fb; //Right channel @@ -108,8 +112,8 @@ void Chorus::out(const Stereo<float *> &input) dlhi2 = (dlhi - 1 + maxdelay) % maxdelay; dllo = 1.0f - fmodf(tmp, one); - efxoutr[i] = delaySample.r[dlhi2] * dllo + delaySample.r[dlhi] - * (1.0f - dllo); + efxoutr[i] = cinterpolate(delaySample.r, maxdelay, dlhi2) * dllo + + cinterpolate(delaySample.r, maxdelay, dlhi) * (1.0f - dllo); delaySample.r[dlk] = inR + efxoutr[i] * fb; } @@ -128,8 +132,8 @@ void Chorus::out(const Stereo<float *> &input) //Cleanup the effect void Chorus::cleanup(void) { - delaySample.l.clear(); - delaySample.r.clear(); + memset(delaySample.l, 0, maxdelay * sizeof(float)); + memset(delaySample.r, 0, maxdelay * sizeof(float)); } //Parameter control diff --git a/src/Effects/Chorus.h b/src/Effects/Chorus.h @@ -24,7 +24,6 @@ #define CHORUS_H #include "Effect.h" #include "EffectLFO.h" -#include "../Samples/Sample.h" #include "../Misc/Stereo.h" #define MAX_CHORUS_DELAY 250.0f //ms @@ -99,10 +98,9 @@ class Chorus:public Effect float depth, delay, fb; float dl1, dl2, dr1, dr2, lfol, lfor; int maxdelay; - Stereo<Sample> delaySample; - int dlk, drk, dlhi, dlhi2; + Stereo<float*> delaySample; + int dlk, drk, dlhi; float getdelay(float xlfo); - float dllo, mdel; }; #endif diff --git a/src/Effects/Echo.h b/src/Effects/Echo.h @@ -25,7 +25,6 @@ #include "Effect.h" #include "../Misc/Stereo.h" -#include "../Samples/Sample.h" /**Echo Effect*/ class Echo:public Effect diff --git a/src/Misc/Util.cpp b/src/Misc/Util.cpp @@ -22,6 +22,7 @@ #include "Util.h" #include <vector> +#include <cassert> #include <math.h> #include <stdio.h> #include <err.h> @@ -202,3 +203,20 @@ float SYNTH_T::numRandom() const { return RND; } + +float interpolate(const float *data, size_t len, float pos) +{ + assert(len > (size_t)pos+1); + const int l_pos = (int)pos, + r_pos = l_pos + 1; + const float leftness = pos - l_pos; + return data[l_pos] * leftness + data[r_pos] * (1.0f - leftness); +} + +float cinterpolate(const float *data, size_t len, float pos) +{ + const int l_pos = ((int)pos) % len, + r_pos = (l_pos + 1) % len; + const float leftness = pos - l_pos; + return data[l_pos] * leftness + data[r_pos] * (1.0f - leftness); +} diff --git a/src/Misc/Util.h b/src/Misc/Util.h @@ -114,5 +114,10 @@ inline void sprng(prng_t p) # define INT32_MAX (2147483647) #define RND (prng() / (INT32_MAX * 1.0f)) +//Linear Interpolation +float interpolate(const float *data, size_t len, float pos); + +//Linear circular interpolation +float cinterpolate(const float *data, size_t len, float pos); #endif diff --git a/src/Nio/OutMgr.cpp b/src/Nio/OutMgr.cpp @@ -9,7 +9,6 @@ #include "WavEngine.h" #include "../Misc/Master.h" #include "../Misc/Util.h" //for set_realtime() -#include "../Samples/Sample.h" //for resampling using namespace std; @@ -116,16 +115,6 @@ string OutMgr::getSink() const return "ERROR"; } -//performs linear interpolation -static float interpolate(const float *data, size_t len, float pos) -{ - assert(len > (size_t)pos+1); - const int l_pos = (int)pos, - r_pos = l_pos + 1; - const float leftness = pos - l_pos; - return data[l_pos] * leftness + data[r_pos] * (1.0f - leftness); -} - //perform a cheap linear interpolation for resampling //This will result in some distortion at frame boundries //returns number of samples produced diff --git a/src/Samples/CMakeLists.txt b/src/Samples/CMakeLists.txt @@ -1,11 +0,0 @@ -set(zynaddsubfx_samples_SRCS - Sample.cpp -) - -add_library(zynaddsubfx_samples STATIC - ${zynaddsubfx_samples_SRCS} - ) - -target_link_libraries(zynaddsubfx_samples - zynaddsubfx_samples - ) diff --git a/src/Samples/Sample.cpp b/src/Samples/Sample.cpp @@ -1,201 +0,0 @@ -/* - ZynAddSubFX - a software synthesizer - - Sample.cpp - Object for storing information on samples - Copyright (C) 2009-2009 Mark McCurry - Author: Mark McCurry - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include <cmath> -#include <cstring> //for memcpy/memset - -#include <iostream> -#include "Sample.h" - -using namespace std; - -#warning TODO Think about renaming Sample to Frame -/**\TODO start using pointer math here as these will be Frequency called - * functions throughout the code*/ -Sample::Sample() - :bufferSize(1), buffer(new float[1]) -{ - buffer[0] = 0.0f; -} - -Sample::Sample(const Sample &smp) - :bufferSize(smp.bufferSize) -{ - buffer = new float[bufferSize]; - memcpy(buffer, smp.buffer, bufferSize * sizeof(float)); -} - -Sample::Sample(int length, float fill) - :bufferSize(length) -{ - if(length < 1) - bufferSize = 1; - buffer = new float[bufferSize]; - memset(buffer, fill, bufferSize * sizeof(float)); -} - -Sample::Sample(int length, const float *input) - :bufferSize(length) -{ - if(length > 0) { - buffer = new float[length]; - memcpy(buffer, input, bufferSize * sizeof(float)); - } - else { - buffer = new float[1]; - bufferSize = 1; - *buffer = 0; - } -} - -Sample::~Sample() -{ - delete[] buffer; -} - -void Sample::clear() -{ - for(int i = 0; i < bufferSize; ++i) - *(i + buffer) = 0; -} - -void Sample::operator=(const Sample &smp) -{ - if(bufferSize != smp.bufferSize) { - delete[] buffer; - buffer = new float[smp.bufferSize]; - bufferSize = smp.bufferSize; - } - memcpy(buffer, smp.buffer, bufferSize * sizeof(float)); -} - -bool Sample::operator==(const Sample &smp) const -{ - if(this->bufferSize != smp.bufferSize) - return false; - for(int i = 0; i < bufferSize; ++i) - if(this->buffer[i] != smp.buffer[i]) - return false; - return true; -} - -/** - * Linear point estimation - * @param ya Y of point a - * @param yb Y of point b - * @param xt X of test point - * @param xa X of point a - * @param xb X of point b - * @return estimated Y of test point - */ -float linearEstimate(float ya, - float yb, - float xt, - float xa = 0.0f, - float xb = 1.0f) -{ -#warning TODO this could be done with a good bit less computation - //Lets make this simple by normalizing the x axis - - //Normalize point a - xb -= xa; - xt -= xa; - xa -= xa; - - //Normalize point b - xt /= xb; - xb /= xb; - - //Now xa=0 xb=1 0<=xt<=1 - //simpily use y=mx+b - return (yb - ya) * xt + ya; -} - - -void Sample::resample(const unsigned int rate, const unsigned int nrate) -{ - if(rate == nrate) - return; //no resampling here - else { //resampling occurs here - float ratio = (nrate * 1.0f) / (rate * 1.0f); - - int nBufferSize = (int)bufferSize * ratio; - float *nBuffer = new float[nBufferSize]; - - //addition is done to avoid 0 edge case - for(int i = 0; i < nBufferSize; ++i) - nBuffer[i] = linearEstimate(buffer[(int)floor(i / ratio)], - buffer[(int)ceil((i + 1) / ratio)], - i, - floor(i / ratio), - ceil((i + 1) / ratio)); - - //put the new data in - delete[] buffer; - buffer = nBuffer; - bufferSize = nBufferSize; - } -} - -Sample &Sample::append(const Sample &smp) -{ - int nbufferSize = bufferSize + smp.bufferSize; - float *nbuffer = new float[nbufferSize]; - - memcpy(nbuffer, buffer, bufferSize * sizeof(float)); - memcpy(nbuffer + bufferSize, smp.buffer, smp.bufferSize * sizeof(float)); - delete[] buffer; - - buffer = nbuffer; - bufferSize = nbufferSize; - return *this; -} - -Sample Sample::subSample(int a, int b) const -{ - return Sample(b - a, buffer + a); -} - -float Sample::max() const -{ - float max = -1500; //a good low considering that samples should store values -1.0f to 1.0f - for(int i = 0; i < bufferSize; ++i) - if(buffer[i] > max) - max = buffer[i]; - return max; -} - -float Sample::min() const -{ - float min = 1500; //a good high considering that samples should store values -1.0f to 1.0f - for(int i = 0; i < bufferSize; ++i) - if(buffer[i] < min) - min = buffer[i]; - return min; -} - -float Sample::absMax() const -{ - float max = 0; - for(int i = 0; i < bufferSize; ++i) - if(fabs(buffer[i]) > max) - max = fabs(buffer[i]); - return max; -} diff --git a/src/Samples/Sample.h b/src/Samples/Sample.h @@ -1,78 +0,0 @@ -/* - ZynAddSubFX - a software synthesizer - - Sample.h - Object for storing information on samples - Copyright (C) 2009-2009 Mark McCurry - Author: Mark McCurry - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef SAMPLE_H -#define SAMPLE_H -#include "../globals.h" -/** - * Audio Samples Representation - */ -class Sample -{ - public: - Sample(); - Sample(const Sample &smp); - Sample(int length, float fill = 0); - Sample(int length, const float *fill); - ~Sample(); - /**Fills the buffer with zeros*/ - void clear(); - /**States the size of the buffer - * @return the size of the buffer*/ - int size() const { - return bufferSize; - } - /**Provides the indexing operator for non const Samples*/ - float &operator[](int index) { - return *(buffer + index % bufferSize); - } - /**Provides the indexing operator for const Samples*/ - const float &operator[](int index) const { - return *(buffer + index % bufferSize); - } - /**Provides the assignment operator*/ - void operator=(const Sample &smp); - /**Provides the == operator*/ - bool operator==(const Sample &smp) const; - - /**Provides direct access to the buffer to allow for transition - * - * This method is like c_str() from the string class and should be used - * sparingly*/ - const float *c_buf() const {return buffer;} - - /**Change the sampling rate of the Sample*/ - void resample(const unsigned int rate, const unsigned int nrate); - - /**Appends another Sample to this Sample - * @return this*/ - Sample &append(const Sample &smp); - - /**Gets a subsample from a to b*/ - Sample subSample(int a, int b) const; - - float max() const; - float min() const; - float absMax() const; - private: - int bufferSize; - float *buffer; -}; -#endif diff --git a/src/Tests/SampleTest.h b/src/Tests/SampleTest.h @@ -1,101 +0,0 @@ -/* - ZynAddSubFX - a software synthesizer - - SampleTest.h - CxxTest for Samples - Copyright (C) 2009-2009 Mark McCurry - Author: Mark McCurry - - This program is free software; you can redistribute it and/or modify - it under the terms of version 2 of the GNU General Public License - as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License (version 2 or later) for more details. - - You should have received a copy of the GNU General Public License (version 2) - along with this program; if not, write to the Free Software Foundation, - Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -*/ -#include <cxxtest/TestSuite.h> -#include "../Samples/Sample.h" - -class SampleTest:public CxxTest::TestSuite -{ - public: - void testInit() { - Sample smp(10); - TS_ASSERT_EQUALS(smp.size(), 10); - for(int i = 0; i < 20; ++i) - TS_ASSERT_EQUALS(smp[i], 0.0f); - Sample nsmp(5, 15.0f); - TS_ASSERT_EQUALS(nsmp.size(), 5); - TS_ASSERT_EQUALS(nsmp[4], 15.0f); - } - - void testAssign() { - Sample smp(3); - smp[0] = 0; - smp[1] = 1; - smp[2] = 2; - Sample nsmp(40); - nsmp = smp; - TS_ASSERT_EQUALS(smp.size(), nsmp.size()); - for(int i = 0; i < 29; ++i) - TS_ASSERT_EQUALS(smp[i], nsmp[i]); - } - void testBounds() { - Sample smp(0); - TS_ASSERT(smp.size() != 0); - } - - void testAllocDealloc() { - float *fl = new float[50]; - for(int i = 0; i < 50; ++i) - *(fl + i) = i; - Sample smp(2); - smp = Sample(50, fl); - delete [] fl; - for(int i = 0; i < 50; ++i) - TS_ASSERT_DELTA(smp[i], i, 0.001f); - smp = Sample(3); - } - - void testClear() { - Sample smp(50); - for(int i = 0; i < 50; ++i) - smp[i] = 10; - smp.clear(); - for(int i = 0; i < 50; ++i) - TS_ASSERT_EQUALS(smp[i], 0); - } - - void testAppend() { - Sample smp1(54, 2); - Sample smp2(20, 17); - smp1.append(smp2); - TS_ASSERT_EQUALS(smp1.size(), 74); - for(int i = 0; i < 74; ++i) - TS_ASSERT_DELTA(smp1[i], (i < 54 ? 2 : 17), 0.001f); - } - - void testResample() { - Sample orig(32, 2); - Sample cpy(orig); - - //test for no resampleing - orig.resample(128, 128); - TS_ASSERT_EQUALS(cpy, orig); - - //test for no bad distortions - orig.resample(128, 256); - orig.resample(256, 128); - TS_ASSERT_EQUALS(cpy, orig); - - //test for downsample - orig.resample(256, 128); - TS_ASSERT_EQUALS(orig.size(), cpy.size() / 2); - } -};