zynaddsubfx

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

NulEngine.cpp (2665B)


      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 
     23 NulEngine::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 
     31 void *NulEngine::_AudioThread(void *arg)
     32 {
     33     return (static_cast<NulEngine *>(arg))->AudioThread();
     34 }
     35 
     36 void *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 
     67 NulEngine::~NulEngine()
     68 {}
     69 
     70 bool NulEngine::Start()
     71 {
     72     setAudioEn(true);
     73     return getAudioEn();
     74 }
     75 
     76 void NulEngine::Stop()
     77 {
     78     setAudioEn(false);
     79 }
     80 
     81 void 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 
    102 bool NulEngine::getAudioEn() const
    103 {
    104     return pThread;
    105 }
    106 
    107 }