commit 3f7d778606d2c75b90a7c5d7beb87d6a31b969c8
parent 1593cba642e6f9c8a18dc8e69ffe56bec5dd4ace
Author: fundamental <[email protected]>
Date: Tue, 4 May 2010 10:45:41 -0400
Merge branch 'niowav' into nio
Diffstat:
8 files changed, 91 insertions(+), 72 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/AudioOut.h b/src/Nio/AudioOut.h
@@ -33,9 +33,6 @@ class AudioOut : public virtual Engine
AudioOut(class OutMgr *out);
virtual ~AudioOut();
- /**Give the Driver Samples to process*/
- //virtual void out(Stereo<Sample> smps);
-
/**Sets the Sample Rate of this Output
* (used for getNext()).*/
void setSamplerate(int _samplerate);
diff --git a/src/Nio/InMgr.h b/src/Nio/InMgr.h
@@ -2,9 +2,7 @@
#define INMGR_H
#include <string>
-#include <pthread.h>
#include <semaphore.h>
-#include "../Misc/Atomic.h"
#include "SafeQueue.h"
enum midi_type{
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
@@ -3,16 +3,14 @@
#include "../globals.h"
#include "../Misc/Stereo.h"
-#include "../Misc/Atomic.h"
-#include "../Samples/Sample.h"
+#include "../Samples/Sample.h" //deprecated
#include <list>
-#include <map>
#include <string>
-#include <pthread.h>
#include <semaphore.h>
class AudioOut;
+class WavEngine;
class Master;
class OutMgr
{
@@ -20,11 +18,6 @@ class OutMgr
OutMgr(Master *nmaster);
~OutMgr();
- /**Adds audio output out.*/
- void add(AudioOut *out){};
- /**Removes given audio output engine*/
- void remove(AudioOut *out){};
-
/**Execute a tick*/
const Stereo<REALTYPE *> tick(unsigned int frameSize);
@@ -40,6 +33,7 @@ class OutMgr
AudioOut *getOut(std::string name);
/**Gets the name of the first running driver
+ * Deprecated
* @return if no running output, "" is returned
*/
std::string getDriver() const;
@@ -49,30 +43,25 @@ 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();};
+ int storedSmps() const {return priBuffCurrent.l() - priBuf.l();};
void makeStale(unsigned int size);
void removeStaleSmps();
- //should hold outputs here that exist for the life of the OutMgr
+
AudioOut *defaultOut;/**<The default output*/
- AudioOut *currentOut;
+ AudioOut *currentOut;/**<The current output driver*/
- //should hold short lived, externally controlled Outputs (eg WavEngine)
- //[needs mutex]
- //std::list<AudioOut *> unmanagedOuts;
- //mutable pthread_mutex_t mutex;
sem_t requested;
- //information on current active primary driver
- //sample rate
- //frame size
-
/**Buffer*/
- Stereo<REALTYPE *> priBuf; //buffer for primary drivers
+ Stereo<REALTYPE *> priBuf; //buffer for primary drivers
Stereo<REALTYPE *> priBuffCurrent; //current array accessor
- Stereo<Sample> smps;
+ Stereo<Sample> smps; /**Deprecated TODO Remove*/
+
REALTYPE *outl;
REALTYPE *outr;
Master *master;
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