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.

133 lines
2.8KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. WavEngine - an Output To File Engine
  4. Copyright (C) 2006 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 "WavEngine.h"
  12. #include <cstdio>
  13. #include <iostream>
  14. #include <cstdlib>
  15. #include "../Misc/WavFile.h"
  16. #include "../Misc/Util.h"
  17. using namespace std;
  18. namespace zyncarla {
  19. WavEngine::WavEngine(const SYNTH_T &synth_)
  20. :AudioOut(synth_), file(NULL), buffer(synth.samplerate * 4), pThread(NULL)
  21. {
  22. work.init(PTHREAD_PROCESS_PRIVATE, 0);
  23. }
  24. WavEngine::~WavEngine()
  25. {
  26. Stop();
  27. destroyFile();
  28. }
  29. bool WavEngine::openAudio()
  30. {
  31. return file && file->good();
  32. }
  33. bool WavEngine::Start()
  34. {
  35. if(pThread)
  36. return true;
  37. pThread = new pthread_t;
  38. pthread_attr_t attr;
  39. pthread_attr_init(&attr);
  40. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  41. pthread_create(pThread, &attr, _AudioThread, this);
  42. return true;
  43. }
  44. void WavEngine::Stop()
  45. {
  46. if(!pThread)
  47. return;
  48. pthread_t *tmp = pThread;
  49. pThread = NULL;
  50. work.post();
  51. pthread_join(*tmp, NULL);
  52. delete pThread;
  53. }
  54. void WavEngine::push(Stereo<float *> smps, size_t len)
  55. {
  56. if(!pThread)
  57. return;
  58. //copy the input [overflow when needed]
  59. for(size_t i = 0; i < len; ++i) {
  60. buffer.push(*smps.l++);
  61. buffer.push(*smps.r++);
  62. }
  63. work.post();
  64. }
  65. void WavEngine::newFile(WavFile *_file)
  66. {
  67. //ensure system is clean
  68. destroyFile();
  69. file = _file;
  70. //check state
  71. if(!file->good())
  72. cerr
  73. << "ERROR: WavEngine handed bad file output WavEngine::newFile()"
  74. << endl;
  75. }
  76. void WavEngine::destroyFile()
  77. {
  78. if(file)
  79. delete file;
  80. file = NULL;
  81. }
  82. void *WavEngine::_AudioThread(void *arg)
  83. {
  84. return (static_cast<WavEngine *>(arg))->AudioThread();
  85. }
  86. void *WavEngine::AudioThread()
  87. {
  88. short *recordbuf_16bit = new short[2 * synth.buffersize];
  89. while(!work.wait() && pThread) {
  90. for(int i = 0; i < synth.buffersize; ++i) {
  91. float left = 0.0f, right = 0.0f;
  92. buffer.pop(left);
  93. buffer.pop(right);
  94. recordbuf_16bit[2 * i] = limit((int)(left * 32767.0f),
  95. -32768,
  96. 32767);
  97. recordbuf_16bit[2 * i + 1] = limit((int)(right * 32767.0f),
  98. -32768,
  99. 32767);
  100. }
  101. if(file)
  102. file->writeStereoSamples(synth.buffersize, recordbuf_16bit);
  103. }
  104. delete[] recordbuf_16bit;
  105. return NULL;
  106. }
  107. }