commit 2c133e58ced35c7747ddd74bdcf0d750566e8556
parent c24e6c76d4f74afda17513146066fd3727f2fc7a
Author: fundamental <mark.d.mccurry@gmail.com>
Date: Mon, 3 May 2010 14:34:36 -0400
WIP: Wave Output in nio
Right now it glitches, but outputting something similar to desired
Diffstat:
6 files changed, 82 insertions(+), 46 deletions(-)
diff --git a/src/Misc/Recorder.cpp b/src/Misc/Recorder.cpp
@@ -22,11 +22,12 @@
#include <sys/stat.h>
#include "Recorder.h"
+#include "WavFile.h"
#include "../Nio/OutMgr.h"
#include "../Nio/WavEngine.h"
Recorder::Recorder()
- :status(0), wave(NULL), notetrigger(0)
+ :status(0), notetrigger(0)
{}
Recorder::~Recorder()
@@ -45,8 +46,7 @@ int Recorder::preparefile(std::string filename_, int overwrite)
return 1;
}
- if(!(wave=new WavEngine(sysOut, filename_, SAMPLE_RATE, 2)))
- return 2;
+ sysOut->wave->newFile(new WavFile(filename_, SAMPLE_RATE, 2));
status = 1; //ready
@@ -61,21 +61,15 @@ void Recorder::start()
void Recorder::stop()
{
- if(wave)
- {
- //sysOut->remove(wave);
- //wave->Stop();
- delete wave;
- wave = NULL; //is this even needed?
- }
+ sysOut->wave->Stop();
+ sysOut->wave->destroyFile();
status = 0;
}
void Recorder::pause()
{
status = 0;
- //wave->Stop();
- //sysOut->remove(wave);
+ sysOut->wave->Stop();
}
int Recorder::recording()
@@ -90,8 +84,7 @@ void Recorder::triggernow()
{
if(status == 2) {
if(notetrigger!=1) {
- //wave->openAudio();
- //sysOut->add(wave);
+ sysOut->wave->Start();
}
notetrigger = 1;
}
diff --git a/src/Misc/Recorder.h b/src/Misc/Recorder.h
@@ -25,8 +25,6 @@
#include <string>
#include "../globals.h"
-class WavEngine;
-
/**Records sound to a file*/
class Recorder
{
@@ -50,7 +48,6 @@ class Recorder
int status;
private:
- WavEngine *wave;
int notetrigger;
};
diff --git a/src/Nio/OutMgr.cpp b/src/Nio/OutMgr.cpp
@@ -5,6 +5,7 @@
#include "Engine.h"
#include "EngineMgr.h"
#include "InMgr.h"
+#include "WavEngine.h"
#include "../Misc/Master.h"
#include "../Misc/Util.h"//for set_realtime()
@@ -13,7 +14,8 @@ using namespace std;
OutMgr *sysOut;
OutMgr::OutMgr(Master *nmaster)
- :priBuf(new REALTYPE[4096],new REALTYPE[4096]),priBuffCurrent(priBuf)
+ :wave(new WavEngine(this)),
+ priBuf(new REALTYPE[4096],new REALTYPE[4096]),priBuffCurrent(priBuf)
{
currentOut = NULL;
stales = 0;
@@ -148,6 +150,9 @@ string OutMgr::getSink() const
void OutMgr::addSmps(REALTYPE *l, REALTYPE *r)
{
+ //allow wave file to syphon off stream
+ wave->push(Stereo<REALTYPE *>(l,r),SOUND_BUFFER_SIZE);
+
Stereo<Sample> smps(Sample(SOUND_BUFFER_SIZE, l), Sample(SOUND_BUFFER_SIZE, r));
if(currentOut->getSampleRate() != SAMPLE_RATE) { //we need to resample
diff --git a/src/Nio/OutMgr.h b/src/Nio/OutMgr.h
@@ -43,6 +43,8 @@ class OutMgr
bool setSink(std::string name);
std::string getSink() const;
+
+ WavEngine *wave; /**<The Wave Recorder*/
private:
void addSmps(REALTYPE *l, REALTYPE *r);
int storedSmps() const {return priBuffCurrent.l() - priBuf.l();};
@@ -53,7 +55,6 @@ class OutMgr
AudioOut *currentOut;/**<The current output driver*/
- WavEngine *wave; /**<The Wave Recorder*/
sem_t requested;
/**Buffer*/
diff --git a/src/Nio/WavEngine.cpp b/src/Nio/WavEngine.cpp
@@ -20,47 +20,81 @@
#include <cstdio>
#include <iostream>
#include <cstdlib>
-#include "SafeQueue.h"
+#include "../Misc/WavFile.h"
#include "../Misc/Util.h"
using namespace std;
-WavEngine::WavEngine(OutMgr *out, string filename, int samplerate, int channels)
- :AudioOut(out), file(filename, samplerate, channels),
- enabled(false)
+WavEngine::WavEngine(OutMgr *out)
+ :AudioOut(out), file(NULL), buffer(SAMPLE_RATE*2), pThread(NULL)
{
+ sem_init(&work, PTHREAD_PROCESS_PRIVATE, 0);
}
WavEngine::~WavEngine()
{
Stop();
+ sem_destroy(&work);
+ destroyFile();
}
bool WavEngine::openAudio()
{
- return file.good();
+ return file && file->good();
}
bool WavEngine::Start()
{
- if(enabled())
+ if(pThread)
return true;
+ pThread = new pthread_t;
+
pthread_attr_t attr;
- enabled = true;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
- pthread_create(&pThread, &attr, _AudioThread, this);
+ pthread_create(pThread, &attr, _AudioThread, this);
return true;
}
void WavEngine::Stop()
{
- if(!enabled())
+ if(!pThread)
+ return;
+
+ pthread_t *tmp = pThread;
+ pThread = NULL;
+
+ sem_post(&work);
+ pthread_join(*tmp, NULL);
+ delete pThread;
+}
+
+void WavEngine::push(Stereo<REALTYPE *> smps, size_t len)
+{
+ if(!pThread)
return;
- enabled = false;
- pthread_join(pThread, NULL);
+
+ //copy the input [overflow when needed]
+ for(size_t i = 0; i < len; ++i) {
+ buffer.push(*smps.l()++);
+ buffer.push(*smps.r()++);
+ sem_post(&work);
+ }
+}
+
+void WavEngine::newFile(WavFile *_file)
+{
+ //ensure system is clean
+ destroyFile();
+ file = _file;
+}
+
+void WavEngine::destroyFile()
+{
+ if(file)
+ delete file;
}
void *WavEngine::_AudioThread(void *arg)
@@ -70,18 +104,16 @@ void *WavEngine::_AudioThread(void *arg)
void *WavEngine::AudioThread()
{
- short int *recordbuf_16bit = new short int [SOUND_BUFFER_SIZE*2];
- int size = SOUND_BUFFER_SIZE;
-
+ short int recordbuf_16bit[2];
- while (enabled())
+ while(!sem_wait(&work) && pThread)
{
- const Stereo<Sample> smps = getNext(true);
- for(int i = 0; i < size; i++) {
- recordbuf_16bit[i*2] = limit((int)(smps.l()[i] * 32767.0), -32768, 32767);
- recordbuf_16bit[i*2+1] = limit((int)(smps.r()[i] * 32767.0), -32768, 32767);
- }
- file.writeStereoSamples(size, recordbuf_16bit);
+ float left=0.0f, right=0.0f;
+ buffer.pop(left);
+ buffer.pop(right);
+ recordbuf_16bit[0] = limit((int)(left * 32767.0), -32768, 32767);
+ recordbuf_16bit[1] = limit((int)(right * 32767.0), -32768, 32767);
+ file->writeStereoSamples(1, recordbuf_16bit);
}
pthread_exit(NULL);
}
diff --git a/src/Nio/WavEngine.h b/src/Nio/WavEngine.h
@@ -23,15 +23,16 @@
#ifndef WAVENGINE_H
#define WAVENGINE_H
#include "AudioOut.h"
-#include "../Misc/WavFile.h"
-#include "../Misc/Atomic.h"
#include <string>
#include <pthread.h>
+#include <semaphore.h>
+#include "SafeQueue.h"
+class WavFile;
class WavEngine: public AudioOut
{
public:
- WavEngine(OutMgr *out, std::string filename, int samplerate, int channels);
+ WavEngine(OutMgr *out);
~WavEngine();
bool openAudio();
@@ -41,14 +42,21 @@ class WavEngine: public AudioOut
void setAudioEn(bool /*nval*/){};
bool getAudioEn() const{return true;};
+ void push(Stereo<REALTYPE *> smps, size_t len);
+
+ void newFile(WavFile *_file);
+ void destroyFile();
+
protected:
void *AudioThread();
static void *_AudioThread(void *arg);
private:
- WavFile file;
- Atomic<bool> enabled;
- pthread_t pThread;
+ WavFile *file;
+ sem_t work;
+ SafeQueue<float> buffer;
+
+ pthread_t *pThread;
};
#endif