@@ -91,39 +91,41 @@ src/dist/ | |||
*build-*Debug/ | |||
*build-*Release/ | |||
# ZynAddSubFX UI | |||
source/modules/native-plugins/zynaddsubfx/UI/ADnoteUI.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/ADnoteUI.h | |||
source/modules/native-plugins/zynaddsubfx/UI/BankUI.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/BankUI.h | |||
source/modules/native-plugins/zynaddsubfx/UI/ConfigUI.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/ConfigUI.h | |||
source/modules/native-plugins/zynaddsubfx/UI/EffUI.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/EffUI.h | |||
source/modules/native-plugins/zynaddsubfx/UI/EnvelopeUI.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/EnvelopeUI.h | |||
source/modules/native-plugins/zynaddsubfx/UI/FilterUI.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/FilterUI.h | |||
source/modules/native-plugins/zynaddsubfx/UI/LFOUI.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/LFOUI.h | |||
source/modules/native-plugins/zynaddsubfx/UI/MasterUI.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/MasterUI.h | |||
source/modules/native-plugins/zynaddsubfx/UI/MicrotonalUI.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/MicrotonalUI.h | |||
source/modules/native-plugins/zynaddsubfx/UI/OscilGenUI.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/OscilGenUI.h | |||
source/modules/native-plugins/zynaddsubfx/UI/PADnoteUI.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/PADnoteUI.h | |||
source/modules/native-plugins/zynaddsubfx/UI/PartUI.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/PartUI.h | |||
source/modules/native-plugins/zynaddsubfx/UI/PresetsUI.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/PresetsUI.h | |||
source/modules/native-plugins/zynaddsubfx/UI/ResonanceUI.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/ResonanceUI.h | |||
source/modules/native-plugins/zynaddsubfx/UI/SUBnoteUI.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/SUBnoteUI.h | |||
source/modules/native-plugins/zynaddsubfx/UI/VirKeyboard.cpp | |||
source/modules/native-plugins/zynaddsubfx/UI/VirKeyboard.h | |||
# ZynAddSubFX | |||
source/modules/native-plugins/ZynAddSubFX/Output/ | |||
source/modules/native-plugins/ZynAddSubFX/Tests/ | |||
source/modules/native-plugins/ZynAddSubFX/UI/ADnoteUI.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/ADnoteUI.h | |||
source/modules/native-plugins/ZynAddSubFX/UI/BankUI.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/BankUI.h | |||
source/modules/native-plugins/ZynAddSubFX/UI/ConfigUI.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/ConfigUI.h | |||
source/modules/native-plugins/ZynAddSubFX/UI/EffUI.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/EffUI.h | |||
source/modules/native-plugins/ZynAddSubFX/UI/EnvelopeUI.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/EnvelopeUI.h | |||
source/modules/native-plugins/ZynAddSubFX/UI/FilterUI.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/FilterUI.h | |||
source/modules/native-plugins/ZynAddSubFX/UI/LFOUI.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/LFOUI.h | |||
source/modules/native-plugins/ZynAddSubFX/UI/MasterUI.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/MasterUI.h | |||
source/modules/native-plugins/ZynAddSubFX/UI/MicrotonalUI.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/MicrotonalUI.h | |||
source/modules/native-plugins/ZynAddSubFX/UI/OscilGenUI.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/OscilGenUI.h | |||
source/modules/native-plugins/ZynAddSubFX/UI/PADnoteUI.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/PADnoteUI.h | |||
source/modules/native-plugins/ZynAddSubFX/UI/PartUI.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/PartUI.h | |||
source/modules/native-plugins/ZynAddSubFX/UI/PresetsUI.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/PresetsUI.h | |||
source/modules/native-plugins/ZynAddSubFX/UI/ResonanceUI.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/ResonanceUI.h | |||
source/modules/native-plugins/ZynAddSubFX/UI/SUBnoteUI.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/SUBnoteUI.h | |||
source/modules/native-plugins/ZynAddSubFX/UI/VirKeyboard.cpp | |||
source/modules/native-plugins/ZynAddSubFX/UI/VirKeyboard.h | |||
# Other | |||
source/includes/asio/ | |||
@@ -1,711 +0,0 @@ | |||
/* | |||
ZynAddSubFX - a software synthesizer | |||
DSSIaudiooutput.cpp - Audio functions for DSSI | |||
Copyright (C) 2002 Nasca Octavian Paul | |||
Author: Nasca Octavian Paul | |||
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 | |||
*/ | |||
/* | |||
* Inital working DSSI output code contributed by Stephen G. Parry | |||
*/ | |||
//this file contains code used from trivial_synth.c from | |||
//the DSSI (published by Steve Harris under public domain) as a template. | |||
#include "DSSIaudiooutput.h" | |||
#include "../Misc/Config.h" | |||
#include "../Misc/Bank.h" | |||
#include "../Misc/Util.h" | |||
#include <string.h> | |||
#include <limits.h> | |||
using std::string; | |||
using std::vector; | |||
//Dummy variables and functions for linking purposes | |||
const char *instance_name = 0; | |||
class WavFile; | |||
namespace Nio { | |||
bool start(void){return 1;}; | |||
void stop(void){}; | |||
void waveNew(WavFile *){} | |||
void waveStart(void){} | |||
void waveStop(void){} | |||
void waveEnd(void){} | |||
} | |||
// | |||
// Static stubs for LADSPA member functions | |||
// | |||
// LADSPA is essentially a C handle based API; This plug-in implementation is | |||
// a C++ OO one so we need stub functions to map from C API calls to C++ object | |||
// method calls. | |||
void DSSIaudiooutput::stub_connectPort(LADSPA_Handle instance, | |||
unsigned long port, | |||
LADSPA_Data *data) | |||
{ | |||
getInstance(instance)->connectPort(port, data); | |||
} | |||
void DSSIaudiooutput::stub_activate(LADSPA_Handle instance) | |||
{ | |||
getInstance(instance)->activate(); | |||
} | |||
void DSSIaudiooutput::stub_run(LADSPA_Handle instance, | |||
unsigned long sample_count) | |||
{ | |||
getInstance(instance)->run(sample_count); | |||
} | |||
void DSSIaudiooutput::stub_deactivate(LADSPA_Handle instance) | |||
{ | |||
getInstance(instance)->deactivate(); | |||
} | |||
void DSSIaudiooutput::stub_cleanup(LADSPA_Handle instance) | |||
{ | |||
DSSIaudiooutput *plugin_instance = getInstance(instance); | |||
plugin_instance->cleanup(); | |||
delete plugin_instance; | |||
} | |||
const LADSPA_Descriptor *ladspa_descriptor(unsigned long index) | |||
{ | |||
return DSSIaudiooutput::getLadspaDescriptor(index); | |||
} | |||
// | |||
// Static stubs for DSSI member functions | |||
// | |||
// DSSI is essentially a C handle based API; This plug-in implementation is | |||
// a C++ OO one so we need stub functions to map from C API calls to C++ object | |||
// method calls. | |||
const DSSI_Program_Descriptor *DSSIaudiooutput::stub_getProgram( | |||
LADSPA_Handle instance, | |||
unsigned long index) | |||
{ | |||
return getInstance(instance)->getProgram(index); | |||
} | |||
void DSSIaudiooutput::stub_selectProgram(LADSPA_Handle instance, | |||
unsigned long bank, | |||
unsigned long program) | |||
{ | |||
getInstance(instance)->selectProgram(bank, program); | |||
} | |||
int DSSIaudiooutput::stub_getMidiControllerForPort(LADSPA_Handle instance, | |||
unsigned long port) | |||
{ | |||
return getInstance(instance)->getMidiControllerForPort(port); | |||
} | |||
void DSSIaudiooutput::stub_runSynth(LADSPA_Handle instance, | |||
unsigned long sample_count, | |||
snd_seq_event_t *events, | |||
unsigned long event_count) | |||
{ | |||
getInstance(instance)->runSynth(sample_count, events, event_count); | |||
} | |||
const DSSI_Descriptor *dssi_descriptor(unsigned long index) | |||
{ | |||
return DSSIaudiooutput::getDssiDescriptor(index); | |||
} | |||
// | |||
// LADSPA member functions | |||
// | |||
/** | |||
* Instantiates a plug-in. | |||
* | |||
* This LADSPA member function instantiates a plug-in. | |||
* Note that instance initialisation should generally occur in | |||
* activate() rather than here. | |||
* | |||
* Zyn Implementation | |||
* ------------------ | |||
* This implementation creates a C++ class object and hides its pointer | |||
* in the handle by type casting. | |||
* | |||
* @param descriptor [in] the descriptor for this plug-in | |||
* @param s_rate [in] the sample rate | |||
* @return the plug-in instance handle if successful else NULL | |||
*/ | |||
LADSPA_Handle DSSIaudiooutput::instantiate(const LADSPA_Descriptor *descriptor, | |||
unsigned long s_rate) | |||
{ | |||
if(descriptor->UniqueID == dssiDescriptor->LADSPA_Plugin->UniqueID) | |||
return (LADSPA_Handle)(new DSSIaudiooutput(s_rate)); | |||
else | |||
return NULL; | |||
} | |||
/** | |||
* Connects a port on an instantiated plug-in. | |||
* | |||
* This LADSPA member function connects a port on an instantiated plug-in to a | |||
* memory location at which a block of data for the port will be read/written. | |||
* The data location is expected to be an array of LADSPA_Data for audio ports | |||
* or a single LADSPA_Data value for control ports. Memory issues will be | |||
* managed by the host. The plug-in must read/write the data at these locations | |||
* every time run() or run_adding() is called and the data present at the time | |||
* of this connection call should not be considered meaningful. | |||
* | |||
* Zyn Implementation | |||
* ------------------ | |||
* The buffer pointers are stored as member variables | |||
* | |||
* @param port [in] the port to be connected | |||
* @param data [in] the data buffer to write to / read from | |||
*/ | |||
void DSSIaudiooutput::connectPort(unsigned long port, LADSPA_Data *data) | |||
{ | |||
switch(port) { | |||
case 0: | |||
outl = data; | |||
break; | |||
case 1: | |||
outr = data; | |||
break; | |||
} | |||
} | |||
/** | |||
* Initialises a plug-in instance and activates it for use. | |||
* | |||
* This LADSPA member function initialises a plug-in instance and activates it | |||
* for use. This is separated from instantiate() to aid real-time support and | |||
* so that hosts can reinitialise a plug-in instance by calling deactivate() and | |||
* then activate(). In this case the plug-in instance must reset all state | |||
* information dependent on the history of the plug-in instance except for any | |||
* data locations provided by connect_port() and any gain set by | |||
* set_run_adding_gain(). | |||
* | |||
* Zyn Implementation | |||
* ------------------ | |||
* Currently this does nothing; Care must be taken as to code placed here as | |||
* too much code here seems to cause time-out problems in jack-dssi-host. | |||
*/ | |||
void DSSIaudiooutput::activate() | |||
{} | |||
/** | |||
* Runs an instance of a plug-in for a block. | |||
* | |||
* This LADSPA member function runs an instance of a plug-in for a block. | |||
* Note that if an activate() function exists then it must be called before | |||
* run() or run_adding(). If deactivate() is called for a plug-in instance then | |||
* the plug-in instance may not be reused until activate() has been called again. | |||
* | |||
* Zyn Implementation | |||
* ------------------ | |||
* This is a LADSPA function that does not process any MIDI events; it is hence | |||
* implemented by simply calling runSynth() with an empty event list. | |||
* | |||
* @param sample_count [in] the block size (in samples) for which the plug-in instance may run | |||
*/ | |||
void DSSIaudiooutput::run(unsigned long sample_count) | |||
{ | |||
runSynth(sample_count, NULL, (unsigned long)0); | |||
} | |||
/** | |||
* Counterpart to activate(). | |||
* | |||
* This LADSPA member function is the counterpart to activate() (see above). | |||
* Deactivation is not similar to pausing as the plug-in instance will be | |||
* reinitialised when activate() is called to reuse it. | |||
* | |||
* Zyn Implementation | |||
* ------------------ | |||
* Currently this function does nothing. | |||
*/ | |||
void DSSIaudiooutput::deactivate() | |||
{} | |||
/** | |||
* Deletes a plug-in instance that is no longer required. | |||
* | |||
* LADSPA member function; once an instance of a plug-in has been finished with | |||
* it can be deleted using this function. The instance handle ceases to be | |||
* valid after this call. | |||
* | |||
* If activate() was called for a plug-in instance then a corresponding call to | |||
* deactivate() must be made before cleanup() is called. | |||
* | |||
* Zyn Implementation | |||
* ------------------ | |||
* Currently cleanup is deferred to the destructor that is invoked after cleanup() | |||
*/ | |||
void DSSIaudiooutput::cleanup() | |||
{} | |||
/** | |||
* Initial entry point for the LADSPA plug-in library. | |||
* | |||
* This LADSPA function is the initial entry point for the plug-in library. | |||
* The LADSPA host looks for this entry point in each shared library object it | |||
* finds and then calls the function to enumerate the plug-ins within the | |||
* library. | |||
* | |||
* Zyn Implementation | |||
* ------------------ | |||
* As the Zyn plug-in is a DSSI plug-in, the LADSPA descriptor is embedded inside | |||
* the DSSI descriptor, which is created by DSSIaudiooutput::initDssiDescriptor() | |||
* statically when the library is loaded. This function then merely returns a pointer | |||
* to that embedded descriptor. | |||
* | |||
* @param index [in] the index number of the plug-in within the library. | |||
* @return if index is in range, a pointer to the plug-in descriptor is returned, else NULL | |||
*/ | |||
const LADSPA_Descriptor *DSSIaudiooutput::getLadspaDescriptor( | |||
unsigned long index) | |||
{ | |||
if((index > 0) || (dssiDescriptor == NULL)) | |||
return NULL; | |||
else | |||
return dssiDescriptor->LADSPA_Plugin; | |||
} | |||
// | |||
// DSSI member functions | |||
// | |||
/** | |||
* Provides a description of a program available on this synth. | |||
* | |||
* This DSSI member function pointer provides a description of a program (named | |||
* preset sound) available on this synth. | |||
* | |||
* Zyn Implementation | |||
* ------------------ | |||
* The instruments in all Zyn's bank directories, as shown by the `instrument | |||
* -> show instrument bank` command, are enumerated to the host by this | |||
* function, allowing access to all those instruments. | |||
* The first time an instrument is requested, the bank it is in and any | |||
* unmapped ones preceding that are mapped; all the instruments names and | |||
* filenames from those banks are stored in the programMap member variable for | |||
* later use. This is done on demand in this way, rather than up front in one | |||
* go because loading all the instrument names in one go can lead to timeouts | |||
* and zombies. | |||
* | |||
* @param index [in] index into the plug-in's list of | |||
* programs, not a program number as represented by the Program | |||
* field of the DSSI_Program_Descriptor. (This distinction is | |||
* needed to support synths that use non-contiguous program or | |||
* bank numbers.) | |||
* @return a DSSI_Program_Descriptor pointer that is | |||
* guaranteed to be valid only until the next call to get_program, | |||
* deactivate, or configure, on the same plug-in instance, or NULL if index is out of range. | |||
*/ | |||
const DSSI_Program_Descriptor *DSSIaudiooutput::getProgram(unsigned long index) | |||
{ | |||
static DSSI_Program_Descriptor retVal; | |||
/* Make sure we have the list of banks loaded */ | |||
initBanks(); | |||
/* Make sure that the bank containing the instrument has been mapped */ | |||
while(index >= programMap.size() && mapNextBank()) | |||
/* DO NOTHING MORE */; | |||
if(index >= programMap.size()) | |||
/* No more instruments */ | |||
return NULL; | |||
else { | |||
/* OK, return the instrument */ | |||
retVal.Name = programMap[index].name.c_str(); | |||
retVal.Program = programMap[index].program; | |||
retVal.Bank = programMap[index].bank; | |||
return &retVal; | |||
} | |||
} | |||
/** | |||
* Selects a new program for this synth. | |||
* | |||
* This DSSI member function selects a new program for this synth. The program | |||
* change will take effect immediately at the start of the next run_synth() | |||
* call. An invalid bank / instrument combination is ignored. | |||
* | |||
* Zyn Implementation | |||
* ------------------ | |||
* the banks and instruments are as shown in the `instrument -> show instrument | |||
* bank` command in Zyn. The bank no is a 1-based index into the list of banks | |||
* Zyn loads and shows in the drop down and the program number is the | |||
* instrument within that bank. | |||
* | |||
* @param bank [in] the bank number to select | |||
* @param program [in] the program number within the bank to select | |||
*/ | |||
void DSSIaudiooutput::selectProgram(unsigned long bank, unsigned long program) | |||
{ | |||
initBanks(); | |||
// cerr << "selectProgram(" << (bank & 0x7F) << ':' << ((bank >> 7) & 0x7F) << "," << program << ")" << '\n'; | |||
if((bank < master->bank.banks.size()) && (program < BANK_SIZE)) { | |||
const std::string bankdir = master->bank.banks[bank].dir; | |||
if(!bankdir.empty()) { | |||
pthread_mutex_lock(&master->mutex); | |||
/* We have to turn off the CheckPADsynth functionality, else | |||
* the program change takes way too long and we get timeouts | |||
* and hence zombies (!) */ | |||
int save = config.cfg.CheckPADsynth; | |||
config.cfg.CheckPADsynth = 0; | |||
/* Load the bank... */ | |||
master->bank.loadbank(bankdir); | |||
/* restore the CheckPADsynth flag */ | |||
config.cfg.CheckPADsynth = save; | |||
/* Now load the instrument... */ | |||
master->bank.loadfromslot((unsigned int)program, master->part[0]); | |||
pthread_mutex_unlock(&master->mutex); | |||
} | |||
} | |||
} | |||
/** | |||
* Returns the MIDI controller number or NRPN for a input control port | |||
* | |||
* This DSSI member function returns the MIDI controller number or NRPN that | |||
* should be mapped to the given input control port. If the given port should | |||
* not have any MIDI controller mapped to it, the function will return DSSI_NONE. | |||
* The behaviour of this function is undefined if the given port | |||
* number does not correspond to an input control port. | |||
* | |||
* Zyn Implementation | |||
* ------------------ | |||
* Currently Zyn does not define any controller ports, but may do in the future. | |||
* | |||
* @param port [in] the input controller port | |||
* @return the CC and NRPN values shifted and ORed together. | |||
*/ | |||
int DSSIaudiooutput::getMidiControllerForPort(unsigned long port) | |||
{ | |||
return DSSI_NONE; | |||
} | |||
/** | |||
* Runs the synth for a block. | |||
* | |||
* This DSSI member function runs the synth for a block. This is identical in | |||
* function to the LADSPA run() function, except that it also supplies events | |||
* to the synth. | |||
* | |||
* Zyn Implementation | |||
* ------------------ | |||
* Zyn implements synthesis in Master::GetAudioOutSamples; runSynth calls this | |||
* function in chunks delimited by the sample_count and the frame indexes in | |||
* the events block, calling the appropriate NoteOn, NoteOff and SetController | |||
* members of Master to process the events supplied between each chunk. | |||
* | |||
* @param sample_count [in] the block size (in samples) for which the synth | |||
* instance may run. | |||
* @param events [in] The Events pointer points to a block of ALSA | |||
* sequencer events, used to communicate MIDI and related events to the synth. | |||
* Each event must be timestamped relative to the start of the block, | |||
* (mis)using the ALSA "tick time" field as a frame count. The host is | |||
* responsible for ensuring that events with differing timestamps are already | |||
* ordered by time. Must not include NOTE (only NOTE_ON / NOTE_OFF), LSB or MSB | |||
* events. | |||
* @param event_count [in] the number of entries in the `events` block | |||
*/ | |||
void DSSIaudiooutput::runSynth(unsigned long sample_count, | |||
snd_seq_event_t *events, | |||
unsigned long event_count) | |||
{ | |||
unsigned long from_frame = 0; | |||
unsigned long event_index = 0; | |||
unsigned long next_event_frame = 0; | |||
unsigned long to_frame = 0; | |||
pthread_mutex_lock(&master->mutex); | |||
do { | |||
/* Find the time of the next event, if any */ | |||
if((events == NULL) || (event_index >= event_count)) | |||
next_event_frame = ULONG_MAX; | |||
else | |||
next_event_frame = events[event_index].time.tick; | |||
/* find the end of the sub-sample to be processed this time round... */ | |||
/* if the next event falls within the desired sample interval... */ | |||
if((next_event_frame < sample_count) && (next_event_frame >= to_frame)) | |||
/* set the end to be at that event */ | |||
to_frame = next_event_frame; | |||
else | |||
/* ...else go for the whole remaining sample */ | |||
to_frame = sample_count; | |||
if(from_frame < to_frame) { | |||
// call master to fill from `from_frame` to `to_frame`: | |||
master->GetAudioOutSamples(to_frame - from_frame, | |||
(int)sampleRate, | |||
&(outl[from_frame]), | |||
&(outr[from_frame])); | |||
// next sub-sample please... | |||
from_frame = to_frame; | |||
} | |||
// Now process any event(s) at the current timing point | |||
while(events != NULL && event_index < event_count | |||
&& events[event_index].time.tick == to_frame) { | |||
if(events[event_index].type == SND_SEQ_EVENT_NOTEON) | |||
master->noteOn(events[event_index].data.note.channel, | |||
events[event_index].data.note.note, | |||
events[event_index].data.note.velocity); | |||
else | |||
if(events[event_index].type == SND_SEQ_EVENT_NOTEOFF) | |||
master->noteOff(events[event_index].data.note.channel, | |||
events[event_index].data.note.note); | |||
else | |||
if(events[event_index].type == SND_SEQ_EVENT_CONTROLLER) | |||
master->setController(events[event_index].data.control.channel, | |||
events[event_index].data.control.param, | |||
events[event_index].data.control.value); | |||
else {} | |||
event_index++; | |||
} | |||
// Keep going until we have the desired total length of sample... | |||
} while(to_frame < sample_count); | |||
pthread_mutex_unlock(&master->mutex); | |||
} | |||
/** | |||
* Initial entry point for the DSSI plug-in library. | |||
* | |||
* This DSSI function is the initial entry point for the plug-in library. | |||
* The DSSI host looks for this entry point in each shared library object it | |||
* finds and then calls the function to enumerate the plug-ins within the | |||
* library. | |||
* | |||
* Zyn Implementation | |||
* ------------------ | |||
* The descriptor is created statically by DSSIaudiooutput::initDssiDescriptor() | |||
* when the plug-in library is loaded. This function merely returns a pointer to | |||
* that descriptor. | |||
* | |||
* @param index [in] the index number of the plug-in within the library. | |||
* @return if index is in range, a pointer to the plug-in descriptor is returned, else NULL | |||
*/ | |||
const DSSI_Descriptor *DSSIaudiooutput::getDssiDescriptor(unsigned long index) | |||
{ | |||
if((index > 0) || (dssiDescriptor == NULL)) | |||
return NULL; | |||
else | |||
return dssiDescriptor; | |||
} | |||
// | |||
// Internal member functions | |||
// | |||
// Initialise the DSSI descriptor, statically: | |||
DSSI_Descriptor *DSSIaudiooutput::dssiDescriptor = | |||
DSSIaudiooutput::initDssiDescriptor(); | |||
/** | |||
* Initializes the DSSI (and LADSPA) descriptor, returning it is an object. | |||
*/ | |||
DSSI_Descriptor *DSSIaudiooutput::initDssiDescriptor() | |||
{ | |||
DSSI_Descriptor *newDssiDescriptor = new DSSI_Descriptor; | |||
LADSPA_PortDescriptor *newPortDescriptors; | |||
const char **newPortNames; | |||
LADSPA_PortRangeHint *newPortRangeHints; | |||
if(newDssiDescriptor) { | |||
LADSPA_Descriptor *newLadspaDescriptor = new LADSPA_Descriptor; | |||
if(newLadspaDescriptor) { | |||
newLadspaDescriptor->UniqueID = 100; | |||
newLadspaDescriptor->Label = "ZASF"; | |||
newLadspaDescriptor->Properties = 0; | |||
newLadspaDescriptor->Name = "ZynAddSubFX"; | |||
newLadspaDescriptor->Maker = | |||
"Nasca Octavian Paul <zynaddsubfx@yahoo.com>"; | |||
newLadspaDescriptor->Copyright = "GNU General Public License v.2"; | |||
newLadspaDescriptor->PortCount = 2; | |||
newPortNames = new const char *[newLadspaDescriptor->PortCount]; | |||
newPortNames[0] = "Output L"; | |||
newPortNames[1] = "Output R"; | |||
newLadspaDescriptor->PortNames = newPortNames; | |||
newPortDescriptors = | |||
new LADSPA_PortDescriptor[newLadspaDescriptor->PortCount]; | |||
newPortDescriptors[0] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; | |||
newPortDescriptors[1] = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO; | |||
newLadspaDescriptor->PortDescriptors = newPortDescriptors; | |||
newPortRangeHints = | |||
new LADSPA_PortRangeHint[newLadspaDescriptor->PortCount]; | |||
newPortRangeHints[0].HintDescriptor = 0; | |||
newPortRangeHints[1].HintDescriptor = 0; | |||
newLadspaDescriptor->PortRangeHints = newPortRangeHints; | |||
newLadspaDescriptor->activate = stub_activate; | |||
newLadspaDescriptor->cleanup = stub_cleanup; | |||
newLadspaDescriptor->connect_port = stub_connectPort; | |||
newLadspaDescriptor->deactivate = stub_deactivate; | |||
newLadspaDescriptor->instantiate = instantiate; | |||
newLadspaDescriptor->run = stub_run; | |||
newLadspaDescriptor->run_adding = NULL; | |||
newLadspaDescriptor->set_run_adding_gain = NULL; | |||
} | |||
newDssiDescriptor->LADSPA_Plugin = newLadspaDescriptor; | |||
newDssiDescriptor->DSSI_API_Version = 1; | |||
newDssiDescriptor->configure = NULL; | |||
newDssiDescriptor->get_program = stub_getProgram; | |||
newDssiDescriptor->get_midi_controller_for_port = | |||
stub_getMidiControllerForPort; | |||
newDssiDescriptor->select_program = stub_selectProgram; | |||
newDssiDescriptor->run_synth = stub_runSynth; | |||
newDssiDescriptor->run_synth_adding = NULL; | |||
newDssiDescriptor->run_multiple_synths = NULL; | |||
newDssiDescriptor->run_multiple_synths_adding = NULL; | |||
} | |||
dssiDescriptor = newDssiDescriptor; | |||
return dssiDescriptor; | |||
} | |||
/** | |||
* Converts a LADSPA / DSSI handle into a DSSIaudiooutput instance. | |||
* | |||
* @param instance [in] | |||
* @return the instance | |||
*/ | |||
DSSIaudiooutput *DSSIaudiooutput::getInstance(LADSPA_Handle instance) | |||
{ | |||
return (DSSIaudiooutput *)(instance); | |||
} | |||
SYNTH_T *synth; | |||
/** | |||
* The private sole constructor for the DSSIaudiooutput class. | |||
* | |||
* Only ever called via instantiate(). | |||
* @param sampleRate [in] the sample rate to be used by the synth. | |||
* @return | |||
*/ | |||
DSSIaudiooutput::DSSIaudiooutput(unsigned long sampleRate) | |||
{ | |||
synth = new SYNTH_T; | |||
synth->samplerate = sampleRate; | |||
this->sampleRate = sampleRate; | |||
this->banksInited = false; | |||
config.init(); | |||
sprng(time(NULL)); | |||
denormalkillbuf = new float [synth->buffersize]; | |||
for(int i = 0; i < synth->buffersize; i++) | |||
denormalkillbuf[i] = (RND - 0.5f) * 1e-16; | |||
synth->alias(); | |||
this->master = new Master(); | |||
} | |||
/** | |||
* The destructor for the DSSIaudiooutput class | |||
* @return | |||
*/ | |||
DSSIaudiooutput::~DSSIaudiooutput() | |||
{} | |||
/** | |||
* Ensures the list of bank (directories) has been initialised. | |||
*/ | |||
void DSSIaudiooutput::initBanks(void) | |||
{ | |||
if(!banksInited) { | |||
pthread_mutex_lock(&master->mutex); | |||
master->bank.rescanforbanks(); | |||
banksInited = true; | |||
pthread_mutex_unlock(&master->mutex); | |||
} | |||
} | |||
/** | |||
* constructor for the internally used ProgramDescriptor class | |||
* | |||
* @param _bank [in] bank number | |||
* @param _program [in] program number | |||
* @param _name [in] instrument / sample name | |||
* @return | |||
*/ | |||
DSSIaudiooutput::ProgramDescriptor::ProgramDescriptor(unsigned long _bank, | |||
unsigned long _program, | |||
char *_name) | |||
:bank(_bank), program(_program), name(_name) | |||
{} | |||
/** | |||
* The map of programs available; held as a single shared statically allocated object. | |||
*/ | |||
vector<DSSIaudiooutput::ProgramDescriptor> DSSIaudiooutput::programMap = | |||
vector<DSSIaudiooutput::ProgramDescriptor>(); | |||
/** | |||
* Index controlling the map of banks | |||
*/ | |||
long DSSIaudiooutput::bankNoToMap = 1; | |||
/** | |||
* Queries and maps the next available bank of instruments. | |||
* | |||
* If the program index requested to getProgram() lies beyond the banks mapped to date, | |||
* this member function is called to map the next one. | |||
* @return true if a new bank has been found and mapped, else false. | |||
*/ | |||
bool DSSIaudiooutput::mapNextBank() | |||
{ | |||
pthread_mutex_lock(&master->mutex); | |||
Bank &bank = master->bank; | |||
bool retval; | |||
if((bankNoToMap >= (int)bank.banks.size()) | |||
|| bank.banks[bankNoToMap].dir.empty()) | |||
retval = false; | |||
else { | |||
bank.loadbank(bank.banks[bankNoToMap].dir); | |||
for(unsigned long instrument = 0; instrument < BANK_SIZE; | |||
++instrument) { | |||
string insName = bank.getname(instrument); | |||
if(!insName.empty() && (insName[0] != '\0') && (insName[0] != ' ')) | |||
programMap.push_back(ProgramDescriptor(bankNoToMap, instrument, | |||
const_cast<char *>( | |||
insName.c_str()))); | |||
} | |||
bankNoToMap++; | |||
retval = true; | |||
} | |||
pthread_mutex_unlock(&master->mutex); | |||
return retval; | |||
} |
@@ -1,123 +0,0 @@ | |||
/* | |||
ZynAddSubFX - a software synthesizer | |||
VSTaudiooutput.h - Audio output for VST | |||
Copyright (C) 2002 Nasca Octavian Paul | |||
Author: Nasca Octavian Paul | |||
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 | |||
*/ | |||
#ifndef VST_AUDIO_OUTPUT_H | |||
#define VST_AUDIO_OUTPUT_H | |||
#include <pthread.h> | |||
#include "../globals.h" | |||
#include "../Misc/Master.h" | |||
#include <dssi.h> | |||
#include <ladspa.h> | |||
#include <vector> | |||
class DSSIaudiooutput | |||
{ | |||
public: | |||
// | |||
// Static stubs for LADSPA member functions | |||
// | |||
static void stub_connectPort(LADSPA_Handle instance, | |||
unsigned long port, | |||
LADSPA_Data *data); | |||
static void stub_activate(LADSPA_Handle instance); | |||
static void stub_run(LADSPA_Handle instance, unsigned long sample_count); | |||
static void stub_deactivate(LADSPA_Handle Instance); | |||
static void stub_cleanup(LADSPA_Handle instance); | |||
// | |||
// Static stubs for DSSI member functions | |||
// | |||
static const DSSI_Program_Descriptor *stub_getProgram( | |||
LADSPA_Handle instance, | |||
unsigned long Index); | |||
static void stub_selectProgram(LADSPA_Handle instance, | |||
unsigned long bank, | |||
unsigned long program); | |||
static int stub_getMidiControllerForPort(LADSPA_Handle instance, | |||
unsigned long port); | |||
static void stub_runSynth(LADSPA_Handle instance, | |||
unsigned long sample_count, | |||
snd_seq_event_t *events, | |||
unsigned long event_count); | |||
/* | |||
* LADSPA member functions | |||
*/ | |||
static LADSPA_Handle instantiate(const LADSPA_Descriptor *descriptor, | |||
unsigned long s_rate); | |||
void connectPort(unsigned long port, LADSPA_Data *data); | |||
void activate(); | |||
void run(unsigned long sample_count); | |||
void deactivate(); | |||
void cleanup(); | |||
static const LADSPA_Descriptor *getLadspaDescriptor(unsigned long index); | |||
/* | |||
* DSSI member functions | |||
*/ | |||
const DSSI_Program_Descriptor *getProgram(unsigned long Index); | |||
void selectProgram(unsigned long bank, unsigned long program); | |||
int getMidiControllerForPort(unsigned long port); | |||
void runSynth(unsigned long sample_count, | |||
snd_seq_event_t *events, | |||
unsigned long event_count); | |||
static const DSSI_Descriptor *getDssiDescriptor(unsigned long index); | |||
struct ProgramDescriptor { | |||
unsigned long bank; | |||
unsigned long program; | |||
std::string name; | |||
ProgramDescriptor(unsigned long _bank, | |||
unsigned long _program, | |||
char *_name); | |||
}; | |||
private: | |||
DSSIaudiooutput(unsigned long sampleRate); | |||
~DSSIaudiooutput(); | |||
static DSSI_Descriptor *initDssiDescriptor(); | |||
static DSSIaudiooutput *getInstance(LADSPA_Handle instance); | |||
void initBanks(); | |||
bool mapNextBank(); | |||
LADSPA_Data *outl; | |||
LADSPA_Data *outr; | |||
long sampleRate; | |||
Master *master; | |||
static DSSI_Descriptor *dssiDescriptor; | |||
static std::string bankDirNames[]; | |||
static | |||
std::vector<ProgramDescriptor> programMap; | |||
/** | |||
* Flag controlling the list of bank directories | |||
*/ | |||
bool banksInited; | |||
static | |||
long bankNoToMap; | |||
}; | |||
#endif |
@@ -1,201 +0,0 @@ | |||
/* | |||
ZynAddSubFX - a software synthesizer | |||
AdNoteTest.h - CxxTest for Synth/ADnote | |||
Copyright (C) 2009-2011 Mark McCurry | |||
Copyright (C) 2009 Harald Hvaal | |||
Authors: Mark McCurry, Harald Hvaal | |||
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 <fstream> | |||
#include <ctime> | |||
#include <string> | |||
#include "../Misc/Master.h" | |||
#include "../Misc/Util.h" | |||
#include "../Synth/ADnote.h" | |||
#include "../Params/Presets.h" | |||
#include "../DSP/FFTwrapper.h" | |||
#include "../globals.h" | |||
SYNTH_T *synth; | |||
using namespace std; | |||
class AdNoteTest:public CxxTest::TestSuite | |||
{ | |||
public: | |||
ADnote *note; | |||
Master *master; | |||
FFTwrapper *fft; | |||
Controller *controller; | |||
unsigned char testnote; | |||
float *outR, *outL; | |||
void setUp() { | |||
//First the sensible settings and variables that have to be set: | |||
synth = new SYNTH_T; | |||
synth->buffersize = 256; | |||
outL = new float[synth->buffersize]; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
*(outL + i) = 0; | |||
outR = new float[synth->buffersize]; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
*(outR + i) = 0; | |||
//next the bad global variables that for some reason have not been properly placed in some | |||
//initialization routine, but rather exist as cryptic oneliners in main.cpp: | |||
denormalkillbuf = new float[synth->buffersize]; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
denormalkillbuf[i] = 0; | |||
//phew, glad to get thouse out of my way. took me a lot of sweat and gdb to get this far... | |||
fft = new FFTwrapper(synth->oscilsize); | |||
//prepare the default settings | |||
ADnoteParameters *defaultPreset = new ADnoteParameters(fft); | |||
//Assert defaults | |||
TS_ASSERT(!defaultPreset->VoicePar[1].Enabled); | |||
XMLwrapper *wrap = new XMLwrapper(); | |||
cout << string(SOURCE_DIR) + string("/guitar-adnote.xmz") | |||
<< endl; | |||
wrap->loadXMLfile(string(SOURCE_DIR) | |||
+ string("/guitar-adnote.xmz")); | |||
TS_ASSERT(wrap->enterbranch("MASTER")); | |||
TS_ASSERT(wrap->enterbranch("PART", 0)); | |||
TS_ASSERT(wrap->enterbranch("INSTRUMENT")); | |||
TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT")); | |||
TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT_ITEM", 0)); | |||
TS_ASSERT(wrap->enterbranch("ADD_SYNTH_PARAMETERS")); | |||
defaultPreset->getfromXML(wrap); | |||
//defaultPreset->defaults(); | |||
//verify xml was loaded | |||
TS_ASSERT(defaultPreset->VoicePar[1].Enabled); | |||
controller = new Controller(); | |||
//lets go with.... 50! as a nice note | |||
testnote = 50; | |||
float freq = 440.0f * powf(2.0f, (testnote - 69.0f) / 12.0f); | |||
note = new ADnote(defaultPreset, | |||
controller, | |||
freq, | |||
120, | |||
0, | |||
testnote, | |||
false); | |||
delete defaultPreset; | |||
delete wrap; | |||
} | |||
void willNoteBeRunButIsHereForLinkingReasonsHowsThisForCamelCaseEh() | |||
{ | |||
master = new Master(); | |||
} | |||
void tearDown() { | |||
delete note; | |||
delete controller; | |||
delete fft; | |||
delete [] outL; | |||
delete [] outR; | |||
delete [] denormalkillbuf; | |||
FFT_cleanup(); | |||
delete synth; | |||
} | |||
void testDefaults() { | |||
int sampleCount = 0; | |||
//#define WRITE_OUTPUT | |||
#ifdef WRITE_OUTPUT | |||
ofstream file("adnoteout", ios::out); | |||
#endif | |||
note->noteout(outL, outR); | |||
#ifdef WRITE_OUTPUT | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
file << outL[i] << std::endl; | |||
#endif | |||
sampleCount += synth->buffersize; | |||
TS_ASSERT_DELTA(outL[255], 0.254609f, 0.0001f); | |||
note->relasekey(); | |||
note->noteout(outL, outR); | |||
sampleCount += synth->buffersize; | |||
TS_ASSERT_DELTA(outL[255], -0.102197f, 0.0001f); | |||
note->noteout(outL, outR); | |||
sampleCount += synth->buffersize; | |||
TS_ASSERT_DELTA(outL[255], -0.111422f, 0.0001f); | |||
note->noteout(outL, outR); | |||
sampleCount += synth->buffersize; | |||
TS_ASSERT_DELTA(outL[255], -0.021375f, 0.0001f); | |||
note->noteout(outL, outR); | |||
sampleCount += synth->buffersize; | |||
TS_ASSERT_DELTA(outL[255], 0.149882f, 0.0001f); | |||
while(!note->finished()) { | |||
note->noteout(outL, outR); | |||
#ifdef WRITE_OUTPUT | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
file << outL[i] << std::endl; | |||
#endif | |||
sampleCount += synth->buffersize; | |||
} | |||
#ifdef WRITE_OUTPUT | |||
file.close(); | |||
#endif | |||
TS_ASSERT_EQUALS(sampleCount, 9472); | |||
} | |||
#define OUTPUT_PROFILE | |||
#ifdef OUTPUT_PROFILE | |||
void testSpeed() { | |||
const int samps = 15000; | |||
int t_on = clock(); // timer before calling func | |||
for(int i = 0; i < samps; ++i) | |||
note->noteout(outL, outR); | |||
int t_off = clock(); // timer when func returns | |||
printf("AdNoteTest: %f seconds for %d Samples to be generated.\n", | |||
(static_cast<float>(t_off - t_on)) / CLOCKS_PER_SEC, samps); | |||
} | |||
#endif | |||
}; |
@@ -1,33 +0,0 @@ | |||
#for tests looking for files stored in the source dir | |||
add_definitions(-DSOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") | |||
CXXTEST_ADD_TEST(ControllerTest ControllerTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/ControllerTest.h) | |||
CXXTEST_ADD_TEST(EchoTest EchoTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/EchoTest.h) | |||
#CXXTEST_ADD_TEST(SampleTest SampleTest.h) | |||
CXXTEST_ADD_TEST(MicrotonalTest MicrotonalTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/MicrotonalTest.h) | |||
CXXTEST_ADD_TEST(XMLwrapperTest XMLwrapper.cpp ${CMAKE_CURRENT_SOURCE_DIR}/XMLwrapperTest.h) | |||
CXXTEST_ADD_TEST(ADnoteTest AdNoteTest.cpp | |||
${CMAKE_CURRENT_SOURCE_DIR}/AdNoteTest.h) | |||
CXXTEST_ADD_TEST(SUBnoteTest SubNoteTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/SubNoteTest.h) | |||
CXXTEST_ADD_TEST(OscilGenTest OscilGenTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/OscilGenTest.h) | |||
CXXTEST_ADD_TEST(RandTest RandTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/RandTest.h) | |||
CXXTEST_ADD_TEST(PADnoteTest PadNoteTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/PadNoteTest.h) | |||
CXXTEST_ADD_TEST(PluginTest PluginTest.cpp ${CMAKE_CURRENT_SOURCE_DIR}/PluginTest.h) | |||
#Extra libraries added to make test and full compilation use the same library | |||
#links for quirky compilers | |||
set(test_lib zynaddsubfx_core ${ZLIB_LIBRARY} ${FFTW_LIBRARIES} ${MXML_LIBRARIES} pthread) | |||
message(STATUS "Linking tests with: ${test_lib}") | |||
target_link_libraries(ADnoteTest ${test_lib}) | |||
target_link_libraries(SUBnoteTest ${test_lib}) | |||
target_link_libraries(ControllerTest ${test_lib}) | |||
target_link_libraries(EchoTest ${test_lib}) | |||
target_link_libraries(MicrotonalTest ${test_lib}) | |||
target_link_libraries(OscilGenTest ${test_lib}) | |||
target_link_libraries(XMLwrapperTest ${test_lib}) | |||
target_link_libraries(RandTest ${test_lib}) | |||
target_link_libraries(PADnoteTest ${test_lib}) | |||
target_link_libraries(PluginTest zynaddsubfx_core zynaddsubfx_nio | |||
${OS_LIBRARIES} ${AUDIO_LIBRARIES}) | |||
@@ -1,75 +0,0 @@ | |||
/* | |||
ZynAddSubFX - a software synthesizer | |||
ControllerTest.h - CxxTest for Params/Controller | |||
Copyright (C) 2009-2011 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 "../Params/Controller.h" | |||
#include "../globals.h" | |||
SYNTH_T *synth; | |||
class ControllerTest:public CxxTest::TestSuite | |||
{ | |||
public: | |||
void setUp() { | |||
synth = new SYNTH_T; | |||
testCtl = new Controller(); | |||
} | |||
void tearDown() { | |||
delete testCtl; | |||
delete synth; | |||
} | |||
void testPortamentoRange() { | |||
//Initialize portamento | |||
testCtl->setportamento(127); | |||
testCtl->portamento.time = 127; | |||
testCtl->initportamento(40.0f, 400.0f, false); | |||
//Bounds Check | |||
while(testCtl->portamento.used) { | |||
TS_ASSERT((0.0f <= testCtl->portamento.x) | |||
&& (testCtl->portamento.x <= 1.0f)); | |||
TS_ASSERT((0.1f <= testCtl->portamento.freqrap) | |||
&& (testCtl->portamento.freqrap <= 1.0f)); | |||
testCtl->updateportamento(); | |||
} | |||
TS_ASSERT((0.0f <= testCtl->portamento.x) | |||
&& (testCtl->portamento.x <= 1.0f)); | |||
TS_ASSERT((0.1f <= testCtl->portamento.freqrap) | |||
&& (testCtl->portamento.freqrap <= 1.0f)); | |||
} | |||
void testPortamentoValue() { | |||
testCtl->setportamento(127); | |||
testCtl->portamento.time = 127; | |||
testCtl->initportamento(40.0f, 400.0f, false); | |||
int i; | |||
for(i = 0; i < 10; ++i) | |||
testCtl->updateportamento(); | |||
//Assert that the numbers are the same as they were at release | |||
TS_ASSERT_DELTA(testCtl->portamento.x, 0.0290249f, 0.000001f) | |||
TS_ASSERT_DELTA(testCtl->portamento.freqrap, 0.126122f, 0.000001f) | |||
} | |||
private: | |||
Controller *testCtl; | |||
}; |
@@ -1,126 +0,0 @@ | |||
/* | |||
ZynAddSubFX - a software synthesizer | |||
EchoTest.h - CxxTest for Effect/Echo | |||
Copyright (C) 2009-2011 Mark McCurry | |||
Copyright (C) 2009 Harald Hvaal | |||
Authors: Mark McCurry, Harald Hvaal | |||
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 <cmath> | |||
#include <cstdlib> | |||
#include <iostream> | |||
#include "../Effects/Echo.h" | |||
#include "../globals.h" | |||
SYNTH_T *synth; | |||
using namespace std; | |||
class EchoTest:public CxxTest::TestSuite | |||
{ | |||
public: | |||
void setUp() { | |||
synth = new SYNTH_T; | |||
outL = new float[synth->buffersize]; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
outL[i] = 0.0f; | |||
outR = new float[synth->buffersize]; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
outR[i] = 0.0f; | |||
input = new Stereo<float *>(new float[synth->buffersize], | |||
new float[synth->buffersize]); | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
input->l[i] = input->r[i] = 0.0f; | |||
testFX = new Echo(true, outL, outR); | |||
} | |||
void tearDown() { | |||
delete[] input->r; | |||
delete[] input->l; | |||
delete input; | |||
delete[] outL; | |||
delete[] outR; | |||
delete testFX; | |||
delete synth; | |||
} | |||
void testInit() { | |||
//Make sure that the output will be zero at start | |||
//(given a zero input) | |||
testFX->out(*input); | |||
for(int i = 0; i < synth->buffersize; ++i) { | |||
TS_ASSERT_DELTA(outL[i], 0.0f, 0.0001f); | |||
TS_ASSERT_DELTA(outR[i], 0.0f, 0.0001f); | |||
} | |||
} | |||
void testClear() { | |||
char DELAY = 2; | |||
testFX->changepar(DELAY, 127); | |||
//flood with high input | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
input->r[i] = input->l[i] = 1.0f; | |||
for(int i = 0; i < 500; ++i) | |||
testFX->out(*input); | |||
for(int i = 0; i < synth->buffersize; ++i) { | |||
TS_ASSERT_DIFFERS(outL[i], 0.0f); | |||
TS_ASSERT_DIFFERS(outR[i], 0.0f) | |||
} | |||
//After making sure the internal buffer has a nonzero value | |||
//cleanup | |||
//Then get the next output, which should be zereoed out if DELAY | |||
//is large enough | |||
testFX->cleanup(); | |||
testFX->out(*input); | |||
for(int i = 0; i < synth->buffersize; ++i) { | |||
TS_ASSERT_DELTA(outL[i], 0.0f, 0.0001f); | |||
TS_ASSERT_DELTA(outR[i], 0.0f, 0.0001f); | |||
} | |||
} | |||
//Insures that the proper decay occurs with high feedback | |||
void testDecaywFb() { | |||
//flood with high input | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
input->r[i] = input->l[i] = 1.0f; | |||
char FEEDBACK = 5; | |||
testFX->changepar(FEEDBACK, 127); | |||
for(int i = 0; i < 100; ++i) | |||
testFX->out(*input); | |||
for(int i = 0; i < synth->buffersize; ++i) { | |||
TS_ASSERT_DIFFERS(outL[i], 0.0f); | |||
TS_ASSERT_DIFFERS(outR[i], 0.0f) | |||
} | |||
float amp = abs(outL[0] + outR[0]) / 2; | |||
//reset input to zero | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
input->r[i] = input->l[i] = 0.0f; | |||
//give the echo time to fade based upon zero input and high feedback | |||
for(int i = 0; i < 50; ++i) | |||
testFX->out(*input); | |||
TS_ASSERT_LESS_THAN_EQUALS(abs(outL[0] + outR[0]) / 2, amp); | |||
} | |||
private: | |||
Stereo<float *> *input; | |||
float *outR, *outL; | |||
Echo *testFX; | |||
}; |
@@ -1,136 +0,0 @@ | |||
/* | |||
ZynAddSubFX - a software synthesizer | |||
MicrotonalTest.h - CxxTest for Misc/Microtonal | |||
Copyright (C) 2009-2012 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> | |||
#include <cstdio> | |||
#include "../globals.h" | |||
SYNTH_T *synth; | |||
using namespace std; | |||
class MicrotonalTest:public CxxTest::TestSuite | |||
{ | |||
public: | |||
void setUp() { | |||
synth = new SYNTH_T; | |||
testMicro = new Microtonal(); | |||
} | |||
void tearDown() { | |||
delete testMicro; | |||
delete synth; | |||
} | |||
//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.0f); | |||
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.4997f, 0.0001f); | |||
} | |||
//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(); | |||
char *tmp = xml.getXMLdata(); | |||
Microtonal other; | |||
other.Penabled = 1; | |||
strcpy((char *)other.Pname, "Myname"); //will be nicer with strings | |||
TS_ASSERT(*testMicro != other); //sanity check | |||
TS_ASSERT(xml.enterbranch("Dummy")); | |||
TS_ASSERT(xml.enterbranch("MICROTONAL")); | |||
other.getfromXML(&xml); | |||
xml.exitbranch(); | |||
xml.exitbranch(); | |||
char *tmpo = xml.getXMLdata(); | |||
TS_ASSERT(!strcmp(tmp, tmpo)); | |||
free(tmp); | |||
free(tmpo); | |||
} | |||
#if 0 | |||
/**\todo Test Saving/loading from file*/ | |||
//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*/ | |||
#endif | |||
private: | |||
Microtonal *testMicro; | |||
}; |
@@ -1,141 +0,0 @@ | |||
/* | |||
ZynAddSubFX - a software synthesizer | |||
AdNoteTest.h - CxxTest for Synth/OscilGen | |||
Copyright (C) 20011-2012 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 <string> | |||
#include "../Synth/OscilGen.h" | |||
#include "../globals.h" | |||
SYNTH_T *synth; | |||
using namespace std; | |||
class OscilGenTest:public CxxTest::TestSuite | |||
{ | |||
public: | |||
float freq; | |||
float *outR, *outL; | |||
FFTwrapper *fft; | |||
OscilGen *oscil; | |||
void setUp() { | |||
synth = new SYNTH_T; | |||
//First the sensible settings and variables that have to be set: | |||
synth->buffersize = 256; | |||
synth->oscilsize = 1024; | |||
outL = new float[synth->oscilsize]; | |||
outR = new float[synth->oscilsize]; | |||
memset(outL, 0, sizeof(float) * synth->oscilsize); | |||
memset(outR, 0, sizeof(float) * synth->oscilsize); | |||
//next the bad global variables that for some reason have not been properly placed in some | |||
//initialization routine, but rather exist as cryptic oneliners in main.cpp: | |||
denormalkillbuf = new float[synth->buffersize]; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
denormalkillbuf[i] = 0; | |||
//prepare the default settings | |||
fft = new FFTwrapper(synth->oscilsize); | |||
oscil = new OscilGen(fft, NULL); | |||
//Assert defaults [TODO] | |||
XMLwrapper *wrap = new XMLwrapper(); | |||
wrap->loadXMLfile(string(SOURCE_DIR) | |||
+ string("/guitar-adnote.xmz")); | |||
TS_ASSERT(wrap->enterbranch("MASTER")); | |||
TS_ASSERT(wrap->enterbranch("PART", 0)); | |||
TS_ASSERT(wrap->enterbranch("INSTRUMENT")); | |||
TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT")); | |||
TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT_ITEM", 0)); | |||
TS_ASSERT(wrap->enterbranch("ADD_SYNTH_PARAMETERS")); | |||
TS_ASSERT(wrap->enterbranch("VOICE", 0)); | |||
TS_ASSERT(wrap->enterbranch("OSCIL")); | |||
oscil->getfromXML(wrap); | |||
delete wrap; | |||
//verify xml was loaded [TODO] | |||
//lets go with.... 50! as a nice note | |||
const char testnote = 50; | |||
freq = 440.0f * powf(2.0f, (testnote - 69.0f) / 12.0f); | |||
} | |||
void tearDown() { | |||
delete oscil; | |||
delete fft; | |||
delete[] outL; | |||
delete[] outR; | |||
delete[] denormalkillbuf; | |||
FFT_cleanup(); | |||
delete synth; | |||
} | |||
//verifies that initialization occurs | |||
void testInit(void) | |||
{ | |||
oscil->get(outL, freq); | |||
} | |||
void testOutput(void) | |||
{ | |||
oscil->get(outL, freq); | |||
TS_ASSERT_DELTA(outL[23], -0.044547f, 0.0001f); | |||
TS_ASSERT_DELTA(outL[129], -0.018169f, 0.0001f); | |||
TS_ASSERT_DELTA(outL[586], 0.045647f, 0.0001f); | |||
TS_ASSERT_DELTA(outL[1023], -0.038334f, 0.0001f); | |||
} | |||
void testSpectrum(void) | |||
{ | |||
oscil->getspectrum(synth->oscilsize / 2, outR, 1); | |||
TS_ASSERT_DELTA(outR[0], 350.698059f, 0.0001f); | |||
TS_ASSERT_DELTA(outR[1], 228.889267f, 0.0001f); | |||
TS_ASSERT_DELTA(outR[2], 62.187931f, 0.0001f); | |||
TS_ASSERT_DELTA(outR[3], 22.295225f, 0.0001f); | |||
TS_ASSERT_DELTA(outR[4], 6.942001f, 0.0001f); | |||
TS_ASSERT_DELTA(outR[26], 0.015110f, 0.0001f); | |||
TS_ASSERT_DELTA(outR[47], 0.003425f, 0.0001f); | |||
TS_ASSERT_DELTA(outR[65], 0.001293f, 0.0001f); | |||
} | |||
//performance testing | |||
void testSpeed() { | |||
const int samps = 15000; | |||
int t_on = clock(); // timer before calling func | |||
for(int i = 0; i < samps; ++i) | |||
oscil->prepare(); | |||
int t_off = clock(); // timer when func returns | |||
printf("OscilGenTest: %f seconds for %d prepares.\n", | |||
(static_cast<float>(t_off - t_on)) / CLOCKS_PER_SEC, samps); | |||
t_on = clock(); // timer before calling func | |||
for(int i = 0; i < samps; ++i) | |||
oscil->get(outL, freq); | |||
t_off = clock(); // timer when func returns | |||
printf("OscilGenTest: %f seconds for %d gets.\n", | |||
(static_cast<float>(t_off - t_on)) / CLOCKS_PER_SEC, samps); | |||
} | |||
}; |
@@ -1,207 +0,0 @@ | |||
/* | |||
ZynAddSubFX - a software synthesizer | |||
PadNoteTest.h - CxxTest for Synth/PADnote | |||
Copyright (C) 20012 zco | |||
Author: zco | |||
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 | |||
*/ | |||
//Based Upon AdNoteTest.h and SubNoteTest.h | |||
#include <cxxtest/TestSuite.h> | |||
#include <iostream> | |||
#include <fstream> | |||
#include <ctime> | |||
#include <string> | |||
#include "../Misc/Master.h" | |||
#include "../Misc/Util.h" | |||
#include "../Synth/PADnote.h" | |||
#include "../Params/Presets.h" | |||
#include "../DSP/FFTwrapper.h" | |||
#include "../globals.h" | |||
SYNTH_T *synth; | |||
using namespace std; | |||
class PadNoteTest:public CxxTest::TestSuite | |||
{ | |||
public: | |||
PADnote *note; | |||
Master *master; | |||
FFTwrapper *fft; | |||
Controller *controller; | |||
unsigned char testnote; | |||
float *outR, *outL; | |||
void setUp() { | |||
synth = new SYNTH_T; | |||
//First the sensible settings and variables that have to be set: | |||
synth->buffersize = 256; | |||
outL = new float[synth->buffersize]; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
*(outL + i) = 0; | |||
outR = new float[synth->buffersize]; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
*(outR + i) = 0; | |||
//next the bad global variables that for some reason have not been properly placed in some | |||
//initialization routine, but rather exist as cryptic oneliners in main.cpp: | |||
denormalkillbuf = new float[synth->buffersize]; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
denormalkillbuf[i] = 0; | |||
//phew, glad to get thouse out of my way. took me a lot of sweat and gdb to get this far... | |||
fft = new FFTwrapper(synth->oscilsize); | |||
//prepare the default settings | |||
PADnoteParameters *defaultPreset = new PADnoteParameters(fft,NULL); | |||
//Assert defaults | |||
///TS_ASSERT(!defaultPreset->VoicePar[1].Enabled); | |||
XMLwrapper *wrap = new XMLwrapper(); | |||
cout << string(SOURCE_DIR) + string("/guitar-adnote.xmz") | |||
<< endl; | |||
wrap->loadXMLfile(string(SOURCE_DIR) | |||
+ string("/guitar-adnote.xmz")); | |||
TS_ASSERT(wrap->enterbranch("MASTER")); | |||
TS_ASSERT(wrap->enterbranch("PART", 2)); | |||
TS_ASSERT(wrap->enterbranch("INSTRUMENT")); | |||
TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT")); | |||
TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT_ITEM", 0)); | |||
TS_ASSERT(wrap->enterbranch("PAD_SYNTH_PARAMETERS")); | |||
defaultPreset->getfromXML(wrap); | |||
//defaultPreset->defaults(); | |||
defaultPreset->applyparameters(false); | |||
//verify xml was loaded | |||
///TS_ASSERT(defaultPreset->VoicePar[1].Enabled); | |||
controller = new Controller(); | |||
//lets go with.... 50! as a nice note | |||
testnote = 50; | |||
float freq = 440.0f * powf(2.0f, (testnote - 69.0f) / 12.0f); | |||
note = new PADnote(defaultPreset, | |||
controller, | |||
freq, | |||
120, | |||
0, | |||
testnote, | |||
false); | |||
//delete defaultPreset; | |||
delete wrap; | |||
} | |||
void willNoteBeRunButIsHereForLinkingReasonsHowsThisForCamelCaseEh() | |||
{ | |||
master = new Master(); | |||
} | |||
void tearDown() { | |||
delete note; | |||
delete controller; | |||
delete fft; | |||
delete [] outL; | |||
delete [] outR; | |||
delete [] denormalkillbuf; | |||
FFT_cleanup(); | |||
delete synth; | |||
} | |||
void testDefaults() { | |||
int sampleCount = 0; | |||
//#define WRITE_OUTPUT | |||
#ifdef WRITE_OUTPUT | |||
ofstream file("padnoteout", ios::out); | |||
#endif | |||
note->noteout(outL, outR); | |||
#ifdef WRITE_OUTPUT | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
file << outL[i] << std::endl; | |||
#endif | |||
sampleCount += synth->buffersize; | |||
TS_ASSERT_DELTA(outL[255], 0.0660f, 0.0001f); | |||
note->relasekey(); | |||
note->noteout(outL, outR); | |||
sampleCount += synth->buffersize; | |||
TS_ASSERT_DELTA(outL[255], -0.0729f, 0.0001f); | |||
note->noteout(outL, outR); | |||
sampleCount += synth->buffersize; | |||
TS_ASSERT_DELTA(outL[255], 0.0613f, 0.0001f); | |||
note->noteout(outL, outR); | |||
sampleCount += synth->buffersize; | |||
TS_ASSERT_DELTA(outL[255], 0.0378f, 0.0005f); | |||
note->noteout(outL, outR); | |||
sampleCount += synth->buffersize; | |||
TS_ASSERT_DELTA(outL[255], -0.0070f, 0.0001f); | |||
while(!note->finished()) { | |||
note->noteout(outL, outR); | |||
#ifdef WRITE_OUTPUT | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
file << outL[i] << std::endl; | |||
#endif | |||
sampleCount += synth->buffersize; | |||
} | |||
#ifdef WRITE_OUTPUT | |||
file.close(); | |||
#endif | |||
TS_ASSERT_EQUALS(sampleCount, 2304); | |||
} | |||
#define OUTPUT_PROFILE | |||
#ifdef OUTPUT_PROFILE | |||
void testSpeed() { | |||
const int samps = 15000; | |||
int t_on = clock(); // timer before calling func | |||
for(int i = 0; i < samps; ++i) | |||
note->noteout(outL, outR); | |||
int t_off = clock(); // timer when func returns | |||
printf("PadNoteTest: %f seconds for %d Samples to be generated.\n", | |||
(static_cast<float>(t_off - t_on)) / CLOCKS_PER_SEC, samps); | |||
} | |||
#endif | |||
}; |
@@ -1,119 +0,0 @@ | |||
/* | |||
ZynAddSubFX - a software synthesizer | |||
PluginTest.h - CxxTest for embedding zyn | |||
Copyright (C) 2013-2013 Mark McCurry | |||
Authors: 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 <cmath> | |||
#include <cstdlib> | |||
#include <iostream> | |||
#include <fstream> | |||
#include <string> | |||
#include "../Misc/Master.h" | |||
#include "../Misc/Util.h" | |||
#include "../globals.h" | |||
SYNTH_T *synth; | |||
using namespace std; | |||
char *instance_name=(char*)""; | |||
class PluginTest:public CxxTest::TestSuite | |||
{ | |||
public: | |||
void setUp() { | |||
synth = new SYNTH_T; | |||
synth->buffersize = 256; | |||
synth->samplerate = 48000; | |||
synth->alias(); | |||
outL = new float[1024]; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
outL[i] = 0.0f; | |||
outR = new float[1024]; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
outR[i] = 0.0f; | |||
//next the bad global variables that for some reason have not been properly placed in some | |||
//initialization routine, but rather exist as cryptic oneliners in main.cpp: | |||
denormalkillbuf = new float[synth->buffersize]; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
denormalkillbuf[i] = 0; | |||
for(int i = 0; i < 16; ++i) | |||
master[i] = new Master(); | |||
} | |||
void tearDown() { | |||
for(int i = 0; i < 16; ++i) | |||
delete master[i]; | |||
delete[] outL; | |||
delete[] outR; | |||
delete synth; | |||
} | |||
void testInit() { | |||
for(int x=0; x<100; ++x) | |||
for(int i=0; i<16; ++i) | |||
master[i]->GetAudioOutSamples(rand()%1025, | |||
synth->samplerate, outL, outR); | |||
} | |||
void testPanic() | |||
{ | |||
master[0]->setController(0, 0x64, 0); | |||
master[0]->noteOn(0,64,64); | |||
master[0]->AudioOut(outL, outR); | |||
float sum = 0.0f; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
sum += fabs(outL[i]); | |||
TS_ASSERT_LESS_THAN(0.1f, sum); | |||
} | |||
string loadfile(string fname) const | |||
{ | |||
std::ifstream t(fname.c_str()); | |||
std::string str((std::istreambuf_iterator<char>(t)), | |||
std::istreambuf_iterator<char>()); | |||
return str; | |||
} | |||
void testLoadSave(void) | |||
{ | |||
const string fname = string(SOURCE_DIR) + "/guitar-adnote.xmz"; | |||
const string fdata = string("\n") + loadfile(fname); | |||
char *result = NULL; | |||
master[0]->putalldata((char*)fdata.c_str(), fdata.length()); | |||
int res = master[0]->getalldata(&result); | |||
TS_ASSERT_EQUALS(fdata.length()+1, res); | |||
TS_ASSERT(fdata == result); | |||
} | |||
private: | |||
float *outR, *outL; | |||
Master *master[16]; | |||
}; |
@@ -1,41 +0,0 @@ | |||
/* | |||
ZynAddSubFX - a software synthesizer | |||
RandTest.h - CxxTest for Pseudo-Random Number Generator | |||
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 "../Misc/Util.h" | |||
SYNTH_T *synth; | |||
#include <cstdlib> | |||
#include <cstdio> | |||
#include <cxxtest/TestSuite.h> | |||
class RandTest:public CxxTest::TestSuite | |||
{ | |||
public: | |||
void testPRNG(void) { | |||
//verify RND returns expected pattern when unseeded | |||
TS_ASSERT_DELTA(RND, 0.607781, 0.00001); | |||
TS_ASSERT_DELTA(RND, 0.591761, 0.00001); | |||
TS_ASSERT_DELTA(RND, 0.186133, 0.00001); | |||
TS_ASSERT_DELTA(RND, 0.286319, 0.00001); | |||
TS_ASSERT_DELTA(RND, 0.511766, 0.00001); | |||
} | |||
}; |
@@ -1,183 +0,0 @@ | |||
/* | |||
ZynAddSubFX - a software synthesizer | |||
AdNoteTest.h - CxxTest for Synth/SUBnote | |||
Copyright (C) 2009-2011 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 | |||
*/ | |||
//Based Upon AdNoteTest.h | |||
#include <cxxtest/TestSuite.h> | |||
#include <iostream> | |||
#include <fstream> | |||
#include <ctime> | |||
#include <string> | |||
#include "../Misc/Master.h" | |||
#include "../Misc/Util.h" | |||
#include "../Synth/SUBnote.h" | |||
#include "../Params/Presets.h" | |||
#include "../globals.h" | |||
SYNTH_T *synth; | |||
using namespace std; | |||
class SubNoteTest:public CxxTest::TestSuite | |||
{ | |||
public: | |||
SUBnote *note; | |||
Master *master; | |||
Controller *controller; | |||
unsigned char testnote; | |||
float *outR, *outL; | |||
void setUp() { | |||
synth = new SYNTH_T; | |||
//First the sensible settings and variables that have to be set: | |||
synth->buffersize = 256; | |||
outL = new float[synth->buffersize]; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
*(outL + i) = 0; | |||
outR = new float[synth->buffersize]; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
*(outR + i) = 0; | |||
//next the bad global variables that for some reason have not been properly placed in some | |||
//initialization routine, but rather exist as cryptic oneliners in main.cpp: | |||
denormalkillbuf = new float[synth->buffersize]; | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
denormalkillbuf[i] = 0; | |||
//prepare the default settings | |||
SUBnoteParameters *defaultPreset = new SUBnoteParameters(); | |||
XMLwrapper *wrap = new XMLwrapper(); | |||
wrap->loadXMLfile(string(SOURCE_DIR) | |||
+ string("/guitar-adnote.xmz")); | |||
TS_ASSERT(wrap->enterbranch("MASTER")); | |||
TS_ASSERT(wrap->enterbranch("PART", 1)); | |||
TS_ASSERT(wrap->enterbranch("INSTRUMENT")); | |||
TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT")); | |||
TS_ASSERT(wrap->enterbranch("INSTRUMENT_KIT_ITEM", 0)); | |||
TS_ASSERT(wrap->enterbranch("SUB_SYNTH_PARAMETERS")); | |||
defaultPreset->getfromXML(wrap); | |||
controller = new Controller(); | |||
//lets go with.... 50! as a nice note | |||
testnote = 50; | |||
float freq = 440.0f * powf(2.0f, (testnote - 69.0f) / 12.0f); | |||
note = new SUBnote(defaultPreset, | |||
controller, | |||
freq, | |||
120, | |||
0, | |||
testnote, | |||
false); | |||
delete wrap; | |||
delete defaultPreset; | |||
} | |||
void willNoteBeRunButIsHereForLinkingReasonsHowsThisForCamelCaseEh() | |||
{ | |||
master = new Master(); | |||
} | |||
void tearDown() { | |||
delete controller; | |||
delete note; | |||
delete [] outL; | |||
delete [] outR; | |||
delete [] denormalkillbuf; | |||
clearTmpBuffers(); | |||
delete synth; | |||
} | |||
void testDefaults() { | |||
//Note: if these tests fail it is due to the relationship between | |||
//global.h::RND and SUBnote.cpp | |||
int sampleCount = 0; | |||
//#define WRITE_OUTPUT | |||
#ifdef WRITE_OUTPUT | |||
ofstream file("subnoteout", ios::out); | |||
#endif | |||
note->noteout(outL, outR); | |||
#ifdef WRITE_OUTPUT | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
file << outL[i] << std::endl; | |||
#endif | |||
sampleCount += synth->buffersize; | |||
TS_ASSERT_DELTA(outL[255], 0.0000f, 0.0001f); | |||
note->relasekey(); | |||
note->noteout(outL, outR); | |||
sampleCount += synth->buffersize; | |||
TS_ASSERT_DELTA(outL[255], 0.0016f, 0.0001f); | |||
note->noteout(outL, outR); | |||
sampleCount += synth->buffersize; | |||
TS_ASSERT_DELTA(outL[255], -0.0000f, 0.0001f); | |||
note->noteout(outL, outR); | |||
sampleCount += synth->buffersize; | |||
TS_ASSERT_DELTA(outL[255], -0.0013f, 0.0001f); | |||
note->noteout(outL, outR); | |||
sampleCount += synth->buffersize; | |||
TS_ASSERT_DELTA(outL[255], -0.0002f, 0.0001f); | |||
while(!note->finished()) { | |||
note->noteout(outL, outR); | |||
#ifdef WRITE_OUTPUT | |||
for(int i = 0; i < synth->buffersize; ++i) | |||
file << outL[i] << std::endl; | |||
#endif | |||
sampleCount += synth->buffersize; | |||
} | |||
#ifdef WRITE_OUTPUT | |||
file.close(); | |||
#endif | |||
TS_ASSERT_EQUALS(sampleCount, 2304); | |||
} | |||
#define OUTPUT_PROFILE | |||
#ifdef OUTPUT_PROFILE | |||
void testSpeed() { | |||
const int samps = 15000; | |||
int t_on = clock(); // timer before calling func | |||
for(int i = 0; i < samps; ++i) | |||
note->noteout(outL, outR); | |||
int t_off = clock(); // timer when func returns | |||
printf("SubNoteTest: %f seconds for %d Samples to be generated.\n", | |||
(static_cast<float>(t_off - t_on)) / CLOCKS_PER_SEC, samps); | |||
} | |||
#endif | |||
}; |
@@ -1,70 +0,0 @@ | |||
/* | |||
ZynAddSubFX - a software synthesizer | |||
XMLwrapperTest.h - CxxTest for Misc/XMLwrapper | |||
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 "../Misc/XMLwrapper.h" | |||
#include <string> | |||
#include "../globals.h" | |||
SYNTH_T *synth; | |||
using namespace std; | |||
class XMLwrapperTest:public CxxTest::TestSuite | |||
{ | |||
public: | |||
void setUp() { | |||
xmla = new XMLwrapper; | |||
xmlb = new XMLwrapper; | |||
} | |||
void testAddPar() { | |||
xmla->addpar("my Pa*_ramet@er", 75); | |||
TS_ASSERT_EQUALS(xmla->getpar("my Pa*_ramet@er", 0, -200, 200), 75); | |||
} | |||
//here to verify that no leaks occur | |||
void testLoad() { | |||
string location = string(SOURCE_DIR) + string( | |||
"/Tests/guitar-adnote.xmz"); | |||
xmla->loadXMLfile(location); | |||
} | |||
void testAnotherLoad() | |||
{ | |||
string dat = | |||
"\n<?xml version=\"1.0f\" encoding=\"UTF-8\"?>\n\ | |||
<!DOCTYPE ZynAddSubFX-data>\n\ | |||
<ZynAddSubFX-data version-major=\"2\" version-minor=\"4\"\n\ | |||
version-revision=\"1\" ZynAddSubFX-author=\"Nasca Octavian Paul\">\n\ | |||
</ZynAddSubFX-data>\n"; | |||
xmlb->putXMLdata(dat.c_str()); | |||
} | |||
void tearDown() { | |||
delete xmla; | |||
delete xmlb; | |||
} | |||
private: | |||
XMLwrapper *xmla; | |||
XMLwrapper *xmlb; | |||
}; |