duma
12th August 2011, 15:18
Hi guys,
I have a program in Qt Creator which outputs a sine wave with the click of a pushButton. However, due to a never ending while loop in my pushButton function, the application freezes when I click the pushButton. So I am using threads for my function and ending the while loop by eliminating the thread with the click of another pushButton(pushButton2).
I build my code with no errors. however, when I run it, the pushButton does not generate a sine wave and I get the following message:
@QMetaObject::connectSlotsByName: No matching signal for on_write_loop(snd_pcm_t*,signed short*,snd_pcm_channel_area_t*)@
Any help would be greatly appreciated.
My code snippets are below:
wave.cpp:
void wave::on_write_loop(snd_pcm_t *handles, signed short *samples , snd_pcm_channel_area_t *areas)
{
double freq = ui->frequency->text().toDouble();
double ampl = ui->amplitude->text().toDouble();
double phase = 0;
signed short *ptr;
int err, cptr;
while (1) {
generate_sine(0, period_size, &phase, freq, ampl);
ptr = samples;
cptr = period_size;
while (cptr > 0) {
err = snd_pcm_writei(hspdif, ptr, cptr);
if (err == -EAGAIN)
continue;
if (err < 0) {
if (xrun_recovery(hspdif, err) < 0) {
printf("Write error: %s ", snd_strerror(err));
exit(EXIT_FAILURE);
}
break; /* skip one period */
}
ptr += err * channels;
cptr -= err;
}
}
}
wave::wave(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::wave)
{
ui->setupUi(this);
//setup();
mThread = new MyThread(this);
connect(mThread, SIGNAL(write_loop(snd_pcm_t*, signed short*, snd_pcm_channel_area_t*)), this, SLOT(on_write_loop(snd_pcm_t*, signed short*, snd_pcm_channel_area_t*)));
}
wave::~wave()
{
delete ui;
}
void wave::on_pushButton_clicked()
{
//Generate
mThread->start();
}
void wave::on_pushButton_2_clicked()
{
//Terminate
mThread->Stop = true;
}
wave.h:
#ifndef WAVE_H
#define WAVE_H
#include "ui_wave.h"
#include <alsa/asoundlib.h>
#include <QMainWindow>
#include <QObject>
#include "mythread.h"
namespace Ui {
class wave;
}
class wave : public QMainWindow
{
Q_OBJECT
public:
explicit wave(QWidget *parent = 0);
~wave();
MyThread *mThread;
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void setup();
private:
Ui::wave *ui;
public slots:
void on_write_loop(snd_pcm_t*, signed short*, snd_pcm_channel_area_t*);
;
#endif // WAVE_H
MyThread.cpp:
void MyThread::run()
{
QMutex mutex;
mutex.lock();
if (this->Stop)
mutex.unlock();
const char *device = "plughw:0,0";
snd_pcm_hw_params_alloca(&hwparams);
snd_pcm_sw_params_alloca(&swparams);
int err = snd_output_stdio_attach(&output, stdout, 0);
printf( "snd_output_stdio_attach err=%d\n", err);
err = snd_pcm_open(&hspdif, device, SND_PCM_STREAM_PLAYBACK, 0);
printf( "snd_pcm_open err=%d\n", err);
err = set_hwparams(hspdif, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
printf( "set_hwparams err=%d\n", err);
err = set_swparams(hspdif, swparams);
printf( "set_swparams err=%d\n", err);
samples = new signed short [period_size * channels * snd_pcm_format_physical_width(format)];
printf( "samples array_size=%d\n", int( period_size * channels * snd_pcm_format_physical_width(format)) );
areas = new snd_pcm_channel_area_t [channels];
printf( "areas channels=%d\n", channels);
for (unsigned int chn = 0; chn < channels; chn++) {
areas[chn].addr = samples;
areas[chn].first = chn * snd_pcm_format_physical_width(format);
areas[chn].step = channels * snd_pcm_format_physical_width(format);
}
emit write_loop(hspdif, samples, areas);
}
MyThread.h:
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <alsa/asoundlib.h>
#include <QThread>
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = 0);
void run();
bool Stop;
signals:
void write_loop(snd_pcm_t*, signed short*, snd_pcm_channel_area_t*);
public slots:
};
#endif // MYTHREAD_H
I have a program in Qt Creator which outputs a sine wave with the click of a pushButton. However, due to a never ending while loop in my pushButton function, the application freezes when I click the pushButton. So I am using threads for my function and ending the while loop by eliminating the thread with the click of another pushButton(pushButton2).
I build my code with no errors. however, when I run it, the pushButton does not generate a sine wave and I get the following message:
@QMetaObject::connectSlotsByName: No matching signal for on_write_loop(snd_pcm_t*,signed short*,snd_pcm_channel_area_t*)@
Any help would be greatly appreciated.
My code snippets are below:
wave.cpp:
void wave::on_write_loop(snd_pcm_t *handles, signed short *samples , snd_pcm_channel_area_t *areas)
{
double freq = ui->frequency->text().toDouble();
double ampl = ui->amplitude->text().toDouble();
double phase = 0;
signed short *ptr;
int err, cptr;
while (1) {
generate_sine(0, period_size, &phase, freq, ampl);
ptr = samples;
cptr = period_size;
while (cptr > 0) {
err = snd_pcm_writei(hspdif, ptr, cptr);
if (err == -EAGAIN)
continue;
if (err < 0) {
if (xrun_recovery(hspdif, err) < 0) {
printf("Write error: %s ", snd_strerror(err));
exit(EXIT_FAILURE);
}
break; /* skip one period */
}
ptr += err * channels;
cptr -= err;
}
}
}
wave::wave(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::wave)
{
ui->setupUi(this);
//setup();
mThread = new MyThread(this);
connect(mThread, SIGNAL(write_loop(snd_pcm_t*, signed short*, snd_pcm_channel_area_t*)), this, SLOT(on_write_loop(snd_pcm_t*, signed short*, snd_pcm_channel_area_t*)));
}
wave::~wave()
{
delete ui;
}
void wave::on_pushButton_clicked()
{
//Generate
mThread->start();
}
void wave::on_pushButton_2_clicked()
{
//Terminate
mThread->Stop = true;
}
wave.h:
#ifndef WAVE_H
#define WAVE_H
#include "ui_wave.h"
#include <alsa/asoundlib.h>
#include <QMainWindow>
#include <QObject>
#include "mythread.h"
namespace Ui {
class wave;
}
class wave : public QMainWindow
{
Q_OBJECT
public:
explicit wave(QWidget *parent = 0);
~wave();
MyThread *mThread;
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void setup();
private:
Ui::wave *ui;
public slots:
void on_write_loop(snd_pcm_t*, signed short*, snd_pcm_channel_area_t*);
;
#endif // WAVE_H
MyThread.cpp:
void MyThread::run()
{
QMutex mutex;
mutex.lock();
if (this->Stop)
mutex.unlock();
const char *device = "plughw:0,0";
snd_pcm_hw_params_alloca(&hwparams);
snd_pcm_sw_params_alloca(&swparams);
int err = snd_output_stdio_attach(&output, stdout, 0);
printf( "snd_output_stdio_attach err=%d\n", err);
err = snd_pcm_open(&hspdif, device, SND_PCM_STREAM_PLAYBACK, 0);
printf( "snd_pcm_open err=%d\n", err);
err = set_hwparams(hspdif, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
printf( "set_hwparams err=%d\n", err);
err = set_swparams(hspdif, swparams);
printf( "set_swparams err=%d\n", err);
samples = new signed short [period_size * channels * snd_pcm_format_physical_width(format)];
printf( "samples array_size=%d\n", int( period_size * channels * snd_pcm_format_physical_width(format)) );
areas = new snd_pcm_channel_area_t [channels];
printf( "areas channels=%d\n", channels);
for (unsigned int chn = 0; chn < channels; chn++) {
areas[chn].addr = samples;
areas[chn].first = chn * snd_pcm_format_physical_width(format);
areas[chn].step = channels * snd_pcm_format_physical_width(format);
}
emit write_loop(hspdif, samples, areas);
}
MyThread.h:
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <alsa/asoundlib.h>
#include <QThread>
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(QObject *parent = 0);
void run();
bool Stop;
signals:
void write_loop(snd_pcm_t*, signed short*, snd_pcm_channel_area_t*);
public slots:
};
#endif // MYTHREAD_H