1 /* 2 ZynAddSubFX - a software synthesizer 3 4 OSSaudiooutput.C - Audio output for Open Sound System 5 Copyright (C) 2002-2005 Nasca Octavian Paul 6 Author: Nasca Octavian Paul 7 8 This program is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public License 10 as published by the Free Software Foundation; either version 2 11 of the License, or (at your option) any later version. 12 */ 13 14 #include "NulEngine.h" 15 #include "../globals.h" 16 #include "../Misc/Util.h" 17 18 #include <iostream> 19 using namespace std; 20 21 namespace zyn { 22 NulEngine(const SYNTH_T & synth_)23NulEngine::NulEngine(const SYNTH_T &synth_) 24 :AudioOut(synth_), pThread(NULL) 25 { 26 name = "NULL"; 27 playing_until.tv_sec = 0; 28 playing_until.tv_usec = 0; 29 } 30 _AudioThread(void * arg)31void *NulEngine::_AudioThread(void *arg) 32 { 33 return (static_cast<NulEngine *>(arg))->AudioThread(); 34 } 35 AudioThread()36void *NulEngine::AudioThread() 37 { 38 while(pThread) { 39 getNext(); 40 41 struct timeval now; 42 int remaining = 0; 43 gettimeofday(&now, NULL); 44 if((playing_until.tv_usec == 0) && (playing_until.tv_sec == 0)) { 45 playing_until.tv_usec = now.tv_usec; 46 playing_until.tv_sec = now.tv_sec; 47 } 48 else { 49 remaining = (playing_until.tv_usec - now.tv_usec) 50 + (playing_until.tv_sec - now.tv_sec) * 1000000; 51 if(remaining > 10000) //Don't sleep() less than 10ms. 52 //This will add latency... 53 os_usleep(remaining - 10000); 54 if(remaining < 0) 55 cerr << "WARNING - too late" << endl; 56 } 57 playing_until.tv_usec += synth.buffersize * 1000000 58 / synth.samplerate; 59 if(remaining < 0) 60 playing_until.tv_usec -= remaining; 61 playing_until.tv_sec += playing_until.tv_usec / 1000000; 62 playing_until.tv_usec %= 1000000; 63 } 64 return NULL; 65 } 66 ~NulEngine()67NulEngine::~NulEngine() 68 {} 69 Start()70bool NulEngine::Start() 71 { 72 setAudioEn(true); 73 return getAudioEn(); 74 } 75 Stop()76void NulEngine::Stop() 77 { 78 setAudioEn(false); 79 } 80 setAudioEn(bool nval)81void NulEngine::setAudioEn(bool nval) 82 { 83 if(nval) { 84 if(!getAudioEn()) { 85 pthread_t *thread = new pthread_t; 86 pthread_attr_t attr; 87 pthread_attr_init(&attr); 88 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 89 pThread = thread; 90 pthread_create(pThread, &attr, _AudioThread, this); 91 } 92 } 93 else 94 if(getAudioEn()) { 95 pthread_t *thread = pThread; 96 pThread = NULL; 97 pthread_join(*thread, NULL); 98 delete thread; 99 } 100 } 101 getAudioEn() const102bool NulEngine::getAudioEn() const 103 { 104 return pThread; 105 } 106 107 } 108