You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
5.2 KiB

  1. Switch madplay to the new API. This is done thanks to a patch written
  2. by Micha Nelissen <micha@neli.hopto.org> and available at
  3. http://article.gmane.org/gmane.comp.audio.mad.devel/729.
  4. --- a/audio_alsa.c
  5. +++ b/audio_alsa.c
  6. @@ -28,31 +28,30 @@
  7. #include <errno.h>
  8. -#define ALSA_PCM_OLD_HW_PARAMS_API
  9. -#define ALSA_PCM_OLD_SW_PARAMS_API
  10. #include <alsa/asoundlib.h>
  11. #include <mad.h>
  12. #include "audio.h"
  13. -char *buf = NULL;
  14. -int paused = 0;
  15. +#define BUFFER_TIME_MAX 500000
  16. -int rate = -1;
  17. -int channels = -1;
  18. -int bitdepth = -1;
  19. -int sample_size = -1;
  20. -
  21. -int buffer_time = 500000;
  22. -int period_time = 100000;
  23. -char *defaultdev = "plughw:0,0";
  24. +unsigned char *buf = NULL;
  25. +int paused = 0;
  26. +
  27. +unsigned int rate = 0;
  28. +unsigned int channels = -1;
  29. +unsigned int bitdepth = -1;
  30. +unsigned int sample_size = -1;
  31. +
  32. +unsigned int buffer_time;
  33. +unsigned int period_time;
  34. +char *defaultdev = "plughw:0,0";
  35. snd_pcm_hw_params_t *alsa_hwparams;
  36. snd_pcm_sw_params_t *alsa_swparams;
  37. -snd_pcm_sframes_t buffer_size;
  38. -snd_pcm_sframes_t period_size;
  39. +snd_pcm_uframes_t buffer_size;
  40. snd_pcm_format_t alsa_format = -1;
  41. snd_pcm_access_t alsa_access = SND_PCM_ACCESS_MMAP_INTERLEAVED;
  42. @@ -66,14 +65,20 @@ int set_hwparams(snd_pcm_t *handle,
  43. snd_pcm_hw_params_t *params,
  44. snd_pcm_access_t access)
  45. {
  46. - int err, dir;
  47. -
  48. + int err;
  49. +
  50. /* choose all parameters */
  51. err = snd_pcm_hw_params_any(handle,params);
  52. if (err < 0) {
  53. printf("Access type not available for playback: %s\n", snd_strerror(err));
  54. return err;
  55. }
  56. + /* set the access type */
  57. + err = snd_pcm_hw_params_set_access(handle, params, alsa_access);
  58. + if (err < 0) {
  59. + printf("Sample format not available for playback: %s\n", snd_strerror(err));
  60. + return err;
  61. + }
  62. /* set the sample format */
  63. err = snd_pcm_hw_params_set_format(handle, params, alsa_format);
  64. if (err < 0) {
  65. @@ -87,29 +92,38 @@ int set_hwparams(snd_pcm_t *handle,
  66. return err;
  67. }
  68. /* set the stream rate */
  69. - err = snd_pcm_hw_params_set_rate_near(handle, params, rate, 0);
  70. + err = snd_pcm_hw_params_set_rate(handle, params, rate, 0);
  71. if (err < 0) {
  72. printf("Rate %iHz not available for playback: %s\n", rate, snd_strerror(err));
  73. return err;
  74. }
  75. - if (err != rate) {
  76. - printf("Rate doesn't match (requested %iHz, get %iHz)\n", rate, err);
  77. - return -EINVAL;
  78. - }
  79. + err = snd_pcm_hw_params_get_buffer_time_max(params, &buffer_time, NULL);
  80. + if (err < 0) {
  81. + printf("Unable to retrieve buffer time: %s\n", snd_strerror(err));
  82. + return err;
  83. + }
  84. + if (buffer_time > BUFFER_TIME_MAX)
  85. + buffer_time = BUFFER_TIME_MAX;
  86. /* set buffer time */
  87. - err = snd_pcm_hw_params_set_buffer_time_near(handle, params, buffer_time, &dir);
  88. + err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &buffer_time, 0);
  89. if (err < 0) {
  90. printf("Unable to set buffer time %i for playback: %s\n", buffer_time, snd_strerror(err));
  91. return err;
  92. }
  93. - buffer_size = snd_pcm_hw_params_get_buffer_size(params);
  94. + if (period_time * 4 > buffer_time)
  95. + period_time = buffer_time / 4;
  96. /* set period time */
  97. - err = snd_pcm_hw_params_set_period_time_near(handle, params, period_time, &dir);
  98. + err = snd_pcm_hw_params_set_period_time_near(handle, params, &period_time, NULL);
  99. if (err < 0) {
  100. printf("Unable to set period time %i for playback: %s\n", period_time, snd_strerror(err));
  101. return err;
  102. }
  103. - period_size = snd_pcm_hw_params_get_period_size(params, &dir);
  104. + /* retrieve buffer size */
  105. + err = snd_pcm_hw_params_get_buffer_size(params, &buffer_size);
  106. + if (err < 0) {
  107. + printf("Unable to retrieve buffer size: %s\n", snd_strerror(err));
  108. + return err;
  109. + }
  110. /* write the parameters to device */
  111. err = snd_pcm_hw_params(handle, params);
  112. if (err < 0) {
  113. @@ -123,6 +137,7 @@ static
  114. int set_swparams(snd_pcm_t *handle,
  115. snd_pcm_sw_params_t *params)
  116. {
  117. + unsigned int start_threshold;
  118. int err;
  119. /* get current swparams */
  120. @@ -136,13 +151,7 @@ int set_swparams(snd_pcm_t *handle,
  121. if (err < 0) {
  122. printf("Unable to set start threshold mode for playback: %s\n", snd_strerror(err));
  123. return err;
  124. - }
  125. - /* allow transfer when at least period_size samples can be processed */
  126. - err = snd_pcm_sw_params_set_avail_min(handle, params, period_size);
  127. - if (err < 0) {
  128. - printf("Unable to set avail min for playback: %s\n", snd_strerror(err));
  129. - return err;
  130. - }
  131. + }
  132. /* align all transfers to 1 samples */
  133. err = snd_pcm_sw_params_set_xfer_align(handle, params, 1);
  134. if (err < 0) {
  135. @@ -190,7 +199,7 @@ int config(struct audio_config *config)
  136. rate = config->speed;
  137. if ( bitdepth == 0 )
  138. - config->precision = bitdepth = 32;
  139. + config->precision = bitdepth = 16;
  140. switch (bitdepth)
  141. {
  142. @@ -241,7 +250,7 @@ int config(struct audio_config *config)
  143. return -1;
  144. }
  145. - buf = malloc(buffer_size);
  146. + buf = malloc(buffer_size * sample_size);
  147. if (buf == NULL) {
  148. audio_error="unable to allocate output buffer table";
  149. return -1;
  150. @@ -279,7 +288,7 @@ static
  151. int play(struct audio_play *play)
  152. {
  153. int err, len;
  154. - char *ptr;
  155. + unsigned char *ptr;
  156. ptr = buf;
  157. len = play->nsamples;