dbemuopl.cpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. //
  2. // dbemuopl.cpp
  3. // SDLPal
  4. //
  5. // Created by louyihua on 15-08-03.
  6. // Copyright (c) 2014 Wei Mingzhi. All rights reserved.
  7. //
  8. #include "dbemuopl.h"
  9. #include <stdlib.h>
  10. bool CDBemuopl::_inited = DBOPL::InitTables();
  11. static inline int16_t conver_to_int16(int32_t sample)
  12. {
  13. if (sample > 32767)
  14. return 32767;
  15. else if (sample < -32768)
  16. return -32768;
  17. else
  18. return (int16_t)sample;
  19. }
  20. static inline uint8_t conver_to_uint8(int32_t sample)
  21. {
  22. if (sample > 32767)
  23. return 0xff;
  24. else if (sample < -32768)
  25. return 0;
  26. else
  27. return (uint8_t)(sample >> 8) ^ 0x80;
  28. }
  29. CDBemuopl::CDBemuopl(int rate, bool bit16, bool usestereo)
  30. : use16bit(bit16), stereo(usestereo), rate(rate)
  31. , maxlen(0), buffer(NULL)
  32. {
  33. currType = TYPE_OPL2;
  34. chip.Setup(rate);
  35. }
  36. CDBemuopl::~CDBemuopl()
  37. {
  38. if (buffer) delete[] buffer;
  39. }
  40. void CDBemuopl::init()
  41. {
  42. chip.Setup(rate);
  43. }
  44. void CDBemuopl::update(short *buf, int samples)
  45. {
  46. if (chip.opl3Active)
  47. update_opl3(buf, samples);
  48. else
  49. update_opl2(buf, samples);
  50. }
  51. void CDBemuopl::write(int reg, int val)
  52. {
  53. chip.WriteReg(reg, (Bit8u)val);
  54. }
  55. // OPL3 generate stereo samples
  56. void CDBemuopl::update_opl3(short *buf, int samples)
  57. {
  58. if (maxlen < samples * 2)
  59. {
  60. if (buffer) delete[] buffer;
  61. buffer = new int32_t[maxlen = samples * 2];
  62. }
  63. chip.GenerateBlock3(samples, buffer);
  64. if (use16bit)
  65. {
  66. if (stereo)
  67. {
  68. for (int i = 0; i < samples * 2; i++)
  69. buf[i] = conver_to_int16(buffer[i]);
  70. }
  71. else
  72. {
  73. for (int i = 0; i < samples; i++)
  74. buf[i] = conver_to_int16((buffer[i * 2] + buffer[i * 2 + 1]) >> 1);
  75. }
  76. }
  77. else
  78. {
  79. uint8_t* outbuf = (uint8_t*)buf;
  80. if (stereo)
  81. {
  82. for (int i = 0; i < samples * 2; i++)
  83. outbuf[i] = conver_to_uint8(buffer[i]);
  84. }
  85. else
  86. {
  87. for (int i = 0; i < samples; i++)
  88. outbuf[i] = conver_to_uint8((buffer[i * 2] + buffer[i * 2 + 1]) >> 1);
  89. }
  90. }
  91. }
  92. // OPL2 generate mono samples
  93. void CDBemuopl::update_opl2(short *buf, int samples)
  94. {
  95. if (maxlen < samples)
  96. {
  97. if (buffer) delete[] buffer;
  98. buffer = new int32_t[maxlen = samples];
  99. }
  100. chip.GenerateBlock2(samples, buffer);
  101. if (use16bit)
  102. {
  103. if (stereo)
  104. {
  105. for (int i = 0; i < samples; i++)
  106. buf[i * 2 + 1] = buf[i * 2] = conver_to_int16(buffer[i]);
  107. }
  108. else
  109. {
  110. for (int i = 0; i < samples; i++)
  111. buf[i] = conver_to_int16(buffer[i]);
  112. }
  113. }
  114. else
  115. {
  116. uint8_t* outbuf = (uint8_t*)buf;
  117. if (stereo)
  118. {
  119. for (int i = 0; i < samples; i++)
  120. outbuf[i * 2 + 1] = outbuf[i * 2] = conver_to_uint8(buffer[i]);
  121. }
  122. else
  123. {
  124. for (int i = 0; i < samples; i++)
  125. outbuf[i] = conver_to_uint8(buffer[i]);
  126. }
  127. }
  128. }