Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt Creator and other tools
  4. Unable to call .first of array[SOLVED]
Forum Updated to NodeBB v4.3 + New Features

Unable to call .first of array[SOLVED]

Scheduled Pinned Locked Moved Qt Creator and other tools
3 Posts 1 Posters 1.3k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • O Offline
    O Offline
    ogopa
    wrote on last edited by
    #1

    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

    1 Reply Last reply
    0
    • O Offline
      O Offline
      ogopa
      wrote on last edited by
      #2

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

      }
      @

      1 Reply Last reply
      0
      • O Offline
        O Offline
        ogopa
        wrote on last edited by
        #3

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

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved