Square wave runs fine in terminal but not in Qt Creator[SOLVED]



  • 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);
    }@



  • 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()


  • Moderators

    I very seriously doubt that a delay assigning the calculations was causing the problems, but as long you have it working, great!



  • [quote author="mlong" date="1313702759"]I very seriously doubt that a delay assigning the calculations was causing the problems, but as long you have it working, great!
    [/quote]

    Sorry, I did not know whether it caused a delay. I shouldn't have said that. What I meant to say was that, after assigning the calculations directly to fval.f and res, the gaps in my square wave disappeared. Like below:
    @fval.f = amplitude_scale * sgn(sin(phase)) * maxval;
    res = amplitude_scale * sgn(sin(phase)) * maxval;@

    instead of :
    @a = amplitude_scale * sgn(sin(phase)) * maxval;
    fval.f = a;

    b = amplitude_scale * sgn(sin(phase)) * maxval;
    res = b;
    @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.