zynaddsubfx

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

commit 1846501ba96d1ed09d29500de114396cee53c948
parent 9e5d641e3d7c361f05ad6baf7f5de5805a91aa5a
Author: fundamental <mark.d.mccurry@gmail.com>
Date:   Fri, 13 Nov 2009 08:40:51 -0500

Nio: Changed sample requesting strategy

Diffstat:
Msrc/Nio/OssEngine.cpp | 76++++++++++++++++++++++++++++++++--------------------------------------------
Msrc/Nio/OutMgr.cpp | 24++++++++++++++++++++++--
Msrc/Nio/OutMgr.h | 5+++++
3 files changed, 59 insertions(+), 46 deletions(-)

diff --git a/src/Nio/OssEngine.cpp b/src/Nio/OssEngine.cpp @@ -76,8 +76,8 @@ void OssEngine::out(const Stereo<Sample> smps) { pthread_mutex_lock(&outBuf_mutex); outBuf.push(smps); - if(outBuf.size()<10) - manager->requestSamples(); + //if(outBuf.size()<) + // manager->requestSamples(); pthread_cond_signal(&outBuf_cv); pthread_mutex_unlock(&outBuf_mutex); } @@ -90,10 +90,7 @@ void *OssEngine::_AudioThread(void *arg) void *OssEngine::AudioThread() { - manager->requestSamples(); - manager->requestSamples(); - manager->requestSamples(); - manager->requestSamples(); + //get some initial samples manager->requestSamples(); manager->requestSamples(); manager->requestSamples(); @@ -107,9 +104,6 @@ void *OssEngine::AudioThread() } return NULL; } -//void OssEngine::out(const Stereo<Sample> smps) -//{ -// OSSout(smps.l(). /* * Output the samples to the soundcard @@ -117,32 +111,32 @@ void *OssEngine::AudioThread() */ void OssEngine::OSSout(const REALTYPE *smp_left, const REALTYPE *smp_right) { - outOut(smp_left,smp_right); - return; -// if(snd_handle < 0) { //output could not be opened - struct timeval now; - int remaining = 0; - gettimeofday(&now, NULL); - if((playing_until.tv_usec == 0) && (playing_until.tv_sec == 0)) { - playing_until.tv_usec = now.tv_usec; - playing_until.tv_sec = now.tv_sec; - } - else { - remaining = (playing_until.tv_usec - now.tv_usec) - + (playing_until.tv_sec - now.tv_sec) * 1000000; - if(remaining > 10000) //Don't sleep() less than 10ms. - //This will add latency... - usleep(remaining - 10000); + if(snd_handle < 0) { //output could not be opened + struct timeval now; + int remaining = 0; + gettimeofday(&now, NULL); + if((playing_until.tv_usec == 0) && (playing_until.tv_sec == 0)) { + playing_until.tv_usec = now.tv_usec; + playing_until.tv_sec = now.tv_sec; + } + else { + remaining = (playing_until.tv_usec - now.tv_usec) + + (playing_until.tv_sec - now.tv_sec) * 1000000; + if(remaining > 10000) //Don't sleep() less than 10ms. + //This will add latency... + usleep(remaining - 10000); + if(remaining < 0) + cerr << "WARNING - too late" << endl; + } + playing_until.tv_usec += SOUND_BUFFER_SIZE * 1000000 / SAMPLE_RATE; if(remaining < 0) - cerr << "WARNING - too late" << endl; + playing_until.tv_usec -= remaining; + playing_until.tv_sec += playing_until.tv_usec / 1000000; + playing_until.tv_usec %= 1000000; + return; } - playing_until.tv_usec += SOUND_BUFFER_SIZE * 1000000 / SAMPLE_RATE; - if(remaining < 0) - playing_until.tv_usec -= remaining; - playing_until.tv_sec += playing_until.tv_usec / 1000000; - playing_until.tv_usec %= 1000000; + outOut(smp_left,smp_right); return; -// } } void OssEngine::outOut(const REALTYPE *smp_left, const REALTYPE *smp_right) @@ -185,25 +179,19 @@ const Stereo<Sample> OssEngine::getNext() pthread_mutex_unlock(&outBuf_mutex); if(isEmpty)//fetch samples if possible { - if(true)//FIXME care about locking state later on - //mgr.requestSamples()!=-1)//samples are being prepared - { + if(manager->getRunning()<1) manager->requestSamples(); - //pthread_mutex_lock(&outBuf_mutex); - //pthread_cond_wait(&outBuf_cv, &outBuf_mutex); - //ans = outBuf.front(); - //outBuf.pop(); - //pthread_mutex_unlock(&outBuf_mutex); - return current; - } + cout << "Starvation"<< endl; + return current; } else { pthread_mutex_lock(&outBuf_mutex); - if(outBuf.size()<10) - manager->requestSamples(); ans = outBuf.front(); outBuf.pop(); + if(outBuf.size()+manager->getRunning()==0) + manager->requestSamples(); + cout << outBuf.size()+manager->getRunning() << endl; pthread_mutex_unlock(&outBuf_mutex); } current=ans; diff --git a/src/Nio/OutMgr.cpp b/src/Nio/OutMgr.cpp @@ -48,11 +48,18 @@ void *OutMgr::outputThread() pthread_mutex_unlock(&mutex); running=true; init=true; + bool doWait; while(running){ //cout << "OutMgr THREAD" << endl; + pthread_mutex_lock(&request_m); + doWait = numRequests--<1; + //cout << numRequests << endl; + pthread_mutex_unlock(&request_m); pthread_mutex_lock(&processing); - //cout << "OutMgr wait" << endl; - pthread_cond_wait(&needsProcess, &processing); + if(doWait) { + //cout << "OutMgr wait" << endl; + pthread_cond_wait(&needsProcess, &processing); + } //make master use samples //cout << "have some food" << endl; pthread_mutex_lock(&(master->mutex)); @@ -101,13 +108,26 @@ int OutMgr::remove(AudioOut *out) pthread_mutex_unlock(&mutex); } +int OutMgr::getRunning() +{ + int tmp; + pthread_mutex_lock(&request_m); + tmp=numRequests; + pthread_mutex_unlock(&request_m); + return tmp; +} + int OutMgr::requestSamples() { //cout << "me hungry" << endl; + pthread_mutex_lock(&request_m); + ++numRequests; + pthread_mutex_unlock(&request_m); pthread_mutex_lock(&processing); pthread_cond_signal(&needsProcess); //cout << "me start fire" << endl; pthread_mutex_unlock(&processing); + return 0; } //int OutMgr::enable(outputDriver out); diff --git a/src/Nio/OutMgr.h b/src/Nio/OutMgr.h @@ -34,6 +34,8 @@ class OutMgr /**Request a new set of samples * @return -1 for locking issues 0 for valid request*/ int requestSamples(); + /**Return the number of building samples*/ + int getRunning(); /**Enables one instance of given driver*/ //int enable(outputDriver out); /**Disables all instances of given driver*/ @@ -52,6 +54,9 @@ class OutMgr pthread_t outThread; pthread_cond_t needsProcess; + /**for num requests*/ + pthread_mutex_t request_m; + int numRequests; /**for closing*/ pthread_mutex_t close_m; pthread_cond_t close_cond;