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.

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