@@ -91,39 +91,41 @@ src/dist/ | |||||
*build-*Debug/ | *build-*Debug/ | ||||
*build-*Release/ | *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 | # Other | ||||
source/includes/asio/ | 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; | |||||
}; |