PDA

View Full Version : Re: square wave generating in terminal but not in Qt Creator[SOLVED]



duma
18th August 2011, 18:16
Hi guys.
I have a program that generates a sine wave and a square wave using user inputs of frequency and amplitude. When I run the program in terminal in linux with a g++ compiler, it runs perfectly.
But when I run it in Qt Creator, the sine wave runs perfectly, but the square wave doesn't, it has gaps i.e. it produces square waves for a short amount of time and then no waves for another short amount of time and then square waves again etc. However, this is not in a periodic fashion.
I'm not sure why the same code is producing the waves fine in terminal but not in Qt Creator. Any help would be greatly appreciated.

The way I am running both waves is through the use of threads to start and terminate each wave with the use of pushButtons. My code is below:

generates the square wave:

static void generate_square(snd_pcm_uframes_t offset, int count, double *_phase)
{
static double max_phase = 2. * M_PI;
double phase = *_phase;
double step = max_phase*freq/(double)rate;
unsigned char *samples[channels];
int steps[channels];
unsigned int chn;
int format_bits = snd_pcm_format_width(format);
unsigned int maxval = (1 << (format_bits - 1)) - 1;
int bps = format_bits / 8; /* bytes per sample */
int phys_bps = snd_pcm_format_physical_width(format) / 8;
int big_endian = snd_pcm_format_big_endian(format) == 1;
int to_unsigned = snd_pcm_format_unsigned(format) == 1;
int is_float = (format == SND_PCM_FORMAT_FLOAT_LE ||
format == SND_PCM_FORMAT_FLOAT_BE);
float amplitude_scale = ampl/8.56;
float a;
int b;

// verify and prepare the contents of areas
for (chn = 0; chn < channels; chn++) {

if ((areas[chn].first % 8) != 0) {

printf("areas[%i].first == %i, aborting...", chn , areas[chn].first);
exit(EXIT_FAILURE);
}
samples[chn] = (((unsigned char *)areas[chn].addr) + (areas[chn].first / 8));


if ((areas[chn].step % 16) != 0) {

// printf("areas[%i].step == %i, aborting... ", chn areas[chn].step);
exit(EXIT_FAILURE);
}
steps[chn] = areas[chn].step / 8;
samples[chn] += offset * steps[chn];


}
// fill the channel areas
while (count-- > 0) {
union {
float f;
int i;
} fval;
int res, i;
if (is_float) {
a = amplitude_scale * sgn(sin(phase)) * maxval;
fval.f = a;
res = fval.i;
} else {
b = amplitude_scale * sgn(sin(phase)) * maxval;
printf("b = %d\n",b);
res = b;

}

if (to_unsigned)
res ^= 1U << (format_bits - 1);
for (chn = 0; chn < channels; chn++) {
// Generate data in native endian format
if (big_endian) {
for (i = 0; i < bps; i++)
*(samples[chn] + phys_bps - 1 - i) = (res >> i * 8) & 0xff;
} else {
for (i = 0; i < bps; i++)
*(samples[chn] + i) = (res >> i * 8) & 0xff;
}
samples[chn] += steps[chn];
}
phase += step;
if (phase >= max_phase)
phase -= max_phase;
}
*_phase = phase;

}

produces/writes the square wave:

void onWriteLoopSquare()
{


double phase = 0;
signed short *ptr;
int err, cptr;

generate_square(0, period_size, &phase);

while (1) {

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;
}
}

}

pushButton function:

void wave::on_goSquare_clicked()
{
//Generate
freq = ui->squareFrequency->text().toDouble();
ampl = ui->squareAmplitude->text().toDouble();

squarethread->start();
ui->goSquare->setEnabled(false);
ui->goSquare->setStyleSheet("background-color: gray");
ui->stopSquare->setStyleSheet("background-color: rgb(255, 192, 192);"
"color: red;");
ui->stopSquare->setEnabled(true);
}

void wave::on_stopSquare_clicked()
{
//Terminate
squarethread->terminate();
ui->stopSquare->setEnabled(false);
ui->stopSquare->setStyleSheet("background-color: gray");
ui->goSquare->setStyleSheet("background-color: rgb(192, 255, 208);"
"color: green;");
ui->goSquare->setEnabled(true);
}

Added after 1 15 minutes:

never mind. found my mistake. I took float a and int b out of my program so there were no delays assigning the calculations to fval.f and res in function generate_square()

jetsu
11th April 2012, 08:50
Hi guys.
I have a program that generates a sine wave and a square wave using user inputs of frequency and amplitude. When I run the program in terminal in linux with a g++ compiler, it runs perfectly.
But when I run it in Qt Creator, the sine wave runs perfectly, but the square wave doesn't, it has gaps i.e. it produces square waves for a short amount of time and then no waves for another short amount of time and then square waves again etc. However, this is not in a periodic fashion.
I'm not sure why the same code is producing the waves fine in terminal but not in Qt Creator. Any help would be greatly appreciated.

The way I am running both waves is through the use of threads to start and terminate each wave with the use of pushButtons. My code is below:

generates the square wave:

static void generate_square(snd_pcm_uframes_t offset, int count, double *_phase)
{
static double max_phase = 2. * M_PI;
double phase = *_phase;
double step = max_phase*freq/(double)rate;
unsigned char *samples[channels];
int steps[channels];
unsigned int chn;
int format_bits = snd_pcm_format_width(format);
unsigned int maxval = (1 << (format_bits - 1)) - 1;
int bps = format_bits / 8; /* bytes per sample */
int phys_bps = snd_pcm_format_physical_width(format) / 8;
int big_endian = snd_pcm_format_big_endian(format) == 1;
int to_unsigned = snd_pcm_format_unsigned(format) == 1;
int is_float = (format == SND_PCM_FORMAT_FLOAT_LE ||
format == SND_PCM_FORMAT_FLOAT_BE);
float amplitude_scale = ampl/8.56;
float a;
int b;

// verify and prepare the contents of areas
for (chn = 0; chn < channels; chn++) {

if ((areas[chn].first % 8) != 0) {

printf("areas[%i].first == %i, aborting...", chn , areas[chn].first);
exit(EXIT_FAILURE);
}
samples[chn] = (((unsigned char *)areas[chn].addr) + (areas[chn].first / 8));


if ((areas[chn].step % 16) != 0) {

// printf("areas[%i].step == %i, aborting... ", chn areas[chn].step);
exit(EXIT_FAILURE);
}
steps[chn] = areas[chn].step / 8;
samples[chn] += offset * steps[chn];


}
// fill the channel areas
while (count-- > 0) {
union {
float f;
int i;
} fval;
int res, i;
if (is_float) {
a = amplitude_scale * sgn(sin(phase)) * maxval;
fval.f = a;
res = fval.i;
} else {
b = amplitude_scale * sgn(sin(phase)) * maxval;
printf("b = %d\n",b);
res = b;

}

if (to_unsigned)
res ^= 1U << (format_bits - 1);
for (chn = 0; chn < channels; chn++) {
// Generate data in native endian format
if (big_endian) {
for (i = 0; i < bps; i++)
*(samples[chn] + phys_bps - 1 - i) = (res >> i * 8) & 0xff;
} else {
for (i = 0; i < bps; i++)
*(samples[chn] + i) = (res >> i * 8) & 0xff;
}
samples[chn] += steps[chn];
}
phase += step;
if (phase >= max_phase)
phase -= max_phase;
}
*_phase = phase;

}

hello,I just don't understand the hardware situation of the program,especially the first part code with the name:generates the square wave
could you please give me your E-mail address?
thanks a lot.