|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711 |
- /*
- 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;
- }
|