Unable to call .first of array[SOLVED]



  • Hi guys,
    I have two problems:
    Problem number 1: I am using pcm.c to build a gui to generate sine waves using user input. I have integrated the code into Qt Creator and I compiled and ran the code with no errors.
    However, every time I click the pushButton (which is supposed to output the sine wave), my program terminates. I have tracked the problem code. In my pushButton function, I have called a function called write_loop which calls generate_sine(). This is causing the problem. I have debugged the code in generate_sine() and I found out that the line which causes it to terminate is this one:
    @if ((areas[chn].first % 8) != 0) {
    printf("areas[%i].first == %i, aborting...", chn , areas[chn].first);
    exit(EXIT_FAILURE);
    }@
    I found out that the problem is that it is refusing to use this specific code: @areas[chn].first@. Also, I did a check to see areas[chn].first is divisible by 8 and it is for all the values of chn. THis program seems only to have the problem of calling areas[chn].first. I have found the problem, but now I don't know how to fix it. Any help would be greatly appreciated.

    The code I have under my pushButton function(on_pushButton_clicked) and generate_sine.cpp is shown below.

    generate_sine.cpp:
    @void generate_sine(snd_pcm_channel_area_t *areas,
    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 = amplitude/8.56;

       //  verify and prepare the contents of areas
         for (chn = 0; chn < channels; chn++) {
                 if (areas[chn].first!=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 !=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) {
                         fval.f = amplitude_scale * sin(phase) * maxval;
                         res = fval.i;
                 } else
                         res = amplitude_scale * sin(phase) * maxval;
                 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;
    

    }@
    more code posted below because of word limit



  • on_pushButton_clicked():
    @void wave::on_pushButton_clicked()
    {

    struct transfer_method {
             const char *name;
             snd_pcm_access_t access;
             int (*transfer_loop)(snd_pcm_t *handle,
                                  signed short *samples,
                                  snd_pcm_channel_area_t *areas);
     };
    
     static struct transfer_method transfer_methods[] = {
    
    
               { "write", SND_PCM_ACCESS_RW_INTERLEAVED, write_loop },
               { NULL, SND_PCM_ACCESS_RW_INTERLEAVED, NULL }
     };
    
            snd_pcm_t *handle;
            int err;
            snd_pcm_hw_params_t *hwparams;
            snd_pcm_sw_params_t *swparams;
            int method = 0;
            signed short *samples;
            unsigned int chn;
            snd_pcm_channel_area_t *areas;
    
            snd_pcm_hw_params_alloca(&hwparams);
            snd_pcm_sw_params_alloca(&swparams);
    
              err = snd_output_stdio_attach(&output, stdout, 0);
            if (err < 0) {
                    printf("Output failed: %s" , snd_strerror(err));
    
            }
    
    
            if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
                    printf("Playback open error: %s", snd_strerror(err));
    
            }
    
            if ((err = set_hwparams(handle, hwparams, transfer_methods[method].access)) < 0) {
                    printf("Setting of hwparams failed: %s", snd_strerror(err));
                    exit(EXIT_FAILURE);
            }
            if ((err = set_swparams(handle, swparams)) < 0) {
                    printf("Setting of swparams failed: %s", snd_strerror(err));
                    exit(EXIT_FAILURE);
            }
    
            if (verbose > 0)
                    snd_pcm_dump(handle, output);
    
            samples = new signed short [period_size * channels * snd_pcm_format_physical_width(format)];
            if (samples == NULL) {
                    printf("Not enough memory");
                    exit(EXIT_FAILURE);
            }
    
            areas = new snd_pcm_channel_area_t [channels];
            if (areas == NULL) {
                    printf("Not enough memory");
                    exit(EXIT_FAILURE);
            }
            for (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);
            }
    
           err = transfer_methods[method].transfer_loop(handle, samples, areas);
    
            delete [] areas;
            delete []samples;
            snd_pcm_close(handle);
    

    }@

    Problem number 2:
    When I set my while loop in the write_loop function to 'true', i.e while(isTrue), (when bool isTrue = true; is defined at the top), my program immediately terminates. And to make sure that it isn't the generate_sine() function that isn't doing it(as described above, I commented the generate_sine() function out, and it still just terminates. However, If I don't set any value for bool isTrue (i.e. just define bool isTrue; at the top, the program doesn't terminate.
    Here is my write_loop function:
    @int write_loop(snd_pcm_t *device_handle,
    signed short *samples,
    snd_pcm_channel_area_t *areas)
    {
    double phase = 0;
    signed short *ptr;
    int err, cptr;

                 generate_sine(areas, 0, period_size, &phase);
         while (isTrue) {
    
    
    
                 ptr = samples;
                 cptr = period_size;
                 while (cptr > 0) {
                         err = snd_pcm_writei(device_handle, ptr, cptr);
    
                         if (err == -EAGAIN)
                                 continue;
                         if (err < 0) {
                                 if (xrun_recovery(device_handle, err) < 0) {
                                         printf("Write error: %s  ", snd_strerror(err));
                                         exit(EXIT_FAILURE);
                                 }
                                 break;  // skip one period
                         }
                         ptr += err * channels;
                         cptr -= err;
                 }
         }
    

    }
    @



  • solved. areas had different values as it was declared again.


Log in to reply
 

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