Hello,
I'm trying to set up a GUI with QT using PortAudio to capture sound. For contious recording i use two buffer which I switch, when one is filled with Data. Now I want to use a new thread to process the full Buffer (save data). That's where the Problem lies... I have created that thread and tryed to interface it via a signal. But the signal is emitted from within the callback thread and not the main thread. For some reason this is not working.
My savethread class:
{
Q_OBJECT
public:
~SaveBuffer();
void process();
protected:
void run();
protected:
bool finish;
private:
SDataStruct sData;
};
class SaveBuffer : public QThread
{
Q_OBJECT
public:
SaveBuffer(QObject *parent = 0);
~SaveBuffer();
void process();
protected:
void run();
protected:
bool finish;
private:
QMutex mutex;
QWaitCondition condition;
SDataStruct sData;
};
To copy to clipboard, switch view to plain text mode
#include "SaveBuffer.h"
SaveBuffer
::SaveBuffer(QObject *parent
){
sData.file.setFileName("recorded.raw");
}
SaveBuffer::~SaveBuffer()
{
//mutex.lock();
condition.wakeOne();
//mutex.unlock();
sData.file.close();
wait();
}
void SaveBuffer::run()
{
forever
{
QFile *file = &sData.
file;
int frameIndex = *sData.FrameIndex;
SAMPLE *buffer = sData.buffer;
for(int k=0;k<frameIndex;k++)
{
out << (qreal)buffer[k];
}
condition.wait(&mutex);//put thread to sleep
}
};
void SaveBuffer::process(DataStruct* incData)
{
if (!isRunning()) {
start(LowPriority);
} else {
condition.wakeOne();
}
}
#include "SaveBuffer.h"
SaveBuffer::SaveBuffer(QObject *parent)
: QThread(parent)
{
sData.file.setFileName("recorded.raw");
sData.file.open(QIODevice::Append);
}
SaveBuffer::~SaveBuffer()
{
//mutex.lock();
condition.wakeOne();
//mutex.unlock();
sData.file.close();
wait();
}
void SaveBuffer::run()
{
forever
{
QMutexLocker locker(&mutex);
QFile *file = &sData.file;
int frameIndex = *sData.FrameIndex;
SAMPLE *buffer = sData.buffer;
QDataStream out(file);
out.setByteOrder(QDataStream::LittleEndian);
for(int k=0;k<frameIndex;k++)
{
out << (qreal)buffer[k];
}
condition.wait(&mutex);//put thread to sleep
}
};
void SaveBuffer::process(DataStruct* incData)
{
QMutexLocker locker(&mutex);
if (!isRunning()) {
start(LowPriority);
} else {
condition.wakeOne();
}
}
To copy to clipboard, switch view to plain text mode
My window class:
{
Q_OBJECT
public:
EEGacquisition
(QWidget *parent
= 0, Qt
::WFlags flags
= 0);
~EEGacquisition();
void processDataEmitter(void*);
private:
Ui::EEGacquisitionClass ui;
SaveBuffer sthread;
signals:
void processData();
};
class EEGacquisition : public QMainWindow
{
Q_OBJECT
public:
EEGacquisition(QWidget *parent = 0, Qt::WFlags flags = 0);
~EEGacquisition();
void processDataEmitter(void*);
private:
Ui::EEGacquisitionClass ui;
SaveBuffer sthread;
signals:
void processData();
};
To copy to clipboard, switch view to plain text mode
int recordCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData,
void *ui);
EEGacquisition
::EEGacquisition(QWidget *parent, Qt
::WFlags flags
){
ui.setupUi(this);
//connects
connect(ui.pushButton_measure,SIGNAL(clicked()),this,SLOT(pushButton_measure_clicked()),Qt::DirectConnection);
/*---portaudio setup---*/
[...]
}
}
void EEGacquisition::processDataEmitter(void *user_int)
{
// problem here if i emit a signal I am still in record callback
// I cannot connet this signal
}
/////
//callback for recording audio data
/////
static int recordCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData,
void *user_int)
{
[...]
//at some point emit save signal!!!
ui->processDataEmitter();
[...]
return paContinue;//0
}
int recordCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData,
void *ui);
EEGacquisition::EEGacquisition(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
//connects
connect(ui.pushButton_measure,SIGNAL(clicked()),this,SLOT(pushButton_measure_clicked()),Qt::DirectConnection);
/*---portaudio setup---*/
[...]
}
}
void EEGacquisition::processDataEmitter(void *user_int)
{
// problem here if i emit a signal I am still in record callback
// I cannot connet this signal
}
/////
//callback for recording audio data
/////
static int recordCallback( const void *inputBuffer, void *outputBuffer,
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo* timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData,
void *user_int)
{
[...]
//at some point emit save signal!!!
ui->processDataEmitter();
[...]
return paContinue;//0
}
To copy to clipboard, switch view to plain text mode
I also tried directly calling the process() function in sthread, but doing so led to an exeption, because the call wasnt from the main window thread.
Can someone please explain some way to start the save thread?
Thanks
Bookmarks