dbemuopl.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /* -*- mode: c; tab-width: 4; c-basic-offset: 4; c-file-style: "linux" -*- */
  2. //
  3. // Copyright (c) 2009, Wei Mingzhi <whistler_wmz@users.sf.net>.
  4. // All rights reserved.
  5. // Created by Lou Yihua <louyihua@21cn.com>, 2015-08-03.
  6. //
  7. // This file is part of SDLPAL.
  8. //
  9. // SDLPAL 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 3 of the License, or
  12. // (at your option) any later version.
  13. //
  14. // This program 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, see <http://www.gnu.org/licenses/>.
  21. //
  22. #include "dbemuopl.h"
  23. #include <stdlib.h>
  24. bool CDBemuopl::_inited = DBOPL::InitTables();
  25. static inline int16_t conver_to_int16(int32_t sample)
  26. {
  27. if (sample > 32767)
  28. return 32767;
  29. else if (sample < -32768)
  30. return -32768;
  31. else
  32. return (int16_t)sample;
  33. }
  34. static inline uint8_t conver_to_uint8(int32_t sample)
  35. {
  36. if (sample > 32767)
  37. return 0xff;
  38. else if (sample < -32768)
  39. return 0;
  40. else
  41. return (uint8_t)(sample >> 8) ^ 0x80;
  42. }
  43. CDBemuopl::CDBemuopl(int rate, bool bit16, bool usestereo)
  44. : buffer(NULL), rate(rate), maxlen(0)
  45. , use16bit(bit16), stereo(usestereo)
  46. {
  47. currType = TYPE_OPL2;
  48. chip.Setup(rate);
  49. }
  50. CDBemuopl::~CDBemuopl()
  51. {
  52. if (buffer) delete[] buffer;
  53. }
  54. void CDBemuopl::init()
  55. {
  56. chip.Setup(rate);
  57. }
  58. void CDBemuopl::update(short *buf, int samples)
  59. {
  60. if (chip.opl3Active)
  61. update_opl3(buf, samples);
  62. else
  63. update_opl2(buf, samples);
  64. }
  65. void CDBemuopl::write(int reg, int val)
  66. {
  67. chip.WriteReg(reg, (Bit8u)val);
  68. }
  69. // OPL3 generate stereo samples
  70. void CDBemuopl::update_opl3(short *buf, int samples)
  71. {
  72. if (maxlen < samples * 2)
  73. {
  74. if (buffer) delete[] buffer;
  75. buffer = new int32_t[maxlen = samples * 2];
  76. }
  77. chip.GenerateBlock3(samples, buffer);
  78. if (use16bit)
  79. {
  80. if (stereo)
  81. {
  82. for (int i = 0; i < samples * 2; i++)
  83. buf[i] = conver_to_int16(buffer[i]);
  84. }
  85. else
  86. {
  87. for (int i = 0; i < samples; i++)
  88. buf[i] = conver_to_int16((buffer[i * 2] + buffer[i * 2 + 1]) >> 1);
  89. }
  90. }
  91. else
  92. {
  93. uint8_t* outbuf = (uint8_t*)buf;
  94. if (stereo)
  95. {
  96. for (int i = 0; i < samples * 2; i++)
  97. outbuf[i] = conver_to_uint8(buffer[i]);
  98. }
  99. else
  100. {
  101. for (int i = 0; i < samples; i++)
  102. outbuf[i] = conver_to_uint8((buffer[i * 2] + buffer[i * 2 + 1]) >> 1);
  103. }
  104. }
  105. }
  106. // OPL2 generate mono samples
  107. void CDBemuopl::update_opl2(short *buf, int samples)
  108. {
  109. if (maxlen < samples)
  110. {
  111. if (buffer) delete[] buffer;
  112. buffer = new int32_t[maxlen = samples];
  113. }
  114. chip.GenerateBlock2(samples, buffer);
  115. if (use16bit)
  116. {
  117. if (stereo)
  118. {
  119. for (int i = 0; i < samples; i++)
  120. buf[i * 2 + 1] = buf[i * 2] = conver_to_int16(buffer[i]);
  121. }
  122. else
  123. {
  124. for (int i = 0; i < samples; i++)
  125. buf[i] = conver_to_int16(buffer[i]);
  126. }
  127. }
  128. else
  129. {
  130. uint8_t* outbuf = (uint8_t*)buf;
  131. if (stereo)
  132. {
  133. for (int i = 0; i < samples; i++)
  134. outbuf[i * 2 + 1] = outbuf[i * 2] = conver_to_uint8(buffer[i]);
  135. }
  136. else
  137. {
  138. for (int i = 0; i < samples; i++)
  139. outbuf[i] = conver_to_uint8(buffer[i]);
  140. }
  141. }
  142. }