commit 2768767392a790991a67ddf1b60d6f859c47bbe3
parent 72d1b5378cdcb977ae6cf7673dedb39d67efd5c7
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Wed, 26 Aug 2009 09:29:48 -0400
Added some tests for Microtonal
Fixed: bug in microtonal, saving and loading Pinvertupdowncenter is now
a 127 variable rather than a bool
Diffstat:
5 files changed, 244 insertions(+), 25 deletions(-)
diff --git a/src/Misc/Microtonal.cpp b/src/Misc/Microtonal.cpp
@@ -78,7 +78,7 @@ Microtonal::~Microtonal()
/*
* Get the size of the octave
*/
-unsigned char Microtonal::getoctavesize()
+unsigned char Microtonal::getoctavesize() const
{
if (Penabled!=0) return(octavesize);
else return(12);
@@ -87,7 +87,7 @@ unsigned char Microtonal::getoctavesize()
/*
* Get the frequency according the note number
*/
-REALTYPE Microtonal::getnotefreq(int note,int keyshift)
+REALTYPE Microtonal::getnotefreq(int note,int keyshift) const
{
// in this function will appears many times things like this:
// var=(a+b*100)%b
@@ -166,6 +166,49 @@ REALTYPE Microtonal::getnotefreq(int note,int keyshift)
};
};
+bool Microtonal::operator==(const Microtonal µ) const
+{
+ return(!(*this!=micro));
+}
+
+/**\TODO remove printfs once testing is done
+//A simple macro to test equality MiCRotonal EQuals (not the perfect approach, but good enough for debug)
+#define MCREQ( x ) if(x!=micro.x){printf("%d\n",__LINE__);return true;}
+//for floats
+#define FMCREQ( x ) if(!((x<micro.x+0.0001)&&(x>micro.x-0.0001))){printf("%d\n",__LINE__);return true;}
+bool Microtonal::operator!=(const Microtonal µ) const
+{
+ MCREQ(Pinvertupdown);
+ MCREQ(Pinvertupdowncenter);
+ MCREQ(octavesize);
+ MCREQ(Penabled);
+ MCREQ(PAnote);
+ FMCREQ(PAfreq);
+ MCREQ(Pscaleshift);
+
+ MCREQ(Pfirstkey);
+ MCREQ(Plastkey);
+ MCREQ(Pmiddlenote);
+ MCREQ(Pmapsize);
+ MCREQ(Pmappingenabled);
+
+ for (int i=0;i<128;i++)
+ MCREQ(Pmapping[i]);
+
+ for (int i=0;i<octavesize;i++) {
+ FMCREQ(octave[i].tuning);
+ MCREQ(octave[i].type);
+ MCREQ(octave[i].x1);
+ MCREQ(octave[i].x2);
+ }
+ if(strcmp((const char *)this->Pname,(const char *)micro.Pname))
+ {printf("%d\n",__LINE__); return true;}
+ if(strcmp((const char *)this->Pcomment,(const char *)micro.Pcomment))
+ {printf("%d\n",__LINE__);return true;}
+ MCREQ(Pglobalfinedetune);
+ return false;
+}
+
/*
* Convert a line to tunings; returns -1 if it ok
@@ -411,13 +454,13 @@ int Microtonal::loadkbm(const char *filename)
-void Microtonal::add2XML(XMLwrapper *xml)
+void Microtonal::add2XML(XMLwrapper *xml)const
{
xml->addparstr("name",(char *) Pname);
xml->addparstr("comment",(char *) Pcomment);
xml->addparbool("invert_up_down",Pinvertupdown);
- xml->addparbool("invert_up_down_center",Pinvertupdowncenter);
+ xml->addpar("invert_up_down_center",Pinvertupdowncenter);
xml->addparbool("enabled",Penabled);
xml->addpar("global_fine_detune",Pglobalfinedetune);
@@ -456,6 +499,7 @@ void Microtonal::add2XML(XMLwrapper *xml)
xml->addpar("degree",Pmapping[i]);
xml->endbranch();
};
+
xml->endbranch();
xml->endbranch();
};
@@ -466,7 +510,7 @@ void Microtonal::getfromXML(XMLwrapper *xml)
xml->getparstr("comment",(char *) Pcomment,MICROTONAL_MAX_NAME_LEN);
Pinvertupdown=xml->getparbool("invert_up_down",Pinvertupdown);
- Pinvertupdowncenter=xml->getparbool("invert_up_down_center",Pinvertupdowncenter);
+ Pinvertupdowncenter=xml->getpar127("invert_up_down_center",Pinvertupdowncenter);
Penabled=xml->getparbool("enabled",Penabled);
Pglobalfinedetune=xml->getpar127("global_fine_detune",Pglobalfinedetune);
@@ -512,7 +556,8 @@ void Microtonal::getfromXML(XMLwrapper *xml)
};
-int Microtonal::saveXML(char *filename)
+
+int Microtonal::saveXML(const char *filename)const
{
XMLwrapper *xml=new XMLwrapper();
@@ -525,7 +570,7 @@ int Microtonal::saveXML(char *filename)
return(result);
};
-int Microtonal::loadXML(char *filename)
+int Microtonal::loadXML(const char *filename)
{
XMLwrapper *xml=new XMLwrapper();
if (xml->loadXMLfile(filename)<0) {
diff --git a/src/Misc/Microtonal.h b/src/Misc/Microtonal.h
@@ -43,18 +43,17 @@ public:
void defaults();
/**Calculates the frequency for a given note
*/
- REALTYPE getnotefreq(int note,int keyshift);
+ REALTYPE getnotefreq(int note,int keyshift) const;
//Parameters
- /**if the keys are inversed (the pitch is lower to keys from the right direction) \todo figure out why this is not a bool*/
+ /**if the keys are inversed (the pitch is lower to keys from the right direction)*/
unsigned char Pinvertupdown;
/**the central key of the inversion*/
unsigned char Pinvertupdowncenter;
- /**0 for 12 key temperate scale, 1 for microtonal
- * \todo find one good reason why this is not a bool*/
+ /**0 for 12 key temperate scale, 1 for microtonal*/
unsigned char Penabled;
/**the note of "A" key*/
@@ -70,35 +69,51 @@ public:
unsigned char Pfirstkey;
unsigned char Plastkey;
- //The middle note where scale degree 0 is mapped to
+ /**The middle note where scale degree 0 is mapped to*/
unsigned char Pmiddlenote;
- //Map size
+ /**Map size*/
unsigned char Pmapsize;
- //Mapping ON/OFF
+ /**Mapping ON/OFF*/
unsigned char Pmappingenabled;
- //Mapping (keys)
+ /**Mapping (keys)*/
short int Pmapping[128];
+ /**Fine detune to be applied to all notes*/
unsigned char Pglobalfinedetune;
// Functions
- /** Return the current octave size
- * \todo why is this not an int?*/
- unsigned char getoctavesize();
+ /** Return the current octave size*/
+ unsigned char getoctavesize() const;
+ /**Convert tunning to string*/
void tuningtoline(int n,char *line,int maxn);
- int loadscl(const char *filename);//load the tunnings from a .scl file
- int loadkbm(const char *filename);//load the mapping from .kbm file
+ /**load the tunnings from a .scl file*/
+ int loadscl(const char *filename);
+ /**load the mapping from .kbm file*/
+ int loadkbm(const char *filename);
+ /**Load text into the internal tunings
+ *
+ *\todo better description*/
int texttotunings(const char *text);
+ /**Load text into the internal mappings
+ *
+ *\todo better description*/
void texttomapping(const char *text);
+
+ /**Name of Microtonal tuning*/
unsigned char *Pname;
+ /**Comment about the tuning*/
unsigned char *Pcomment;
- void add2XML(XMLwrapper *xml);
+ void add2XML(XMLwrapper *xml)const;
void getfromXML(XMLwrapper *xml);
- int saveXML(char *filename);
- int loadXML(char *filename);
+ int saveXML(const char *filename)const;
+ int loadXML(const char *filename);
+
+ //simple operators primarily for debug
+ bool operator==(const Microtonal µ) const;
+ bool operator!=(const Microtonal µ) const;
private:
int linetotunings(unsigned int nline,const char *line);
diff --git a/src/Tests/CMakeLists.txt b/src/Tests/CMakeLists.txt
@@ -1,3 +1,4 @@
unit_test(ControllerTest ControllerTest.h "")
unit_test(EchoTest EchoTest.h "")
unit_test(SampleTest SampleTest.h "")
+unit_test(MicrotonalTest MicrotonalTest.h "")
diff --git a/src/Tests/MicrotonalTest.h b/src/Tests/MicrotonalTest.h
@@ -0,0 +1,157 @@
+/*
+ ZynAddSubFX - a software synthesizer
+
+ MicrotonalTest.h - CxxTest for Misc/Microtonal
+ 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 <iostream>
+#include "../Misc/Microtonal.h"
+#include <cstring>
+#include <string>
+
+using namespace std;
+
+class MicrotonalTest : public CxxTest::TestSuite
+{
+public:
+ void setUp() {
+ testMicro=new Microtonal();
+ }
+
+ void tearDown() {
+ delete testMicro;
+ }
+
+ //Verifies that the object is initialized correctly
+ void testinit() {
+ TS_ASSERT_EQUALS(testMicro->Pinvertupdown, 0 );
+ TS_ASSERT_EQUALS(testMicro->Pinvertupdowncenter, 60 );
+ TS_ASSERT_EQUALS(testMicro->getoctavesize(), 12 );
+ TS_ASSERT_EQUALS(testMicro->Penabled, 0 );
+ TS_ASSERT_EQUALS(testMicro->PAnote, 69 );
+ TS_ASSERT_EQUALS(testMicro->PAfreq, 440.0);
+ TS_ASSERT_EQUALS(testMicro->Pscaleshift, 64 );
+ TS_ASSERT_EQUALS(testMicro->Pfirstkey, 0 );
+ TS_ASSERT_EQUALS(testMicro->Plastkey, 127 );
+ TS_ASSERT_EQUALS(testMicro->Pmiddlenote, 60 );
+ TS_ASSERT_EQUALS(testMicro->Pmapsize, 12 );
+ TS_ASSERT_EQUALS(testMicro->Pmappingenabled, 0 );
+ TS_ASSERT_EQUALS(testMicro->Pglobalfinedetune, 64 );
+
+ TS_ASSERT_EQUALS(string((const char *)testMicro->Pname),"12tET");
+ TS_ASSERT_EQUALS(string((const char *)testMicro->Pcomment),"Equal Temperament 12 notes per octave");
+
+ for (int i=0;i<128;i++)
+ TS_ASSERT_EQUALS(testMicro->Pmapping[i], i);
+
+ TS_ASSERT_DELTA(testMicro->getnotefreq(19,0),24.4997,0.0001);
+ }
+
+ //performs basic sanity check with the == and != operators
+ void testeqeq(){
+ Microtonal other;
+ TS_ASSERT(*testMicro==other);//both are constructed the same, so they should be equal
+ other.PAfreq=220.0;
+ TS_ASSERT(*testMicro!=other);//other is now different
+ }
+
+ //Tests saving/loading to XML
+ void testXML() {
+ //Gah, the XMLwrapper is a twisted maze
+ testMicro->Penabled=1;
+ XMLwrapper xml;
+ xml.beginbranch("Dummy"); //this should not be needed, but odd behavior
+ //seems to exist from MICROTONAL being on the
+ //top of the stack
+ xml.beginbranch("MICROTONAL");
+ testMicro->add2XML(&xml);
+ xml.endbranch();
+ xml.endbranch();//this will cause the system to complain about
+ //stack errors
+
+ char *tmp=xml.getXMLdata();
+ //printf("%s",tmp);
+ Microtonal other;
+
+ cout << (char*)testMicro->Pname << " vs1 "
+ << (char*)other.Pname << endl;
+
+ other.Penabled=1;
+ strcpy((char *)other.Pname,"Myname");//will be nicer with strings
+
+ cout << (char*)testMicro->Pname << " vs1.5 "
+ << (char*)other.Pname << endl;
+
+ TS_ASSERT(*testMicro!=other);//sanity check
+
+ TS_ASSERT(xml.enterbranch("Dummy"));
+ TS_ASSERT(xml.enterbranch("MICROTONAL"));
+ //printf("%s",tmp);
+
+ other.getfromXML(&xml); //failure here
+ xml.exitbranch();
+ xml.exitbranch();
+ char *tmpo=xml.getXMLdata();
+
+ cout << (char*)testMicro->Pname << " vs2 "
+ << (char*)other.Pname << endl; //shows error here
+
+ //printf("%s",tmpo);
+ TS_ASSERT(!strcmp(tmp,tmpo)); //these should be equal, but there seems
+ //to be one line that is duplicated
+ //(I think in one of the reads)
+ free(tmp);
+ free(tmpo);
+
+ TS_ASSERT(*testMicro==other); //cxxTest sees error here
+ cout << (char*)testMicro->Pname << " vs3 "
+ << (char*)other.Pname << endl;
+
+ }
+
+ /**\todo Test Saving/loading from file*/
+ //void testSaveLoad() {}
+
+ //Test texttomapping TODO finish
+ void testTextToMapping() {
+ //the mapping is from old documentation for "Intense Diatonic" scale
+ const char *mapping[12]=
+ {"0","x","1","x","2","3","x","4","x","5","x","6"};
+ //for(int i=0;i<20;++i)
+ // cout << i << ':' << testMicro->getnotefreq(i,0) << endl;
+ //
+ // octave size == 7
+ // find dead notes
+ }
+ //Test texttotunings TODO finish
+ void testTextToTunings() {
+ //the tuning is from old documentation for "Intense Diatonic" scale
+ const char *tuning[7]={"9/8","5/4","4/3","3/2","5/3","15/8","2/1"};
+ const int numTunings=7;
+ //for(int i=0;i<20;++i)
+ // cout << i << ':' << testMicro->getnotefreq(i,0) << endl;
+ // go to middle key and verify the proportions
+
+ }
+ /**\TODO test loading from scl and kbm files*/
+
+private:
+ Microtonal *testMicro;
+
+};
diff --git a/src/Tests/make.sh b/src/Tests/make.sh
@@ -1,5 +1,6 @@
cd ../
make
cd Tests
-cxxtestgen.py --error-printer -o runner.cpp SampleTest.h EchoTest.h ControllerTest.h
-g++ -g -o runner runner.cpp ../Samples/AuSample.o ../Samples/Sample.o ../Effects/Echo.o ../Effects/Effect.o ../Controls/Control.o ../Controls/DelayCtl.o ../Params/Controller.o ../Misc/XMLwrapper.o ../Misc/Config.o ../Misc/Util.o -lmxml -lm -lz -lpthread
+#cxxtestgen.py --error-printer -o runner.cpp SampleTest.h EchoTest.h ControllerTest.h MicrotonalTest.h
+cxxtestgen.py --error-printer -o runner.cpp MicrotonalTest.h
+g++ -g -o runner runner.cpp ../Samples/AuSample.o ../Samples/Sample.o ../Effects/Echo.o ../Effects/Effect.o ../Controls/Control.o ../Controls/DelayCtl.o ../Params/Controller.o ../Misc/XMLwrapper.o ../Misc/Config.o ../Misc/Util.o ../Misc/Microtonal.o -lmxml -lm -lz -lpthread