zynaddsubfx

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

commit 81c307a3e56b2cf285d545fd46c0c1ab3e6b3d60
parent 23362254981dfd2d3dc40828350675807673dd5a
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Sun, 14 Mar 2010 13:56:22 -0400

Nio: Redesign to reduce threading and locking

 -Threads have been reduce, so that only 2 threads will be able to access the
  main allotment of data (UI and Output thread)
 -OutMgr, InMgr, and AudioOut have been reworked to restructure
 -This work is highly experimental and needs a good bit of debugging to stop it
 from exploding

Diffstat:
Msrc/CMakeLists.txt | 16----------------
Msrc/Nio/AudioOut.cpp | 125+++++++++----------------------------------------------------------------------
Msrc/Nio/AudioOut.h | 5++---
Msrc/Nio/CMakeLists.txt | 11++++++++++-
Msrc/Nio/InMgr.cpp | 54++++++++++++++++--------------------------------------
Msrc/Nio/InMgr.h | 10++++------
Dsrc/Nio/MidiEvent.cpp | 27---------------------------
Dsrc/Nio/MidiEvent.h | 34----------------------------------
Msrc/Nio/OutMgr.cpp | 196++++++++++++++++++++++++++++++++++---------------------------------------------
Msrc/Nio/OutMgr.h | 49+++++++++++++++++++++++++------------------------
Msrc/main.cpp | 1-
11 files changed, 156 insertions(+), 372 deletions(-)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt @@ -48,16 +48,6 @@ else () message(STATUS "GUI module defaulting to off") endif() -if (DefaultOutput STREQUAL alsa) - add_definitions(-DALSA_DEFAULT=1) -elseif(DefaultOutput STREQUAL oss) - add_definitions(-DOSS_DEFAULT=1) -elseif(DefaultOutput STREQUAL jack) - add_definitions(-DJACK_DEFAULT=1) -elseif(DefaultOutput STREQUAL portaudio) - add_definitions(-DPORTAUDIO_DEFAULT=1) -endif() - ########### Settings dependant code ########### # From here on, the setting variables have been prepared so concentrate @@ -89,12 +79,6 @@ if (CompileTests) ENABLE_TESTING() endif() -if(JackOutput) - include_directories(${JACK_INCLUDE_DIR}) - add_definitions(-DJACKAUDIOOUT) - set(AUDIO_LIBRARIES ${AUDIO_LIBRARIES} ${JACK_LIBRARIES}) -endif() - add_definitions(-DFFTW_VERSION_${FFTW_VERSION} -DASM_F2I_YES -g #TODO #todo put in a better location diff --git a/src/Nio/AudioOut.cpp b/src/Nio/AudioOut.cpp @@ -37,153 +37,56 @@ struct AudioOut::Data int samplerate; int bufferSize; - SafeQueue<Stereo<Sample> > outBuf; - pthread_mutex_t outBuf_mutex; - pthread_cond_t outBuf_cv; - - /**used for taking in samples with a different - * samplerate/buffersize*/ - Stereo<Sample> partialIn; - bool usePartial; Stereo<Sample> current;/**<used for xrun defence*/ - //The number of Samples that are used to buffer - //Note: there is some undetermined behavior when: - //sampleRate!=SAMPLE_RATE || bufferSize!=SOUND_BUFFER_SIZE - unsigned int buffering; - OutMgr *manager; }; AudioOut::Data::Data(OutMgr *out) :samplerate(SAMPLE_RATE),bufferSize(SOUND_BUFFER_SIZE), - outBuf(100),usePartial(false), - current(Sample(SOUND_BUFFER_SIZE,0.0)),buffering(6), - manager(out) + current(Sample(SOUND_BUFFER_SIZE,0.0)),manager(out) {} AudioOut::AudioOut(OutMgr *out) :dat(new Data(out)) -{ - pthread_mutex_init(&dat->outBuf_mutex, NULL); - pthread_cond_init(&dat->outBuf_cv, NULL); -} +{} AudioOut::~AudioOut() { - pthread_mutex_destroy(&dat->outBuf_mutex); - pthread_cond_destroy(&dat->outBuf_cv); delete dat; } -void AudioOut::out(Stereo<Sample> smps) -{ - pthread_mutex_lock(&dat->outBuf_mutex); - if(dat->samplerate != SAMPLE_RATE) { //we need to resample - smps.l().resample(SAMPLE_RATE,dat->samplerate); - smps.r().resample(SAMPLE_RATE,dat->samplerate); - } - - if(dat->usePartial) { //we have a partial to use - smps.l() = dat->partialIn.l().append(smps.l()); - smps.r() = dat->partialIn.r().append(smps.r()); - } - - if(smps.l().size() == dat->bufferSize) { //sized just right - dat->outBuf.push(smps); - dat->usePartial = false; - pthread_cond_signal(&dat->outBuf_cv); - } - else if(smps.l().size() > dat->bufferSize) { //store overflow - - while(smps.l().size() > dat->bufferSize) { - dat->outBuf.push(Stereo<Sample>(smps.l().subSample(0,dat->bufferSize), - smps.r().subSample(0,dat->bufferSize))); - smps = Stereo<Sample>(smps.l().subSample(dat->bufferSize,smps.l().size()), - smps.r().subSample(dat->bufferSize,smps.r().size())); - } - - if(smps.l().size() == dat->bufferSize) { //no partial - dat->outBuf.push(smps); - dat->usePartial = false; - } - else { //partial - dat->partialIn = smps; - dat->usePartial = true; - } - - pthread_cond_signal(&dat->outBuf_cv); - } - else { //underflow - dat->partialIn = smps; - dat->usePartial = true; - } - pthread_mutex_unlock(&dat->outBuf_mutex); -} - void AudioOut::setSamplerate(int _samplerate) { - pthread_mutex_lock(&dat->outBuf_mutex); - dat->usePartial = false; dat->samplerate = _samplerate; - dat->outBuf.clear(); - pthread_mutex_unlock(&dat->outBuf_mutex); +} +int AudioOut::getSampleRate() +{ + return dat->samplerate; } void AudioOut::setBufferSize(int _bufferSize) { - pthread_mutex_lock(&dat->outBuf_mutex); - dat->usePartial = false; dat->bufferSize = _bufferSize; - dat->outBuf.clear(); - pthread_mutex_unlock(&dat->outBuf_mutex); } +//delete me void AudioOut::bufferingSize(int nBuffering) { - dat->buffering = nBuffering; + //dat->buffering = nBuffering; } +//delete me int AudioOut::bufferingSize() { - return dat->buffering; + //return dat->buffering; } const Stereo<Sample> AudioOut::getNext(bool wait) { - const unsigned int BUFF_SIZE = dat->buffering; - Stereo<Sample> ans; - pthread_mutex_lock(&dat->outBuf_mutex); - bool isEmpty = !dat->outBuf.size(); - pthread_mutex_unlock(&dat->outBuf_mutex); - - if(isEmpty)//fetch samples if possible - { - if((unsigned int)dat->manager->getRunning() < BUFF_SIZE) - dat->manager->requestSamples(BUFF_SIZE-dat->manager->getRunning()); - if(true) - cout << "-----------------Starvation------------------"<< endl; - if(wait) - { - pthread_mutex_lock(&dat->outBuf_mutex); - pthread_cond_wait(&dat->outBuf_cv,&dat->outBuf_mutex); - pthread_mutex_unlock(&dat->outBuf_mutex); - //now the code has a sample to fetch - } - else - return dat->current; - } - - pthread_mutex_lock(&dat->outBuf_mutex); - dat->outBuf.pop(ans); - if(dat->outBuf.size()+dat->manager->getRunning()<BUFF_SIZE) - dat->manager->requestSamples(BUFF_SIZE - (dat->outBuf.size() - + dat->manager->getRunning())); - if(false) - cout << "AudioOut "<< dat->outBuf.size()<< '+' << dat->manager->getRunning() << endl; - pthread_mutex_unlock(&dat->outBuf_mutex); - - dat->current = ans; - return ans; + Stereo<REALTYPE *> tmp = sysOut->tick(dat->bufferSize); + + //stop the samples + return Stereo<Sample>(Sample(dat->bufferSize, tmp.l()), Sample(dat->bufferSize, tmp.r())); } diff --git a/src/Nio/AudioOut.h b/src/Nio/AudioOut.h @@ -34,7 +34,7 @@ class AudioOut : public virtual Engine virtual ~AudioOut(); /**Give the Driver Samples to process*/ - virtual void out(Stereo<Sample> smps); + //virtual void out(Stereo<Sample> smps); /**Sets the Sample Rate of this Output * (used for getNext()).*/ @@ -42,6 +42,7 @@ class AudioOut : public virtual Engine /**Sets the Samples required per Out of this driver * not a realtime opperation */ + int getSampleRate(); void setBufferSize(int _bufferSize); /**Sets the Frame Size for output*/ @@ -52,8 +53,6 @@ class AudioOut : public virtual Engine virtual bool getAudioEn() const=0; protected: - - void putBack(const Stereo<Sample> smp); /**Get the next sample for output. * (has nsamples sampled at a rate of samplerate)*/ const Stereo<Sample> getNext(bool wait = false); diff --git a/src/Nio/CMakeLists.txt b/src/Nio/CMakeLists.txt @@ -12,11 +12,20 @@ set(zynaddsubfx_nio_SRCS InMgr.cpp Engine.cpp EngineMgr.cpp - MidiEvent.cpp ) set(zynaddsubfx_nio_lib ) +if (DefaultOutput STREQUAL alsa) + add_definitions(-DALSA_DEFAULT=1) +elseif(DefaultOutput STREQUAL oss) + add_definitions(-DOSS_DEFAULT=1) +elseif(DefaultOutput STREQUAL jack) + add_definitions(-DJACK_DEFAULT=1) +elseif(DefaultOutput STREQUAL portaudio) + add_definitions(-DPORTAUDIO_DEFAULT=1) +endif() + if(JackEnable) include_directories(${JACK_INCLUDE_DIR}) list(APPEND zynaddsubfx_nio_SRCS JackEngine.cpp) diff --git a/src/Nio/InMgr.cpp b/src/Nio/InMgr.cpp @@ -26,52 +26,33 @@ MidiEvent::MidiEvent() {} InMgr::InMgr(Master *_master) - :queue(100), enabled(false), master(_master) + :queue(100), master(_master) { + current = NULL; sem_init(&work, PTHREAD_PROCESS_PRIVATE, 0); } InMgr::~InMgr() { //lets stop the consumer thread - enabled = false; - sem_post(&work); - pthread_join(inThread, NULL); - sem_destroy(&work); } void InMgr::putEvent(MidiEvent ev) { if(queue.push(ev)) //check for error - cout << "Error, Midi Ringbuffer is FULL" << endl; + cerr << "ERROR: Midi Ringbuffer is FULL" << endl; else sem_post(&work); } -void *_inputThread(void *arg) -{ - return static_cast<InMgr *>(arg)->inputThread(); -} - -void InMgr::run() -{ - enabled = true; - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - pthread_create(&inThread, &attr, _inputThread, this); -} - -void *InMgr::inputThread() +void InMgr::flush() { MidiEvent ev; - while(enabled()) { - sem_wait(&work); + while(!sem_trywait(&work)) { queue.pop(ev); cout << ev << endl; - pthread_mutex_lock(&master->mutex); if(M_NOTE == ev.type) { dump.dumpnote(ev.channel, ev.num, ev.value); @@ -84,9 +65,7 @@ void *InMgr::inputThread() dump.dumpcontroller(ev.channel, ev.num, ev.value); master->setController(ev.channel, ev.num, ev.value); } - pthread_mutex_unlock(&master->mutex); } - return NULL; } bool InMgr::setSource(string name) @@ -95,29 +74,28 @@ bool InMgr::setSource(string name) for(list<Engine*>::iterator itr = sysEngine->engines.begin(); itr != sysEngine->engines.end(); ++itr) { MidiIn *in = dynamic_cast<MidiIn *>(*itr); - if(in) { - if(in->name == name) + if(in && in->name == name) { src = in; - else - in->setMidiEn(false); + break; } } if(!src) return false; - src->setMidiEn(true); + if(current) + current->setMidiEn(false); + current = src; + current->setMidiEn(true); - return src->getMidiEn(); + return current->getMidiEn(); } string InMgr::getSource() const { - for(list<Engine*>::iterator itr = sysEngine->engines.begin(); - itr != sysEngine->engines.end(); ++itr) { - MidiIn *in = dynamic_cast<MidiIn *>(*itr); - if(in && in->getMidiEn()) - return in->name; - } + if(current) + return current->name; + else + return "ERROR"; } diff --git a/src/Nio/InMgr.h b/src/Nio/InMgr.h @@ -22,6 +22,7 @@ struct MidiEvent }; class Master; +class MidiIn; //super simple class to manage the inputs class InMgr { @@ -31,10 +32,8 @@ class InMgr void putEvent(MidiEvent ev); - //run the InMgr - void run(); - - void *inputThread(); + /**Flush the Midi Queue*/ + void flush(); bool setSource(std::string name); @@ -43,8 +42,7 @@ class InMgr private: SafeQueue<MidiEvent> queue; sem_t work; - Atomic<bool> enabled; - pthread_t inThread; + MidiIn *current; /**the link to the rest of zyn*/ Master *master; diff --git a/src/Nio/MidiEvent.cpp b/src/Nio/MidiEvent.cpp @@ -1,27 +0,0 @@ -#include "MidiEvent.h" - -using namespace std; - -MidiNote::MidiNote(char _note, char _channel, char _velocity) - :note(_note), channel(_channel), velocity(_velocity) -{}; - -ostream &operator<<(ostream &out, const MidiNote& note) -{ - out << "MidiNote: note(" << (int)note.note << ")\n" - << " channel(" << (int)note.channel << ")\n" - << " velocity(" << (int)note.velocity << ")"; - return out; -} - -MidiCtl::MidiCtl(char _controller, char _channel, char _value) - :controller(_controller), channel(_channel), value(_value) -{}; - -ostream &operator<<(ostream &out, const MidiCtl &ctl) -{ - out << "MidiCtl: controller(" << (int)ctl.controller << ")\n" - << " channel(" << (int)ctl.channel << ")\n" - << " value(" << (int)ctl.value << ")"; - return out; -} diff --git a/src/Nio/MidiEvent.h b/src/Nio/MidiEvent.h @@ -1,34 +0,0 @@ - -#ifndef MIDI_EVENT -#define MIDI_EVENT - -#include <iostream> - -/**A class to generalize midi events*/ -struct MidiEvent -{ - MidiEvent(){}; -}; - -struct MidiNote : public MidiEvent -{ - MidiNote(char _note, char _channel, char _velocity = 0); - - char note; - char channel; - char velocity; -}; - -std::ostream &operator<<(std::ostream &out, const MidiNote &midi); - -struct MidiCtl : public MidiEvent -{ - MidiCtl(char _controller, char _channel, char _value); - - char controller; - char channel; - char value; -}; - -std::ostream &operator<<(std::ostream &out, const MidiCtl &ctl); -#endif diff --git a/src/Nio/OutMgr.cpp b/src/Nio/OutMgr.cpp @@ -4,6 +4,7 @@ #include "AudioOut.h" #include "Engine.h" #include "EngineMgr.h" +#include "InMgr.h" #include "../Misc/Master.h" #include "../Misc/Util.h"//for set_realtime() @@ -12,14 +13,12 @@ using namespace std; OutMgr *sysOut; OutMgr::OutMgr(Master *nmaster) - :running(false) + :priBuf(new REALTYPE[4096],new REALTYPE[4096]),priBuffCurrent(priBuf) { + currentOut = NULL; + stales = 0; master = nmaster; - //initialize mutex - pthread_mutex_init(&mutex, NULL); - sem_init(&requested, PTHREAD_PROCESS_PRIVATE, 0); - //init samples outr = new REALTYPE[SOUND_BUFFER_SIZE]; outl = new REALTYPE[SOUND_BUFFER_SIZE]; @@ -27,15 +26,11 @@ OutMgr::OutMgr(Master *nmaster) OutMgr::~OutMgr() { - running = false; - sem_post(&requested); - - pthread_join(outThread, NULL); - - pthread_mutex_destroy(&mutex); - sem_destroy(&requested); + delete [] outr; + delete [] outl; } +#if 0 //reenable to get secondary inputs working void OutMgr::add(AudioOut *driver) { pthread_mutex_lock(&mutex); @@ -56,33 +51,36 @@ void OutMgr::remove(AudioOut *out) Sample(SOUND_BUFFER_SIZE, 0.0))); pthread_mutex_unlock(&mutex); } - -void OutMgr::requestSamples(unsigned int n) -{ - for(unsigned int i = 0; i < n; ++i) - sem_post(&requested); -} - -int OutMgr::getRunning() -{ - int tmp; - sem_getvalue(&requested, &tmp); - if(tmp < 0) - tmp = 0; - return tmp; -} - -void *_outputThread(void *arg) -{ - return (static_cast<OutMgr*>(arg))->outputThread(); -} - -void OutMgr::run() +#endif + +/* Sequence of a tick + * 1) lets see if we have any stuff to do via midi + * 2) Lets do that stuff + * 3) Lets see if the event queue has anything for us + * 4) Lets empty that out + * 5) Lets remove old/stale samples + * 6) Lets see if we need to generate samples + * 7) Lets generate some + * 8) Lets return those samples to the primary and secondary outputs + * 9) Lets wait for another tick + */ +const Stereo<REALTYPE *> OutMgr::tick(unsigned int frameSize) { - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - pthread_create(&outThread, &attr, _outputThread, this); + pthread_mutex_lock(&(master->mutex)); + sysIn->flush(); + pthread_mutex_unlock(&(master->mutex)); + //SysEv->execute(); + removeStaleSmps(); + while(frameSize > storedSmps()) { + {//get more stuff + pthread_mutex_lock(&(master->mutex)); + master->AudioOut(outl, outr); + pthread_mutex_unlock(&(master->mutex)); + addSmps(outl,outr); + } + } + makeStale(frameSize); + return priBuf; } AudioOut *OutMgr::getOut(string name) @@ -92,20 +90,10 @@ AudioOut *OutMgr::getOut(string name) string OutMgr::getDriver() const { - for(list<Engine*>::iterator itr = sysEngine->engines.begin(); - itr != sysEngine->engines.end(); ++itr) { - AudioOut *out = dynamic_cast<AudioOut *>(*itr); - if(out && out->getAudioEn()) - return out->name; - } -} - -bool OutMgr::setDriver(string name) -{ - return false; + return currentOut->name; } -void *OutMgr::outputThread() +void OutMgr::run() { defaultOut = dynamic_cast<AudioOut *>(sysEngine->defaultEng); if(!defaultOut) { @@ -115,57 +103,15 @@ void *OutMgr::outputThread() defaultOut = dynamic_cast<AudioOut *>(sysEngine->getEng("NULL")); } - set_realtime(); //open up the default output - if(!defaultOut->Start())//there should be a better failsafe + if(!defaultOut->Start()) { cerr << "ERROR: The default Audio Output Failed to Open!" << endl; - - - //setup - running = true; - init = true; - while(running()) { - - if(false) { - cout << "Status: "; - pthread_mutex_lock(&mutex); - cout << unmanagedOuts.size(); - pthread_mutex_unlock(&mutex); - cout << " outs, "; - cout << getRunning(); - cout << " requests" << endl; - } - - - pthread_mutex_lock(&(master->mutex)); - master->AudioOut(outl,outr); - pthread_mutex_unlock(&(master->mutex)); - - smps = Stereo<Sample>(Sample(SOUND_BUFFER_SIZE, outl), - Sample(SOUND_BUFFER_SIZE, outr)); - - //this mutex might be redundant - pthread_mutex_lock(&mutex); - - for(list<Engine*>::iterator itr = sysEngine->engines.begin(); - itr != sysEngine->engines.end(); ++itr) { - AudioOut *out = dynamic_cast<AudioOut *>(*itr); - if(out && out->getAudioEn()) - out->out(smps); - } - - for(list<AudioOut*>::iterator itr = unmanagedOuts.begin(); - itr != unmanagedOuts.end(); ++itr) { - (*itr)->out(smps); - } - - pthread_mutex_unlock(&mutex); - - //wait for next run - sem_wait(&requested); + currentOut = defaultOut; + } + else { + currentOut = defaultOut = dynamic_cast<AudioOut *>(sysEngine->getEng("NULL")); + defaultOut->Start(); } - pthread_exit(NULL); - return NULL; } bool OutMgr::setSink(string name) @@ -174,29 +120,57 @@ bool OutMgr::setSink(string name) for(list<Engine*>::iterator itr = sysEngine->engines.begin(); itr != sysEngine->engines.end(); ++itr) { AudioOut *out = dynamic_cast<AudioOut *>(*itr); - if(out) { - if(out->name == name) - sink = out; - else - out->setAudioEn(false); - } + if(out && out->name == name) + sink = out; } if(!sink) return false; - sink->setAudioEn(true); + if(currentOut) + currentOut->setAudioEn(false); - return sink->getAudioEn(); + currentOut = sink; + currentOut->setAudioEn(true); + return currentOut->getAudioEn(); } string OutMgr::getSink() const { - for(list<Engine*>::iterator itr = sysEngine->engines.begin(); - itr != sysEngine->engines.end(); ++itr) { - AudioOut *out = dynamic_cast<AudioOut *>(*itr); - if(out && out->getAudioEn()) - return out->name; + if(currentOut) + return currentOut->name; + else { + cerr << "BUG: No current output in OutMgr " << __LINE__ << endl; + return "ERROR"; } } +void OutMgr::addSmps(REALTYPE *l, REALTYPE *r) +{ + Stereo<Sample> smps(Sample(SOUND_BUFFER_SIZE, l), Sample(SOUND_BUFFER_SIZE, r)); + + if(currentOut->getSampleRate() != SAMPLE_RATE) { //we need to resample + smps.l().resample(SAMPLE_RATE,currentOut->getSampleRate()); + smps.r().resample(SAMPLE_RATE,currentOut->getSampleRate()); + } + + memcpy(priBuffCurrent.l(), smps.l().c_buf(), SOUND_BUFFER_SIZE); + memcpy(priBuffCurrent.r(), smps.r().c_buf(), SOUND_BUFFER_SIZE); + priBuffCurrent.l() += SOUND_BUFFER_SIZE; + priBuffCurrent.r() += SOUND_BUFFER_SIZE; +} + +void OutMgr::makeStale(unsigned int size) +{ + stales = size; +} + +void OutMgr::removeStaleSmps() +{ + int toShift = priBuf.l() + stales - priBuffCurrent.l(); + memmove(priBuf.l(), priBuf.l()+stales, toShift); + memmove(priBuf.r(), priBuf.r()+stales, toShift); + priBuffCurrent.l() = toShift + priBuf.l(); + priBuffCurrent.r() = toShift + priBuf.r(); +} + diff --git a/src/Nio/OutMgr.h b/src/Nio/OutMgr.h @@ -20,63 +20,64 @@ class OutMgr OutMgr(Master *nmaster); ~OutMgr(); - /**Adds audio output out. - * @return -1 for error 0 otherwise*/ - void add(AudioOut *out); - /**Removes given audio output engine - * @return -1 for error 0 otherwise*/ - void remove(AudioOut *out); + /**Adds audio output out.*/ + void add(AudioOut *out){}; + /**Removes given audio output engine*/ + void remove(AudioOut *out){}; + + /**Execute a tick*/ + const Stereo<REALTYPE *> tick(unsigned int frameSize); /**Request a new set of samples * @param n number of requested samples (defaults to 1) * @return -1 for locking issues 0 for valid request*/ void requestSamples(unsigned int n=1); - /**Return the number of building samples*/ - int getRunning(); - - void run(); - /**Gets requested driver * @param name case unsensitive name of driver * @return pointer to Audio Out or NULL */ AudioOut *getOut(std::string name); - /**Sets the running driver by name - * @return true for successful insertion*/ - bool setDriver(std::string name); - /**Gets the name of the first running driver * @return if no running output, "" is returned */ std::string getDriver() const; - void *outputThread(); - + void run(); + bool setSink(std::string name); std::string getSink() const; private: - Atomic<bool> running; - bool init; - + void addSmps(REALTYPE *l, REALTYPE *r); + int storedSmps() const {return priBuffCurrent.l() - priBuf.l();}; + void makeStale(unsigned int size); + void removeStaleSmps(); //should hold outputs here that exist for the life of the OutMgr AudioOut *defaultOut;/**<The default output*/ + AudioOut *currentOut; + //should hold short lived, externally controlled Outputs (eg WavEngine) //[needs mutex] - std::list<AudioOut *> unmanagedOuts; - mutable pthread_mutex_t mutex; - - pthread_t outThread; + //std::list<AudioOut *> unmanagedOuts; + //mutable pthread_mutex_t mutex; sem_t requested; + //information on current active primary driver + //sample rate + //frame size + /**Buffer*/ + Stereo<REALTYPE *> priBuf; //buffer for primary drivers + Stereo<REALTYPE *> priBuffCurrent; //current array accessor Stereo<Sample> smps; REALTYPE *outl; REALTYPE *outr; Master *master; + + int stales; }; extern OutMgr *sysOut; diff --git a/src/main.cpp b/src/main.cpp @@ -205,7 +205,6 @@ void initprogram() //Run the system sysOut->run(); - sysIn->run(); #warning remove welcome message when system is out of beta cout << "\nThanks for using the Nio system :)" << endl;