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:
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;