sndioplayer.cc 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /*
  2. * Copyright (c) 2009 Jacob Meuser <jakemsr@sdf.lonestar.org>
  3. *
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. */
  16. #ifdef HAVE_CONFIG_H
  17. # include "config.h"
  18. #endif
  19. #ifdef WANT_SNDIO
  20. #include <stdio.h>
  21. #include <unistd.h>
  22. #include <stdlib.h>
  23. #include <poll.h>
  24. #include <sndio.h>
  25. #include "mpegsound.h"
  26. #include "mpegsound_locals.h"
  27. Sndioplayer::Sndioplayer()
  28. {
  29. this->hdl = NULL;
  30. }
  31. Sndioplayer::~Sndioplayer()
  32. {
  33. if (this->hdl) {
  34. sio_close(this->hdl);
  35. this->hdl = NULL;
  36. }
  37. }
  38. void
  39. Sndioplayer::abort()
  40. {
  41. }
  42. bool
  43. Sndioplayer::setsoundtype(int stereo, int samplesize, int speed)
  44. {
  45. debug("Sndioplayer::setsoundtype()\n");
  46. rawstereo = stereo;
  47. rawsamplesize = samplesize;
  48. rawspeed = speed;
  49. return resetsoundtype();
  50. }
  51. void
  52. Sndioplayer::set8bitmode()
  53. {
  54. }
  55. bool
  56. Sndioplayer::resetsoundtype()
  57. {
  58. struct sio_par par;
  59. debug("Sndioplayer::resetsoundtype()\n");
  60. if (this->hdl) {
  61. sio_stop(this->hdl);
  62. } else {
  63. this->hdl = sio_open(NULL, SIO_PLAY, 0);
  64. if (!this->hdl) {
  65. debug("sio_open failed\n");
  66. seterrorcode(SOUND_ERROR_DEVOPENFAIL);
  67. return false;
  68. }
  69. }
  70. sio_initpar(&par);
  71. /* if one of these is 0, default to reasonable (CD audio) values */
  72. if (rawsamplesize == 0 || rawspeed == 0) {
  73. rawstereo = 1;
  74. rawsamplesize = 16;
  75. rawspeed = 44100;
  76. }
  77. par.pchan = (rawstereo ? 2 : 1);
  78. par.rate = rawspeed ? rawspeed : 44100;
  79. par.bits = rawsamplesize ? rawsamplesize : 16;
  80. par.sig = 1;
  81. par.appbufsz = 4096;
  82. if (!sio_setpar(this->hdl, &par) || !sio_getpar(this->hdl, &par)) {
  83. debug("sio_setpar failed\n");
  84. seterrorcode(SOUND_ERROR_DEVOPENFAIL);
  85. return false;
  86. }
  87. if (par.pchan != (rawstereo ? 2 : 1) || par.rate != rawspeed ||
  88. par.bits != rawsamplesize || par.sig != 1) {
  89. debug("could not configure sndio device as requested\n");
  90. debug("wanted/got: bits %d/%d, pchan %d/%d, rate %d/%d \n",
  91. rawsamplesize, par.bits, (rawstereo ? 2 : 1), par.pchan,
  92. rawspeed, par.rate);
  93. seterrorcode(SOUND_ERROR_DEVOPENFAIL);
  94. return false;
  95. }
  96. rawblocksize = par.round * par.bps * par.pchan;
  97. if (!sio_start(this->hdl)) {
  98. debug("sio_start failed\n");
  99. seterrorcode(SOUND_ERROR_DEVOPENFAIL);
  100. return false;
  101. }
  102. return true;
  103. }
  104. void
  105. Sndioplayer::releasedevice()
  106. {
  107. debug("Sndioplayer::releasedevice()\n");
  108. if (this->hdl) {
  109. sio_close(this->hdl);
  110. this->hdl = NULL;
  111. }
  112. }
  113. bool
  114. Sndioplayer::attachdevice()
  115. {
  116. debug("Sndioplayer::attachdevice()\n");
  117. if (!this->hdl)
  118. return resetsoundtype();
  119. return true;
  120. }
  121. bool
  122. Sndioplayer::putblock(void *buffer, int size)
  123. {
  124. struct pollfd pfd;
  125. nfds_t nfds;
  126. int ret, done;
  127. //debug("Sndioplayer::putblock(), size=%d\n", size);
  128. if (!this->hdl)
  129. return false;
  130. done = 0;
  131. while (done < size) {
  132. nfds = sio_pollfd(this->hdl, &pfd, POLLOUT);
  133. ret = poll(&pfd, nfds, INFTIM);
  134. if (!(sio_revents(this->hdl, &pfd) & POLLOUT))
  135. continue;
  136. ret = sio_write(this->hdl, (unsigned char *)buffer + done,
  137. size - done);
  138. if (!ret) {
  139. debug("sio_write failed\n");
  140. return false;
  141. }
  142. done += ret;
  143. }
  144. return true;
  145. }
  146. int
  147. Sndioplayer::putblock_nt(void *buffer, int size)
  148. {
  149. debug("Sndioplayer::putblock_nt(), size=%d\n", size);
  150. if (!this->hdl)
  151. return -1;
  152. return sio_write(this->hdl, buffer, size);
  153. }
  154. int
  155. Sndioplayer::getblocksize()
  156. {
  157. debug("Sndioplayer::getblocksize(), rawblocksize=%d\n", rawblocksize);
  158. return rawblocksize;
  159. }
  160. int
  161. Sndioplayer::fix_samplesize(void *buffer, int size)
  162. {
  163. (void)buffer;
  164. return size;
  165. }
  166. #endif /* WANT_SNDIO */