audio_out_sndio.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * audio_out_sndio.c
  3. * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org>
  4. * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
  5. *
  6. * This file is part of a52dec, a free ATSC A-52 stream decoder.
  7. * See http://liba52.sourceforge.net/ for updates.
  8. *
  9. * a52dec is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * a52dec is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. */
  23. #include "config.h"
  24. #ifdef LIBAO_SNDIO
  25. #include <sndio.h>
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <inttypes.h>
  29. #include "a52.h"
  30. #include "audio_out.h"
  31. #include "audio_out_internal.h"
  32. typedef struct sndio_instance_s {
  33. ao_instance_t ao;
  34. struct sio_hdl *hdl;
  35. int sample_rate;
  36. int set_params;
  37. int flags;
  38. } sndio_instance_t;
  39. static int sndio_setup (ao_instance_t * _instance, int sample_rate, int * flags,
  40. level_t * level, sample_t * bias)
  41. {
  42. sndio_instance_t * instance = (sndio_instance_t *) _instance;
  43. if ((instance->set_params == 0) && (instance->sample_rate != sample_rate))
  44. return 1;
  45. instance->sample_rate = sample_rate;
  46. *flags = instance->flags;
  47. *level = CONVERT_LEVEL;
  48. *bias = CONVERT_BIAS;
  49. return 0;
  50. }
  51. static int sndio_play (ao_instance_t * _instance, int flags, sample_t * _samples)
  52. {
  53. sndio_instance_t * instance = (sndio_instance_t *) _instance;
  54. int16_t int16_samples[256*6];
  55. int chans = -1;
  56. #ifdef LIBA52_DOUBLE
  57. convert_t samples[256 * 6];
  58. int i;
  59. for (i = 0; i < 256 * 6; i++)
  60. samples[i] = _samples[i];
  61. #else
  62. convert_t * samples = _samples;
  63. #endif
  64. chans = channels_multi (flags);
  65. flags &= A52_CHANNEL_MASK | A52_LFE;
  66. if (instance->set_params) {
  67. struct sio_par par;
  68. sio_initpar(&par);
  69. par.bits = 16;
  70. par.sig = 1;
  71. par.le = SIO_LE_NATIVE;
  72. par.pchan = chans;
  73. par.rate = instance->sample_rate;
  74. if (!sio_setpar(instance->hdl, &par) || !sio_setpar(instance->hdl, &par)) {
  75. fprintf (stderr, "Can not set audio parameters\n");
  76. return 1;
  77. }
  78. if (par.bits != 16 || par.sig != 1 || par.le != SIO_LE_NATIVE ||
  79. par.pchan != chans || par.rate != instance->sample_rate) {
  80. fprintf (stderr, "Unsupported audio parameters\n");
  81. return 1;
  82. }
  83. instance->flags = flags;
  84. instance->set_params = 0;
  85. sio_start(instance->hdl);
  86. } else if ((flags == A52_DOLBY) && (instance->flags == A52_STEREO)) {
  87. fprintf (stderr, "Switching from stereo to dolby surround\n");
  88. instance->flags = A52_DOLBY;
  89. } else if ((flags == A52_STEREO) && (instance->flags == A52_DOLBY)) {
  90. fprintf (stderr, "Switching from dolby surround to stereo\n");
  91. instance->flags = A52_STEREO;
  92. } else if (flags != instance->flags)
  93. return 1;
  94. convert2s16_multi (samples, int16_samples, flags);
  95. sio_write (instance->hdl, int16_samples, 256 * sizeof (int16_t) * chans);
  96. return 0;
  97. }
  98. static void sndio_close (ao_instance_t * _instance)
  99. {
  100. sndio_instance_t * instance = (sndio_instance_t *) _instance;
  101. sio_close (instance->hdl);
  102. }
  103. static ao_instance_t * sndio_open (int flags)
  104. {
  105. sndio_instance_t * instance;
  106. int format;
  107. instance = (sndio_instance_t *) malloc (sizeof (sndio_instance_t));
  108. if (instance == NULL)
  109. return NULL;
  110. instance->ao.setup = sndio_setup;
  111. instance->ao.play = sndio_play;
  112. instance->ao.close = sndio_close;
  113. instance->sample_rate = 0;
  114. instance->set_params = 1;
  115. instance->flags = flags;
  116. instance->hdl = sio_open (SIO_DEVANY, SIO_PLAY, 0);
  117. if (instance->hdl == NULL) {
  118. fprintf (stderr, "Can not open " SIO_DEVANY " device\n");
  119. free (instance);
  120. return NULL;
  121. }
  122. return (ao_instance_t *) instance;
  123. }
  124. ao_instance_t * ao_sndio_open (void)
  125. {
  126. return sndio_open (A52_STEREO);
  127. }
  128. ao_instance_t * ao_sndiodolby_open (void)
  129. {
  130. return sndio_open (A52_DOLBY);
  131. }
  132. ao_instance_t * ao_sndio4_open (void)
  133. {
  134. return sndio_open (A52_2F2R);
  135. }
  136. ao_instance_t * ao_sndio6_open (void)
  137. {
  138. return sndio_open (A52_3F2R | A52_LFE);
  139. }
  140. #endif