Results 1 to 3 of 3

Thread: unable to call .first of array[SOLVED]

  1. #1
    Join Date
    Aug 2011
    Posts
    35
    Thanks
    5

    Default 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:
    Qt Code:
    1. if ((areas[chn].first % 8) != 0) {
    2. printf("areas[%i].first == %i, aborting...", chn , areas[chn].first);
    3. exit(EXIT_FAILURE);
    4. }
    To copy to clipboard, switch view to plain text mode 
    I found out that the problem is that it is refusing to use this specific code:
    Qt Code:
    1. areas[chn].first
    To copy to clipboard, switch view to plain text mode 
    . 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:
    Qt Code:
    1. void generate_sine(snd_pcm_channel_area_t *areas,
    2. snd_pcm_uframes_t offset,
    3. int count, double *_phase)
    4. {
    5. static double max_phase = 2. * M_PI;
    6. double phase = *_phase;
    7. double step = max_phase*freq/(double)rate;
    8. unsigned char *samples[channels];
    9. int steps[channels];
    10. unsigned int chn;
    11. int format_bits = snd_pcm_format_width(format);
    12. unsigned int maxval = (1 << (format_bits - 1)) - 1;
    13. int bps = format_bits / 8; /* bytes per sample */
    14. int phys_bps = snd_pcm_format_physical_width(format) / 8;
    15. int big_endian = snd_pcm_format_big_endian(format) == 1;
    16. int to_unsigned = snd_pcm_format_unsigned(format) == 1;
    17. int is_float = (format == SND_PCM_FORMAT_FLOAT_LE ||
    18. format == SND_PCM_FORMAT_FLOAT_BE);
    19. float amplitude_scale = amplitude/8.56;
    20.  
    21.  
    22. // verify and prepare the contents of areas
    23. for (chn = 0; chn < channels; chn++) {
    24. if (areas[chn].first!=0) {
    25. printf("areas[%i].first == %i, aborting...", chn , areas[chn].first);
    26. exit(EXIT_FAILURE);
    27. }
    28. samples[chn] = (((unsigned char *)areas[chn].addr) + (areas[chn].first / 8));
    29. if (areas[chn].step !=0) {
    30. printf("areas[%i].step == %i, aborting... ", chn, areas[chn].step);
    31. exit(EXIT_FAILURE);
    32. }
    33. steps[chn] = areas[chn].step / 8;
    34. samples[chn] += offset * steps[chn];
    35. }
    36. //fill the channel areas
    37. while (count-- > 0) {
    38. union {
    39. float f;
    40. int i;
    41. } fval;
    42. int res, i;
    43. if (is_float) {
    44. fval.f = amplitude_scale * sin(phase) * maxval;
    45. res = fval.i;
    46. } else
    47. res = amplitude_scale * sin(phase) * maxval;
    48. if (to_unsigned)
    49. res ^= 1U << (format_bits - 1);
    50. for (chn = 0; chn < channels; chn++) {
    51. /* Generate data in native endian format */
    52. if (big_endian) {
    53. for (i = 0; i < bps; i++)
    54. *(samples[chn] + phys_bps - 1 - i) = (res >> i * 8) & 0xff;
    55. } else {
    56. for (i = 0; i < bps; i++)
    57. *(samples[chn] + i) = (res >> i * 8) & 0xff;
    58. }
    59. samples[chn] += steps[chn];
    60. }
    61. phase += step;
    62. if (phase >= max_phase)
    63. phase -= max_phase;
    64. }
    65. *_phase = phase;
    66. }
    To copy to clipboard, switch view to plain text mode 

    on_pushButton_clicked():
    Qt Code:
    1. void wave::on_pushButton_clicked()
    2. {
    3.  
    4. struct transfer_method {
    5. const char *name;
    6. snd_pcm_access_t access;
    7. int (*transfer_loop)(snd_pcm_t *handle,
    8. signed short *samples,
    9. snd_pcm_channel_area_t *areas);
    10. };
    11.  
    12. static struct transfer_method transfer_methods[] = {
    13.  
    14.  
    15. { "write", SND_PCM_ACCESS_RW_INTERLEAVED, write_loop },
    16. { NULL, SND_PCM_ACCESS_RW_INTERLEAVED, NULL }
    17. };
    18.  
    19. snd_pcm_t *handle;
    20. int err;
    21. snd_pcm_hw_params_t *hwparams;
    22. snd_pcm_sw_params_t *swparams;
    23. int method = 0;
    24. signed short *samples;
    25. unsigned int chn;
    26. snd_pcm_channel_area_t *areas;
    27.  
    28. snd_pcm_hw_params_alloca(&hwparams);
    29. snd_pcm_sw_params_alloca(&swparams);
    30.  
    31. err = snd_output_stdio_attach(&output, stdout, 0);
    32. if (err < 0) {
    33. printf("Output failed: %s" , snd_strerror(err));
    34.  
    35. }
    36.  
    37.  
    38. if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
    39. printf("Playback open error: %s", snd_strerror(err));
    40.  
    41. }
    42.  
    43. if ((err = set_hwparams(handle, hwparams, transfer_methods[method].access)) < 0) {
    44. printf("Setting of hwparams failed: %s", snd_strerror(err));
    45. exit(EXIT_FAILURE);
    46. }
    47. if ((err = set_swparams(handle, swparams)) < 0) {
    48. printf("Setting of swparams failed: %s", snd_strerror(err));
    49. exit(EXIT_FAILURE);
    50. }
    51.  
    52. if (verbose > 0)
    53. snd_pcm_dump(handle, output);
    54.  
    55. samples = new signed short [period_size * channels * snd_pcm_format_physical_width(format)];
    56. if (samples == NULL) {
    57. printf("Not enough memory");
    58. exit(EXIT_FAILURE);
    59. }
    60.  
    61. areas = new snd_pcm_channel_area_t [channels];
    62. if (areas == NULL) {
    63. printf("Not enough memory");
    64. exit(EXIT_FAILURE);
    65. }
    66. for (chn = 0; chn < channels; chn++) {
    67. areas[chn].addr = samples;
    68. areas[chn].first = chn * snd_pcm_format_physical_width(format);
    69. areas[chn].step = channels * snd_pcm_format_physical_width(format);
    70. }
    71.  
    72. err = transfer_methods[method].transfer_loop(handle, samples, areas);
    73.  
    74. delete [] areas;
    75. delete []samples;
    76. snd_pcm_close(handle);
    77.  
    78.  
    79. }
    To copy to clipboard, switch view to plain text mode 


    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:
    Qt Code:
    1. int write_loop(snd_pcm_t *device_handle,
    2. signed short *samples,
    3. snd_pcm_channel_area_t *areas)
    4. {
    5. double phase = 0;
    6. signed short *ptr;
    7. int err, cptr;
    8.  
    9. generate_sine(areas, 0, period_size, &phase);
    10. while (isTrue) {
    11.  
    12.  
    13.  
    14. ptr = samples;
    15. cptr = period_size;
    16. while (cptr > 0) {
    17. err = snd_pcm_writei(device_handle, ptr, cptr);
    18.  
    19. if (err == -EAGAIN)
    20. continue;
    21. if (err < 0) {
    22. if (xrun_recovery(device_handle, err) < 0) {
    23. printf("Write error: %s ", snd_strerror(err));
    24. exit(EXIT_FAILURE);
    25. }
    26. break; // skip one period
    27. }
    28. ptr += err * channels;
    29. cptr -= err;
    30. }
    31. }
    32. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by duma; 10th August 2011 at 21:26.

  2. #2
    Join Date
    Apr 2010
    Posts
    769
    Thanks
    1
    Thanked 94 Times in 86 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: unable to call .first of array

    my program terminates.
    How? Provide any output or error messages.

  3. #3
    Join Date
    Aug 2011
    Posts
    35
    Thanks
    5

    Default Re: unable to call .first of array

    problem solved. "areas" had different values.

Similar Threads

  1. Cast QString array to std::string array
    By Ishtar in forum Newbie
    Replies: 4
    Last Post: 15th July 2011, 08:28
  2. Replies: 2
    Last Post: 12th November 2010, 14:42
  3. declare an array of QSemaphore and array of slot functions
    By radeberger in forum Qt Programming
    Replies: 11
    Last Post: 2nd May 2010, 13:24
  4. 2D Array
    By ctote in forum Qt Programming
    Replies: 5
    Last Post: 27th January 2010, 10:57
  5. Min and Max value in array
    By Benjamin in forum Qt Programming
    Replies: 13
    Last Post: 27th February 2009, 14:19

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.