| 
							- 
 - #include <assert.h>
 - 
 - #include "Analyzer.h"
 - #include "asserts.h"
 - #include "CHB.h"
 - #include "EvenVCO.h"
 - #include "FunVCO.h"
 - #include "SawOscillator.h"
 - #include "TestComposite.h"
 - 
 - 
 - using EVCO = EvenVCO <TestComposite>;
 - //using FUN = VoltageControlledOscillator<16, 16>;
 - using CH = CHB<TestComposite>;
 - 
 - float desiredPitch(float octave, float tune, float cv1, float cv2, float mod)
 - {
 -     float pitch = 1.0f + roundf(octave) + tune / 12.0f;
 -     pitch += cv1 + cv2;
 -     pitch += mod / 4.0f;
 - 
 -     float freq = 261.626f * powf(2.0f, pitch);
 -     // printf("theirs: pitch = %f exp = %f\n", pitch, freq);
 -     return freq;
 - }
 - 
 - float desiredPitchEv(const EVCO& vco)
 - {
 - #if 1
 -     return desiredPitch(
 -         vco.params[(int) EVCO::OCTAVE_PARAM].value,
 -         vco.params[(int) EVCO::TUNE_PARAM].value,
 -         vco.inputs[(int) EVCO::PITCH1_INPUT].value,
 -         vco.inputs[(int) EVCO::PITCH2_INPUT].value,
 -         vco.inputs[(int) EVCO::FM_INPUT].value
 -     );
 - #else
 -     // This is just the original code as reference
 -     float pitch = 1.0f + roundf(vco.params[(int) EVCO::OCTAVE_PARAM].value) + vco.params[(int) EVCO::TUNE_PARAM].value / 12.0f;
 -     pitch += vco.inputs[(int) EVCO::PITCH1_INPUT].value + vco.inputs[(int) EVCO::PITCH2_INPUT].value;
 -     pitch += vco.inputs[(int) EVCO::FM_INPUT].value / 4.0f;
 - 
 -     float freq = 261.626f * powf(2.0f, pitch);
 -    // printf("theirs: pitch = %f exp = %f\n", pitch, freq);
 -     return freq;
 - #endif
 - }
 - 
 - float desiredPitchCh(const CH& vco)
 - {
 -     return desiredPitch(
 -         vco.params[(int) CH::PARAM_OCTAVE].value,
 -         vco.params[(int) CH::PARAM_TUNE].value,
 -         vco.inputs[(int) CH::CV_INPUT].value,
 -         0,
 -         vco.inputs[(int) CH::PITCH_MOD_INPUT].value
 -     );
 - 
 - #if 0
 -     float pitch = 1.0f + roundf(vco.params[(int) CH::PARAM_OCTAVE].value) + vco.params[(int) CH::PARAM_TUNE].value / 12.0f;
 -     pitch += vco.inputs[(int) CH::CV_INPUT].value;
 -     pitch += vco.inputs[(int) CH::PITCH_MOD_INPUT].value / 4.0f;
 - 
 -     // TODO: atenuverter on FM
 - 
 -     float freq = 261.626f * powf(2.0f, pitch);
 -     // printf("theirs: pitch = %f exp = %f\n", pitch, freq);
 -     printf("in desiredPitchCh oct=%f, tune=%f cv=%f, mode=%f\n",
 -         vco.params[(int) CH::PARAM_OCTAVE].value,
 -         vco.params[(int) CH::PARAM_TUNE].value,
 -         vco.inputs[(int) CH::CV_INPUT].value,
 -         vco.inputs[(int) CH::PITCH_MOD_INPUT].value);
 -     printf("  freq = %f\n", freq);
 - 
 - 
 -     return freq;
 - #endif
 - }
 - 
 - static void testxEv(float octave, float tune = 0, float pitch1 = 0, float pitch2 = 0, float fm = 0)
 - {
 -     EVCO vco;
 - 
 -     vco.params[(int) EVCO::OCTAVE_PARAM].value = octave;
 -     vco.params[(int) EVCO::TUNE_PARAM].value = tune;
 -     vco.inputs[(int) EVCO::PITCH1_INPUT].value = pitch1;
 -     vco.inputs[(int) EVCO::PITCH2_INPUT].value = pitch2;
 -     vco.inputs[(int) EVCO::FM_INPUT].value = fm;
 - 
 -     vco.outputs[(int) EVCO::SAW_OUTPUT].active = true;
 -     vco.outputs[(int) EVCO::EVEN_OUTPUT].active = false;
 -     vco.outputs[(int) EVCO::TRI_OUTPUT].active = false;
 -     vco.outputs[(int) EVCO::SQUARE_OUTPUT].active = false;
 -     vco.outputs[(int) EVCO::SINE_OUTPUT].active = false;
 - 
 -     vco.step();
 -     const float desired = desiredPitchEv(vco);
 - 
 -    // printf("test, oct=%f, freq=%.2f desired=%.2f\n", octave, vco._freq, desired);
 -     if (desired > 20000) {
 -         // lookup table doesn't go past 20k. that's fine
 -         assertGE(vco._freq, 20000 - 1);
 -     } else {
 -         assertClose(vco._freq, desired, 1.5);     // todo: make better tolerance
 -     }
 - }
 - 
 - static void testxCh(float octave, float tune = 0, float pitch1 = 0, float pitch2 = 0, float fm = 0)
 - {
 -     CH vco;
 - 
 -     assert(pitch2 == 0);     // ch doesn't have one
 - 
 -     vco.params[(int) CH::PARAM_OCTAVE].value = octave;
 -     vco.params[(int) CH::PARAM_TUNE].value = tune;
 -     vco.inputs[(int) CH::CV_INPUT].value = pitch1;
 -   //  vco.inputs[(int) CH::PITCH2_INPUT].value = pitch2;
 -     vco.inputs[(int) CH::PITCH_MOD_INPUT].value = fm;
 - 
 - 
 -     vco.step();
 -     const float desired = desiredPitchCh(vco);
 - 
 -     // printf("test, oct=%f, freq=%.2f desired=%.2f\n", octave, vco._freq, desired);
 -     if (desired > 20000) {
 -         // lookup table doesn't go past 20k. that's fine
 -         assertGE(vco._freq, 20000 - 1);
 -     } else {
 -         assertClose(vco._freq, desired, 1.5);     // todo: make better tolerance
 -     }
 - }
 - 
 - 
 - static void testInitEv()
 - {
 -     EVCO vco;
 - 
 -     vco.step();
 -     const float desired = desiredPitchEv(vco);
 -     assertClose(vco._freq, desired, 1);         // todo: tighten up
 - }
 - 
 - static void testInitCh()
 - {
 -     CH vco;
 - 
 -     vco.step();
 -     const float desired = desiredPitchCh(vco);
 -     assertClose(vco._freq, desired, 1);         // todo: tighten up
 - }
 - 
 - static void testOctavesEv()
 - {
 -     EVCO vco;
 -     for (int octave = -5; octave <= 4; ++octave) {
 -         testxEv(float(octave));
 -     }
 - }
 - 
 - static void testOctavesCh()
 - {
 -     CH vco;
 -     for (int octave = -5; octave <= 4; ++octave) {
 -         testxCh(float(octave));
 -     }
 - }
 - // test that we go up to 20k
 - static void testMaxFreqEv()
 - {
 -     testxEv(4, 7, 0, 0);
 -     testxEv(4, 7, 1, 0);
 -     testxEv(4, 7, 0, 1);
 - 
 - }
 - 
 - static void testMaxFreqCh()
 - {
 -     testxCh(4, 7, 0, 0);
 -     testxCh(4, 7, 1, 0);
 - }
 - 
 - static void testMinFreqEv()
 - {
 -     testxEv(-5, -7, 0, 0);
 -     testxEv(-5, -7, -2, 0);
 - }
 - 
 - static void testMinFreqCh()
 - {
 -     testxCh(-5, -7, 0, 0);
 -     testxCh(-5, -7, -2, 0);
 - }
 - 
 - static void testTuneEv()
 - {
 -     testxEv(0, -7, 0, 0);
 -     testxEv(0, 7, 0, 0);
 - }
 - 
 - 
 - static void testTuneCh()
 - {
 -     testxCh(0, -7, 0, 0);
 -     testxCh(0, 7, 0, 0);
 - }
 - 
 - 
 - static void testClamp()
 - {
 -     assertEQ(std::clamp(12, 0, 14), 12);
 -     assertEQ(std::clamp(12, 0, 10), 10);
 -    
 -     assertEQ(std::clamp(12, 13, 15), 13);
 - }
 - 
 - #if 1
 - void testVCO()
 - {
 -     testInitEv();
 -     testInitCh();
 -     testOctavesEv();
 -     testOctavesCh();
 -     testMaxFreqEv();
 -     testMaxFreqCh();
 -     testMinFreqEv();
 -     testMinFreqCh();
 -     testClamp();
 -     testTuneEv();
 -     testTuneCh();
 - }
 - #else
 - void testVCO()
 - {
 -     testOctavesCh();
 - }
 - #endif
 
 
  |