Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
2.6KB

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