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.

108 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 "../Misc/Util.h"
  14. #include <iostream>
  15. using namespace std;
  16. namespace zyncarla {
  17. NulEngine::NulEngine(const SYNTH_T &synth_)
  18. :AudioOut(synth_), pThread(NULL)
  19. {
  20. name = "NULL";
  21. playing_until.tv_sec = 0;
  22. playing_until.tv_usec = 0;
  23. }
  24. void *NulEngine::_AudioThread(void *arg)
  25. {
  26. return (static_cast<NulEngine *>(arg))->AudioThread();
  27. }
  28. void *NulEngine::AudioThread()
  29. {
  30. while(pThread) {
  31. getNext();
  32. struct timeval now;
  33. int remaining = 0;
  34. gettimeofday(&now, NULL);
  35. if((playing_until.tv_usec == 0) && (playing_until.tv_sec == 0)) {
  36. playing_until.tv_usec = now.tv_usec;
  37. playing_until.tv_sec = now.tv_sec;
  38. }
  39. else {
  40. remaining = (playing_until.tv_usec - now.tv_usec)
  41. + (playing_until.tv_sec - now.tv_sec) * 1000000;
  42. if(remaining > 10000) //Don't sleep() less than 10ms.
  43. //This will add latency...
  44. os_usleep(remaining - 10000);
  45. if(remaining < 0)
  46. cerr << "WARNING - too late" << endl;
  47. }
  48. playing_until.tv_usec += synth.buffersize * 1000000
  49. / synth.samplerate;
  50. if(remaining < 0)
  51. playing_until.tv_usec -= remaining;
  52. playing_until.tv_sec += playing_until.tv_usec / 1000000;
  53. playing_until.tv_usec %= 1000000;
  54. }
  55. return NULL;
  56. }
  57. NulEngine::~NulEngine()
  58. {}
  59. bool NulEngine::Start()
  60. {
  61. setAudioEn(true);
  62. return getAudioEn();
  63. }
  64. void NulEngine::Stop()
  65. {
  66. setAudioEn(false);
  67. }
  68. void NulEngine::setAudioEn(bool nval)
  69. {
  70. if(nval) {
  71. if(!getAudioEn()) {
  72. pthread_t *thread = new pthread_t;
  73. pthread_attr_t attr;
  74. pthread_attr_init(&attr);
  75. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  76. pThread = thread;
  77. pthread_create(pThread, &attr, _AudioThread, this);
  78. }
  79. }
  80. else
  81. if(getAudioEn()) {
  82. pthread_t *thread = pThread;
  83. pThread = NULL;
  84. pthread_join(*thread, NULL);
  85. delete thread;
  86. }
  87. }
  88. bool NulEngine::getAudioEn() const
  89. {
  90. return pThread;
  91. }
  92. }