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