SID_sndio.i 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /*
  2. * Copyright (c) 2010 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. /* Based on SID_openbsd by Marc Espie. */
  17. extern "C" {
  18. #include "VIC.h"
  19. }
  20. #define FRAGSIZE (SAMPLE_FREQ / CALC_FREQ) /* samples in a fragment */
  21. void DigitalRenderer::init_sound(void)
  22. {
  23. struct sio_par par;
  24. ready = false;
  25. hdl = sio_open(NULL, SIO_PLAY, 0);
  26. if (hdl == NULL) {
  27. fprintf(stderr, "SID_sndio: unable to open device\n");
  28. return;
  29. }
  30. sio_initpar(&par);
  31. par.rate = SAMPLE_FREQ;
  32. par.pchan = 1;
  33. par.bits = 16;
  34. par.sig = 1;
  35. par.round = FRAGSIZE;
  36. par.appbufsz = FRAGSIZE * 2;
  37. if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par)) {
  38. fprintf(stderr, "SID_sndio: failure setting parameters.\n");
  39. sio_close(hdl);
  40. return;
  41. }
  42. if (par.rate != SAMPLE_FREQ || par.bits != 16 || par.sig != 1 ||
  43. par.pchan != 1) {
  44. fprintf(stderr, "SID_sndio: could not set desired parameters.\n");
  45. sio_close(hdl);
  46. return;
  47. } else {
  48. fprintf(stderr,
  49. "SID_sndio: selected 16 bits/%d hz linear encoding.\n",
  50. SAMPLE_FREQ);
  51. }
  52. if (!sio_start(hdl)) {
  53. fprintf(stderr, "SID_sndio: could not start sndio.\n");
  54. sio_close(hdl);
  55. return;
  56. }
  57. sound_calc_buf = new int16[FRAGSIZE];
  58. ready = true;
  59. }
  60. DigitalRenderer::~DigitalRenderer()
  61. {
  62. if (ready) {
  63. delete [] sound_calc_buf;
  64. if (hdl != NULL)
  65. sio_close(hdl);
  66. hdl = NULL;
  67. }
  68. }
  69. void DigitalRenderer::Pause(void)
  70. {
  71. }
  72. void DigitalRenderer::Resume(void)
  73. {
  74. }
  75. void DigitalRenderer::EmulateLine(void)
  76. {
  77. static int divisor = 0;
  78. static int to_output = 0;
  79. sample_buf[sample_in_ptr] = volume;
  80. sample_in_ptr = (sample_in_ptr + 1) % SAMPLE_BUF_SIZE;
  81. divisor += SAMPLE_FREQ;
  82. while (divisor >= 0) {
  83. divisor -= TOTAL_RASTERS * SCREEN_FREQ;
  84. to_output++;
  85. }
  86. if (!ready)
  87. return;
  88. while (to_output >= FRAGSIZE) {
  89. calc_buffer(sound_calc_buf, FRAGSIZE * 2);
  90. sio_write(hdl, sound_calc_buf, FRAGSIZE * 2);
  91. to_output -= FRAGSIZE;
  92. }
  93. }