zynaddsubfx

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

SubNoteTest.cpp (5756B)


      1 /*
      2   ZynAddSubFX - a software synthesizer
      3 
      4   AdNoteTest.h - CxxTest for Synth/SUBnote
      5   Copyright (C) 2009-2011 Mark McCurry
      6   Author: Mark McCurry
      7 
      8   This program is free software; you can redistribute it and/or
      9   modify it under the terms of the GNU General Public License
     10   as published by the Free Software Foundation; either version 2
     11   of the License, or (at your option) any later version.
     12 */
     13 
     14 //Based Upon AdNoteTest.h
     15 #include "test-suite.h"
     16 #include <iostream>
     17 #include <fstream>
     18 #include <ctime>
     19 #include <string>
     20 #include "../Misc/Master.h"
     21 #include "../Misc/Allocator.h"
     22 #include "../Misc/Util.h"
     23 #include "../Misc/XMLwrapper.h"
     24 #include "../Synth/SUBnote.h"
     25 #include "../Params/SUBnoteParameters.h"
     26 #include "../Params/Presets.h"
     27 #include "../globals.h"
     28 #include <rtosc/thread-link.h>
     29 
     30 using namespace std;
     31 using namespace zyn;
     32 
     33 SYNTH_T *synth;
     34 
     35 class SubNoteTest
     36 {
     37     public:
     38 
     39         SUBnoteParameters *pars;
     40         SUBnote      *note;
     41         Master       *master;
     42         AbsTime      *time;
     43         Controller   *controller;
     44         float test_freq_log2;
     45         Alloc         memory;
     46         rtosc::ThreadLink *tr;
     47         WatchManager *w;
     48 
     49 
     50         float *outR, *outL;
     51 
     52         void setUp() {
     53             synth = new SYNTH_T;
     54             //First the sensible settings and variables that have to be set:
     55             synth->buffersize = 256;
     56             time  = new AbsTime(*synth);
     57 
     58             outL = new float[synth->buffersize];
     59             for(int i = 0; i < synth->buffersize; ++i)
     60                 *(outL + i) = 0;
     61             outR = new float[synth->buffersize];
     62             for(int i = 0; i < synth->buffersize; ++i)
     63                 *(outR + i) = 0;
     64 
     65             tr  = new rtosc::ThreadLink(1024,3);
     66             w   = new WatchManager(tr);
     67 
     68             //prepare the default settings
     69             SUBnoteParameters *defaultPreset = new SUBnoteParameters(time);
     70             XMLwrapper wrap;
     71             wrap.loadXMLfile(string(SOURCE_DIR)
     72                               + string("/guitar-adnote.xmz"));
     73             TS_ASSERT(wrap.enterbranch("MASTER"));
     74             TS_ASSERT(wrap.enterbranch("PART", 1));
     75             TS_ASSERT(wrap.enterbranch("INSTRUMENT"));
     76             TS_ASSERT(wrap.enterbranch("INSTRUMENT_KIT"));
     77             TS_ASSERT(wrap.enterbranch("INSTRUMENT_KIT_ITEM", 0));
     78             TS_ASSERT(wrap.enterbranch("SUB_SYNTH_PARAMETERS"));
     79             defaultPreset->getfromXML(wrap);
     80 
     81             controller = new Controller(*synth, time);
     82 
     83             //lets go with.... 50! as a nice note
     84             test_freq_log2 = log2f(440.0f) + (50.0 - 69.0f) / 12.0f;
     85 
     86             SynthParams pars{memory, *controller, *synth, *time, 120, 0, test_freq_log2, false, prng()};
     87             note = new SUBnote(defaultPreset, pars, w);
     88             this->pars = defaultPreset;
     89         }
     90 
     91         void tearDown() {
     92             delete controller;
     93             delete note;
     94             delete w;
     95             delete tr;
     96             delete [] outL;
     97             delete [] outR;
     98             delete time;
     99             delete synth;
    100             delete pars;
    101         }
    102 
    103         void testDefaults() {
    104             //Note: if these tests fail it is due to the relationship between
    105             //global.h::RND and SUBnote.cpp
    106 
    107             int sampleCount = 0;
    108 
    109 //#define WRITE_OUTPUT
    110 
    111 #ifdef WRITE_OUTPUT
    112             ofstream file("subnoteout", ios::out);
    113 #endif
    114             note->noteout(outL, outR);
    115 #ifdef WRITE_OUTPUT
    116             for(int i = 0; i < synth->buffersize; ++i)
    117                 file << outL[i] << std::endl;
    118 
    119 #endif
    120             sampleCount += synth->buffersize;
    121 
    122             TS_ASSERT_DELTA(outL[255], -0.0009f, 0.0001f);
    123 
    124             note->releasekey();
    125 
    126             TS_ASSERT(!tr->hasNext());
    127             w->add_watch("noteout/filter");
    128 
    129             note->noteout(outL, outR);
    130             sampleCount += synth->buffersize;
    131             TS_ASSERT_DELTA(outL[255], 0.0026f, 0.0001f);
    132             w->tick();
    133 
    134             note->noteout(outL, outR);
    135             sampleCount += synth->buffersize;
    136             TS_ASSERT_DELTA(outL[255], -0.0011f, 0.0001f);
    137             w->tick();
    138 
    139             TS_ASSERT(tr->hasNext());
    140             TS_ASSERT_EQUAL_STR("noteout/filter", tr->read());
    141             TS_ASSERT(!tr->hasNext());
    142 
    143             w->add_watch("noteout/amp_int");
    144             note->noteout(outL, outR);
    145             sampleCount += synth->buffersize;
    146             TS_ASSERT_DELTA(outL[255], -0.0023f, 0.0001f);
    147             w->tick();
    148 
    149             note->noteout(outL, outR);
    150             sampleCount += synth->buffersize;
    151             TS_ASSERT_DELTA(outL[255], -0.0013f, 0.0001f);
    152             w->tick();
    153             TS_ASSERT(tr->hasNext());
    154             TS_ASSERT_EQUAL_STR("noteout/amp_int", tr->read());
    155             TS_ASSERT(!tr->hasNext());
    156 
    157             while(!note->finished()) {
    158                 note->noteout(outL, outR);
    159 #ifdef WRITE_OUTPUT
    160                 for(int i = 0; i < synth->buffersize; ++i)
    161                     file << outL[i] << std::endl;
    162 
    163 #endif
    164                 sampleCount += synth->buffersize;
    165             }
    166 #ifdef WRITE_OUTPUT
    167             file.close();
    168 #endif
    169 
    170             TS_ASSERT_EQUAL_INT(sampleCount, 5888);
    171         }
    172 
    173 #define OUTPUT_PROFILE
    174 #ifdef OUTPUT_PROFILE
    175         void testSpeed() {
    176             const int samps = 15000;
    177 
    178             int t_on = clock(); // timer before calling func
    179             for(int i = 0; i < samps; ++i)
    180                 note->noteout(outL, outR);
    181             int t_off = clock(); // timer when func returns
    182 
    183             printf("SubNoteTest: %f seconds for %d Samples to be generated.\n",
    184                    (static_cast<float>(t_off - t_on)) / CLOCKS_PER_SEC, samps);
    185         }
    186 #endif
    187 };
    188 
    189 int main(void)
    190 {
    191     SubNoteTest test;
    192     RUN_TEST(testDefaults);
    193     return test_summary();
    194 }