void testInterpolatingDelayZero() { Jamoma::SampleVector input = {0,1,0,0, 0,0,0,0, 2,0,0,0, 0,0,3,0 }; Jamoma::SampleVector output; Jamoma::DelayWithLinearInterpolation delay; delay.size = 0.; for (auto& in : input) { Jamoma::Sample out = delay(in); output.push_back(out); } Jamoma::Sample temp = 0.0; Jamoma::Sample tempExpected = 0.0; int badSampleCount = 0; for (int i=0; i < input.size(); i++) { temp = output[i]; tempExpected = input[i]; if (! mTest->compare(temp, tempExpected, true, 8) ) { badSampleCount++; std::cout << "sample " << i << " had a difference of " << std::fabs(temp - tempExpected) << std::endl; } } mTest->TEST_ASSERT("delay.size of 0 produced correct output", badSampleCount == 0); }
void testImpulseResponse() { Jamoma::Dcblock my_dcblock; Jamoma::UnitImpulse impulse; impulse.channelCount = 1; impulse.frameCount = 64; auto out_samples = my_dcblock( impulse() ); Jamoma::SampleVector expectedIR = generateReferenceImpulseResponse(); int badSampleCount = 0; Jamoma::Sample temp = 0.0; Jamoma::Sample tempExpected = 0.0; for (int i=0; i < expectedIR.size(); i++) { temp = out_samples[0][0][i]; tempExpected = expectedIR[i]; if ( ! mTest->compare(temp, tempExpected ) ) { badSampleCount++; mTest->log("sample %i had a difference of %.10f", i, std::fabs(temp - tempExpected)); } } mTest->TEST_ASSERT("Bad Sample Count", badSampleCount == 0); if (badSampleCount) mTest->log("the impulse response of my_dcblock has %i bad sample(s)", badSampleCount); }
void testSettingInterpolatingDelaySize() { Jamoma::DelayWithLinearInterpolation delay; delay.size = 3.2; mTest->TEST_ASSERT("mIntergralDelay value is correct", delay.integralDelay() == 3); mTest->TEST_ASSERT("mFractionalDelay value is correct", mTest->compare(delay.fractionalDelay(), 0.2, true, 6) ); }
/* Vector Size = 4 Delay Size = 3 Thus Buffer Size = 7 Write: [1][0][0][0][ ][ ][ ] Read: [x][ ][ ][ ][x][x][x] Write: [0][ ][ ][ ][0][0][0] Read: [ ][x][x][x][x][ ][ ] Write: [ ][0][0][0][0][ ][ ] Read: [x][x][ ][ ][ ][x][x] */ void testDelayLessThanOneVectorSize() { Jamoma::SampleBundle zero(1, 4); Jamoma::UnitImpulse impulse; impulse.channelCount = 1; impulse.frameCount = 4; Jamoma::Delay my_delay; my_delay.sampleRate = 96000; my_delay.size = 3; Jamoma::SampleBundle out1 = my_delay( impulse() ); Jamoma::SampleBundle out2 = my_delay( zero ); Jamoma::SampleBundle out3 = my_delay( zero ); mTest->TEST_ASSERT("First Vector Output Correct", out1[0][0] == 0.0 && out1[0][1] == 0.0 && out1[0][2] == 0.0 && out1[0][3] == 1.0); mTest->TEST_ASSERT("Second Vector Output Correct", out2[0][0] == 0.0 && out2[0][1] == 0.0 && out2[0][2] == 0.0 && out2[0][3] == 0.0); mTest->TEST_ASSERT("Third Vector Output Correct", out3[0][0] == 0.0 && out3[0][1] == 0.0 && out3[0][2] == 0.0 && out3[0][3] == 0.0); }
void testDelaySingleSample() { Jamoma::SampleVector input = {0,1,0,0, 0,0,0,0, 2,0,0,0, 0,0,3,0 }; Jamoma::SampleVector output; Jamoma::Delay delay; delay.size = 3; for (auto& in : input) { Jamoma::Sample out = delay(in); output.push_back(out); } mTest->TEST_ASSERT("First Vector Output Correct", output[0] == 0 && output[1] == 0 && output[2] == 0 && output[3] == 0 && output[4] == 1 && output[5] == 0 && output[6] == 0 && output[7] == 0 && output[8] == 0 && output[9] == 0 && output[10] == 0 && output[11] == 2 && output[12] == 0 && output[13] == 0 && output[14] == 0 && output[15] == 0 ); }
int main(int argc, const char * argv[]) { Jamoma::UnitTest<DelayTest> aUnitTestInstance; return aUnitTestInstance.failureCount(); }
void testInterpolatingDelayAtVectorEdge() { Jamoma::SampleBundle zero(2, 64); Jamoma::UnitImpulse impulse; impulse.channelCount = 2; impulse.frameCount = 64; Jamoma::DelayWithLinearInterpolation my_delay; my_delay.sampleRate = 44100; my_delay.size = 63.70000000000000284; Jamoma::SampleBundle out_samples1 = my_delay( impulse() ); Jamoma::SampleBundle out_samples2 = my_delay( zero ); // NW: first test to see if the expected values are in the right place Jamoma::Sample temp = 0.0; Jamoma::Sample tempExpected = 0.0; int badSampleCount = 0; temp = out_samples1[0][63]; tempExpected = 0.29999999999999716; if (! mTest->compare(temp, tempExpected, true, 8)) { badSampleCount++; std::cout << "expected value " << tempExpected << " but instead it was " << temp << std::endl; } temp = out_samples2[0][0]; tempExpected = 0.70000000000000284; if (! mTest->compare(temp, tempExpected, true, 8)) { badSampleCount++; std::cout << "expected value " << tempExpected << " but instead it was " << temp << std::endl; } temp = out_samples1[1][63]; tempExpected = 0.29999999999999716; if (! mTest->compare(temp, tempExpected, true, 8)) { badSampleCount++; std::cout << "expected value " << tempExpected << " but instead it was " << temp << std::endl; } temp = out_samples2[1][0]; tempExpected = 0.70000000000000284; if (! mTest->compare(temp, tempExpected, true, 8)) { badSampleCount++; std::cout << "expected value " << tempExpected << " but instead it was " << temp << std::endl; } mTest->TEST_ASSERT("InterpolatingDelayAtVectorEdge produced non-zero samples in the wrong place", badSampleCount == 0); // NW: then test to see how many non-zero samples were produced // if this count is not right, it may be that the delay size is set incorrectly int nonZeroSampleCount = 0; // first 64 samples should should produce 1 non-zero values per channel, 2 total for (auto& channel : out_samples1) { for (auto& sample : channel) { if (sample != 0.0) { nonZeroSampleCount++; if (badSampleCount) std::cout << "an out_samples1 item is " << sample << std::endl; } } } // this group of samples should produce 1 non-zero values per channel, 2 total for (auto& channel : out_samples2) { for (auto& sample : channel) { if (sample != 0.0) { nonZeroSampleCount++; if (badSampleCount) std::cout << "an out_samples2 item is " << sample << std::endl; } } } if (nonZeroSampleCount != 4) { std::cout << "the output has " << nonZeroSampleCount << " non-zero samples" << std::endl; } mTest->TEST_ASSERT("InterpolatingDelayAtVectorEdge produced correct number of non-zero samples", nonZeroSampleCount == 4); }
void testDelayGreaterThanOneVectorSize() { Jamoma::SampleBundle zero(2, 64); Jamoma::UnitImpulse impulse; impulse.channelCount = 2; impulse.frameCount = 64; Jamoma::Delay my_delay; my_delay.sampleRate = 44100; my_delay.size = 100; Jamoma::SampleBundle out_samples1 = my_delay( impulse() ); Jamoma::SampleBundle out_samples2 = my_delay( zero ); Jamoma::SampleBundle out_samples3 = my_delay( zero ); int badSampleCount = 0; // first 64 samples should all be zero for (auto& channel : out_samples1) { for (auto& sample : channel) { if (sample != 0.0) { badSampleCount++; std::cout << "bad sample " << " is " << sample << std::endl; } } } // 100 samples later should be 1.0 // note: this is not the 100th sample, but 100 samples after sample 0 -- a delay of 0 is sample 0 for (auto& channel : out_samples2) { int i = 0; for (auto& sample : channel) { if (i == 100-64) { if (sample != 1.0) { badSampleCount++; std::cout << "sample " << i << " is " << sample << std::endl; } } else if (sample != 0.0) { badSampleCount++; std::cout << "sample " << i << " is " << sample << std::endl; } ++i; } } // last 64 samples should all be zero for (auto& channel : out_samples3) { for (auto& sample : channel) { if (sample != 0.0) { badSampleCount++; std::cout << "bad sample " << " is " << sample << std::endl; } } } if (badSampleCount) { std::cout << "the output has " << badSampleCount << " bad samples" << std::endl; } mTest->TEST_ASSERT("DelayGreaterThanOneVectorSize produced correct output", badSampleCount == 0); }
int main(int argc, const char * argv[]) { Jamoma::UnitTest<Jamoma::SampleBundleTest> aUnitTestInstance; return aUnitTestInstance.failureCount(); }
void testImpulseResponse() { Jamoma::LowpassOnePole my_lowpass; my_lowpass.coefficient = 0.5; Jamoma::UnitImpulse impulse; impulse.channelCount = 1; impulse.frameCount = 64; auto out_samples = my_lowpass( impulse() ); // The following impulse was based on the code from jamoma // implemented in Processing by NW Jamoma::SampleVector expectedIR = { 0.5, 0.25, 0.125, 0.0625, 0.03125, 0.015625, 0.0078125, 0.00390625, 0.001953125, 9.765625E-4, 4.8828125E-4, 2.44140625E-4, 1.220703125E-4, 6.103515625E-5, 3.0517578125E-5, 1.52587890625E-5, 7.62939453125E-6, 3.814697265625E-6, 1.9073486328125E-6, 9.5367431640625E-7, 4.76837158203125E-7, 2.384185791015625E-7, 1.1920928955078125E-7, 5.9604644775390625E-8, 2.9802322387695312E-8, 1.4901161193847656E-8, 7.450580596923828E-9, 3.725290298461914E-9, 1.862645149230957E-9, 9.313225746154785E-10, 4.6566128730773926E-10, 2.3283064365386963E-10, 1.1641532182693481E-10, 5.820766091346741E-11, 2.9103830456733704E-11, 1.4551915228366852E-11, 7.275957614183426E-12, 3.637978807091713E-12, 1.8189894035458565E-12, 9.094947017729282E-13, 4.547473508864641E-13, 2.2737367544323206E-13, 1.1368683772161603E-13, 5.6843418860808015E-14, 2.8421709430404007E-14, 1.4210854715202004E-14, 7.105427357601002E-15, 3.552713678800501E-15, 1.7763568394002505E-15, 8.881784197001252E-16, 4.440892098500626E-16, 2.220446049250313E-16, 1.1102230246251565E-16, 5.551115123125783E-17, 2.7755575615628914E-17, 1.3877787807814457E-17, 6.938893903907228E-18, 3.469446951953614E-18, 1.734723475976807E-18, 8.673617379884035E-19, 4.3368086899420177E-19, 2.1684043449710089E-19, 1.0842021724855044E-19, 5.421010862427522E-20 }; int badSampleCount = 0; Jamoma::Sample temp = 0.0; Jamoma::Sample tempExpected = 0.0; for (int i = 0; i < expectedIR.size(); i++) { temp = out_samples[0][0][i]; tempExpected = expectedIR[i]; if (! mTest->compare(temp, tempExpected) ) { badSampleCount++; std::cout << "sample " << i << " had a difference of " << std::fabs(temp - tempExpected) << std::endl; } } std::cout << "the impulse response of my_lowpass (1 pole) has " << badSampleCount << " bad samples" << std::endl; mTest->TEST_ASSERT("Bad Sample Count", badSampleCount == 0); // testing range limitations my_lowpass.coefficient = 0.7; mTest->TEST_ASSERT("coefficient setting", my_lowpass.coefficient == 0.7); my_lowpass.coefficient = -1.0; mTest->TEST_ASSERT("low coefficient limiting", my_lowpass.coefficient == 0.0); my_lowpass.coefficient = 1.2; mTest->TEST_ASSERT("high coefficient limiting", my_lowpass.coefficient == 1.0); // Testing coefficient setting via frequency // The following Max 7 patcher can be convenient as an interactive reference for the // relationship between frequency response and coefficient /* <pre><code> ----------begin_max5_patcher---------- 2115.3oc6asrjiZCEcc2eEJplEcRY6fdAlYURVjJUMS9BRkpKYiraxfAG.mz 8L0ju8nm.1FroaaHdQVLF8BoiNb0U2G87k6uCtH6YQAD7dvuAt6tub+c2oaR 0vc152A2vedYBuPOL3FQQAes.NwzWo34Rc6XOOWawQ5VxV7GSCpZrn7kDgtc WKY6JSDkkurUXVeHD761tR2sINU1odIw1F2xKW9Tb55GyEKKMuBwmMyaB.6o 9kfzkIy7plms4hBQZIuLNKcuWiV+ZteZt3FnoWcjpwud+8pelzSNJU72xM+Q Tj34s4.zLvTfrzCSwx076.jYHJhIK7tUHv2CnTjm2rusEpze9kSkntoRJSSD gdFR7Xt7xokSH5H2ysskoCpziOogzCcdekd7I9CpzypjL4jzFcPdMzwD.bAO c8aVR.gYlGdGQLqxx2v0i1uZZx4aDkh7GEo7EFr4cZZjxLLNB0CdDeEE2Prt D2PCp3FK3MItwlqE2PgCj3VmzTmmJGVc5Lq.2qkln3A8T41jrx+oE1fE5Zju KJNak5bPQ7m06ejGlNwMW4qiSs2zp2TyqgKqITuBTH0vcgZ4MeGSx1mO1lEm ZlIFxMW4REFhD9BQhd+8q70owk6hDfGh9op6jhx1vkvnZT+bt3O2IRW9B3ge 4yUi5.Fuw5JIx81.E6VT0lxJjpO.x9Vlkjka5vaFch6m.l7.Q81QI19T7xOk JLerTZTbcn2lOVKollk5j0k8lDmJZzopJOutaIbWH0o00auJNQpxS2AuLKZQ cOFNR9h7b82DuFHx1mHUKDgwdrV5sAlxVez7Jkl9jH2xXtY.XtGUqqvUXtqP fqfuq.yUf5JPbEvtBHWA2L6lX275lV2r5lT2b5lRbCj4.lCWNX4PkCTNL4fj CQN.YwiENVzXAiEKVnXQhEHVbXggEEVPXwfEBVDz3ZP45aW9ZiklaWayR6NO OwdJjzPaF5P8R0eQ0GmbeP0CSZVDrBuFyqqnQH9CvFeuk89AXi4TeLtV3aJh faHgY50J94cTGceZvz+dxd5keJRq5cJVaU8Ti4QSMptmZXjoAlgL2LjPyPPd ysuucdT37n8QSpwrcUTgcQgxmvp0FJeBqf.T9DVgDn7IrBPP80XNbAkOgUvC JeBqPIT9DVCVnp.rFzJ.XvCwAHBt4Gir7Xol+Ge9P1119K11MMatOpSMfAJo G7b0ujv+WEXkX3oOO8exIiSJF+1EO.+9UzDOZGV3wHCpEdzflV30au1olypi tgv3tXI7vxR3SyRCnilLuwzQSlwLU1E5l4k6v3xrMajxcGI.rpx.23TvSetE BidhXyzW1v52igMr1ffQc9A26JJgKWKTa6J+AU.2YJmwsXBsu5ABI5wyFY0. dyBaiiXCJGgoM4Hb3LV+3H7bbMoNpjDqMRZXiiGx3n6qmjPFIO+QmjZ8z1vd oqyqlNIoAKr2emzLq1t+j9ZtkQdWk5pfW84Gjc6Z7EiL.2h10sFRyjAayRDf jr+dqbv.qoxGSDjvK+1CpKv8l8q01g46caZZYUfolOyavuUAAdWax4jfgUio 8PsQbmv56sJAFqKwCV.D6hldGBzVlyHCrNyfyPSCn4kD7nXdoSR.2HlL2l1W JDQK3K+DXYlX0p3kwxAAdXwin1RCHw6xUVfCZxLsYqYWGRrWhPl2iCIdWuqP 9lofVuBAGNdWg32URlGtqPVykNbrmPA+Qu1DJPjqfPgMRkcKTb4ed6Tkv3nQ vY7yMiFgtRpDoxyqqediNA+DtWhivAmKwQTT64MhuYahNuQckxnB0HDEmNWQ CQdgXcFTzkw4KS5Nrnlvw8VBK59cz+nhROcHQOHBjsEUTZi61sGtajAZiZMS JIX8JuDl3cCTlqXeOHxjUh57UXVGn5VJ65Ck14ehHv5MC2U7WIrKK0Dx2W8q Nl45hX0OHcQjd+xrWhM0Tdpt8olwnP1IChqF5.ndbP2KqphTUsYpvTT0QU6X cEroBQWg.fibHg6RyCE+ehlGeS3+5slmNSY81m3EBvC47nXdZQm4rNUonOQ5 MTDnJ5d2RZiFnTz7V0EgtTUQVSEQUmBIUrj9Ln+DW1szI25nbacFsQUGpf1o UVlBsSrrrOzN0xxpj2gLuK5jIMcnxLjKcoFUnSsoI0jyTSdTOVabmYBUq4wl 3QiZHaJLo5J1LX5qqXye4b.rZ0UYyDre1TGcUQcXyuQrMRTxiSZyhwpvHnBr QpzHMcW+XdLO4UZL4Q+6sZXIkpeD1VpLZD7ERGAew+5QdQwKKmsU4SYwxmDa 3uG3nyh30o.45Jx4kY4uGDIRyjaRSkenT9ccsTREf.31Hc+qBoqPmzwRd9Kc P0jyS017hgCeabcS2zzuo9j6A+kPqWdU66+AnHaW9R2dw8mlKnF.RRtTwnxs XyAQ1aPOEGIo9ltSDEWn7vHpamq5KdB75AdXdiFdX8AOGPhCId7o2V7yAhFs iG73AGzMF8biINqt5473Ib7NdguwNtStsvC0+l53kJkw2RvgdaAmaKcgz9n6 gLd3AG1C7PGuyVj9nKTY1H.ON3g1W7fFG7zGcyGPhCp7SefC8lBN3w6lTbut oHXbszfdtOW9mAOahipibl5uoHlJ7Kz.cjBBo5+TPz0pWnq6N.cN8U3W2N.E FpBVDMP67muD5LasytCL95w2t8ujd4ZQgF7R2p+CSP7BlnqFmZppc6GlK9qX 230nBxyktlVJ8KcWtwc2ms+2UDtIKRjmtK15moj1t25V7A9WV4.cIeqwYYIA shuKobeVsoy1RJ6iRm0AeLd8SprYZ1aSreTxERR5.GvgajSXriHzAo4q2+u. 80vVA -----------end_max5_patcher----------- </code></pre> */ my_lowpass.sampleRate = 96000; my_lowpass.frequency = 1000.0; // hz mTest->TEST_ASSERT("coefficient for 1K cutoff @ 96K fs", mTest->compare((double)my_lowpass.coefficient, 0.06335217076965427)); my_lowpass.frequency = 4000.0; // hz mTest->TEST_ASSERT("coefficient for 1K cutoff @ 96K fs", mTest->compare((double)my_lowpass.coefficient, 0.23032864479520065)); my_lowpass.sampleRate = 44100; my_lowpass.frequency = 1000.0; // hz mTest->TEST_ASSERT("coefficient for 1K cutoff @ 44.1K fs", mTest->compare((double)my_lowpass.coefficient, 0.132787865213287)); my_lowpass.frequency = 4000.0; // hz mTest->TEST_ASSERT("coefficient for 1K cutoff @ 44.1K fs", mTest->compare((double)my_lowpass.coefficient, 0.43441043913502342)); }
int main(int argc, const char * argv[]) { Jamoma::UnitTest<LowpassOnePoleTest> aUnitTestInstance; return aUnitTestInstance.failureCount(); }