demuopl.cpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. //
  2. // demuopl.cpp
  3. // SDLPal
  4. //
  5. // Created by palxex on 14-7-20.
  6. // Copyright (c) 2014年 Wei Mingzhi. All rights reserved.
  7. //
  8. #include "demuopl.h"
  9. #include <math.h>
  10. #include <stdlib.h> // rand()
  11. #include <string.h>
  12. int CDemuopl::channels = 0;
  13. struct OPLHandler {
  14. virtual void init(int rate) = 0;
  15. virtual void getsample(short *buf,int samples) = 0;
  16. virtual void write(int reg,int val) = 0;
  17. };
  18. namespace OPLCore {
  19. #include "dosbox_opl.cpp"
  20. struct DOSBoxOPLHandler : OPLHandler {
  21. void init(int rate) {
  22. adlib_init(rate);
  23. }
  24. void getsample(short *buf, int samples) {
  25. adlib_getsample(buf, samples);
  26. }
  27. void write(int reg, int val) {
  28. adlib_write(reg, val);
  29. }
  30. };
  31. }
  32. namespace OPLCore2 {
  33. #include "dosbox_opl.cpp"
  34. struct DOSBoxOPLHandler : OPLHandler {
  35. void init(int rate) {
  36. adlib_init(rate);
  37. }
  38. void getsample(short *buf, int samples) {
  39. adlib_getsample(buf, samples);
  40. }
  41. void write(int reg, int val) {
  42. adlib_write(reg, val);
  43. }
  44. };
  45. }
  46. CDemuopl::CDemuopl(int rate, bool bit16, bool usestereo)
  47. :use16bit(bit16), stereo(usestereo)
  48. {
  49. if (channels++ == 0)
  50. pHandler = new OPLCore::DOSBoxOPLHandler;
  51. else
  52. pHandler = new OPLCore2::DOSBoxOPLHandler;
  53. pHandler->init(rate);
  54. currType = TYPE_OPL2;
  55. }
  56. void CDemuopl::update(short *buf, int samples)
  57. {
  58. short *mixbuf1 = NULL;
  59. short *outbuf;
  60. if (use16bit) outbuf = buf;
  61. else{
  62. mixbuf1 = new short[samples * 2];
  63. outbuf = mixbuf1;
  64. }
  65. pHandler->getsample(outbuf, samples);
  66. if (stereo)
  67. for (int i = samples - 1; i >= 0; i--) {
  68. outbuf[i * 2] = outbuf[i];
  69. outbuf[i * 2 + 1] = outbuf[i];
  70. }
  71. //now reduce to 8bit if we need to
  72. if (!use16bit) {
  73. for (int i = 0; i < (stereo ? samples * 2 : samples); i++)
  74. ((char *)buf)[i] = (outbuf[i] >> 8) ^ 0x80;
  75. delete[] mixbuf1;
  76. }
  77. }
  78. // template methods
  79. void CDemuopl::write(int reg, int val)
  80. {
  81. pHandler->write(reg, val);
  82. };