Exemplo n.º 1
0
 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);
     
 }
Exemplo n.º 2
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);
	}
Exemplo n.º 3
0
	// Generate an impulse response from a set of coefficients
	// TODO: factor this out into the core as it is generally useful
	std::vector<double> generateReferenceImpulseResponse()
	{
		int		N = 64;								// size of the impulse response
		Jamoma::SampleVector	a = {1.0, -1.0};	// feedforward coefficients (numerator)
		Jamoma::SampleVector	b = {1.0, -0.9997};	// feedback coefficients (denominator)
		Jamoma::SampleVector	x(N);				// input -- feedforward history
		Jamoma::SampleVector	y(N);				// output -- feedback history
		
		std::fill_n(x.begin(), N, 0.0);
		std::fill_n(y.begin(), N, 0.0);
		x[0] = 1.0;
		
		for (int n=0; n<N; n++) {
			int i;
			
			for (i=0; i<a.size(); i++) {
				Jamoma::Sample	sample = x[n-i];
				
				if (n-i < 0 )
					y[n] += 0.0;
				else
					y[n] += ( a[i] * sample );
			}
			
			// ignore b[0] and assume it is normalized to 1.0
			for (i=1; i<b.size(); i++) {
				if (n-i < 0)
					y[n] -= 0.0;
				else
					y[n] -= ( b[i] * y[n - i] );
			}
		}
		return y;
	}
Exemplo n.º 4
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
						   );

	}
Exemplo n.º 5
0
	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));
		
	}