sndio_a.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Copyright (c) 2008 IWATA Ray <iwata@quasiquote.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 /* HAVE_CONFIG_H */
  19. #include <sndio.h>
  20. #include "timidity.h"
  21. #include "output.h"
  22. #include "controls.h"
  23. #include "timer.h"
  24. #include "instrum.h"
  25. #include "playmidi.h"
  26. #include "miditrace.h"
  27. static int open_output(void); /* 0=success, 1=warning, -1=fatal error */
  28. static void close_output(void);
  29. static int output_data(char *buf, int32 nbytes);
  30. static int acntl(int request, void *arg);
  31. /* export the playback mode */
  32. #define dpm sndio_play_mode
  33. PlayMode dpm = {
  34. DEFAULT_RATE, PE_SIGNED|PE_16BIT, PF_PCM_STREAM,
  35. -1,
  36. {0}, /* default: get all the buffer fragments you can */
  37. "sndio mode", 's',
  38. NULL,
  39. open_output,
  40. close_output,
  41. output_data,
  42. acntl
  43. };
  44. static struct sio_hdl *sndio_ctx;
  45. static int open_output(void)
  46. {
  47. static struct sio_par par, newpar;
  48. sndio_ctx = sio_open(NULL, SIO_PLAY, 0);
  49. if (sndio_ctx == NULL) {
  50. ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "sio_open() failed");
  51. return -1;
  52. }
  53. sio_initpar(&par);
  54. par.sig = 1;
  55. par.pchan = (dpm.encoding & PE_MONO) ? 1 : 2;
  56. par.le = SIO_LE_NATIVE;
  57. par.rate = dpm.rate;
  58. if (dpm.encoding & PE_24BIT) {
  59. par.bits = 24;
  60. par.bps = 3;
  61. } else if (dpm.encoding & PE_16BIT) {
  62. par.bits = 16;
  63. par.bps = 2;
  64. } else {
  65. par.bits = 8;
  66. par.bps = 1;
  67. }
  68. if (!sio_setpar(sndio_ctx, &par)) {
  69. ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "sio_setpar() failed");
  70. return -1;
  71. }
  72. if (sio_getpar(sndio_ctx, &newpar) == 0) {
  73. ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "sio_getpar() failed");
  74. return -1;
  75. }
  76. if (newpar.sig != par.sig ||
  77. newpar.le != par.le ||
  78. newpar.pchan != par.pchan ||
  79. newpar.bits != par.bits ||
  80. newpar.bps != par.bps ||
  81. newpar.rate * 1000 > par.rate * 1005 ||
  82. newpar.rate * 1000 < par.rate * 995) {
  83. ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "couldn't set output play parameters");
  84. return -1;
  85. }
  86. if (!sio_start(sndio_ctx)) {
  87. ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "sio_start() failed");
  88. return -1;
  89. }
  90. return 0;
  91. }
  92. static int output_data(char *buf, int32 nbytes)
  93. {
  94. if (!sio_write(sndio_ctx, buf, nbytes)) {
  95. ctl->cmsg(CMSG_WARNING, VERB_VERBOSE, "sio_write() failed");
  96. return -1;
  97. }
  98. return 0;
  99. }
  100. static void close_output(void)
  101. {
  102. if (sndio_ctx != NULL) {
  103. sio_close(sndio_ctx);
  104. sndio_ctx = NULL;
  105. }
  106. }
  107. static int acntl(int request, void *arg)
  108. {
  109. switch(request) {
  110. case PM_REQ_DISCARD:
  111. case PM_REQ_PLAY_START: /* Called just before playing */
  112. case PM_REQ_PLAY_END: /* Called just after playing */
  113. return 0;
  114. }
  115. return -1;
  116. }