AudioRenderer.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /**
  2. * Created by wangweijie5 on 2016/12/16.
  3. */
  4. "use strict";
  5. var _createClass = function () {
  6. function defineProperties(target, props) {
  7. for (var i = 0; i < props.length; i++) {
  8. var descriptor = props[i];
  9. descriptor.enumerable = descriptor.enumerable || false;
  10. descriptor.configurable = true;
  11. if ("value" in descriptor) descriptor.writable = true;
  12. Object.defineProperty(target, descriptor.key, descriptor);
  13. }
  14. }
  15. return function (Constructor, protoProps, staticProps) {
  16. if (protoProps) defineProperties(Constructor.prototype, protoProps);
  17. if (staticProps) defineProperties(Constructor, staticProps);
  18. return Constructor;
  19. };
  20. }();
  21. function _classCallCheck(instance, Constructor) {
  22. if (!(instance instanceof Constructor)) {
  23. throw new TypeError("Cannot call a class as a function");
  24. }
  25. }
  26. var __instance = function () {
  27. var instance = void 0;
  28. return function (newInstance) {
  29. if (newInstance) instance = newInstance;
  30. return instance;
  31. };
  32. }();
  33. var AudioRenderer = function () {
  34. function AudioRenderer() {
  35. _classCallCheck(this, AudioRenderer);
  36. if (__instance()) return __instance();
  37. // 确保只有单例
  38. if (AudioRenderer.unique !== undefined) {
  39. return AudioRenderer.unique;
  40. }
  41. AudioRenderer.unique = this;
  42. this.oAudioContext = null;
  43. this.currentVolume = 0.8; // 初始音量
  44. this.bSetVolume = false;
  45. this.gainNode = null;
  46. this.iWndNum = -1; // 窗口号
  47. this.mVolumes = new Map(); // 用于存储所有音量
  48. // Init AudioContext
  49. var AudioContext = window.AudioContext || window.webkitAudioContext;
  50. this.oAudioContext = new AudioContext();
  51. this.writeString = function (view, offset, string) {
  52. for (var i = 0; i < string.length; i++) {
  53. view.setUint8(offset + i, string.charCodeAt(i));
  54. }
  55. };
  56. this.setBufferToDataview = function (output, offset, input) {
  57. for (var i = 0; i < input.length; i++, offset++) {
  58. output.setUint8(offset, input[i]);
  59. }
  60. };
  61. __instance(this);
  62. }
  63. /**
  64. * @synopsis 音频播放
  65. *
  66. * @param dataBuf [IN] 音频缓存
  67. * @param dataLen [IN] 缓存长度
  68. * @param audioInfo [IN] 音频参数
  69. *
  70. * @returns 状态码
  71. */
  72. _createClass(AudioRenderer, [{
  73. key: 'Play',
  74. value: function Play(dataBuf, dataLen, audioInfo) {
  75. var bufferData = new ArrayBuffer(44 + dataLen);
  76. var viewTalk = new DataView(bufferData);
  77. var sampleRates = audioInfo.samplesPerSec;
  78. var channels = audioInfo.channels;
  79. var bitsPerSample = audioInfo.bitsPerSample;
  80. //console.log("audiorender sampleRates"+sampleRates+"channels:"+channels+"bitsPerSample:"+bitsPerSample);
  81. /* RIFF identifier */
  82. this.writeString(viewTalk, 0, 'RIFF');
  83. /* file length */
  84. viewTalk.setUint32(4, 32 + dataLen * 2, true);
  85. /* RIFF type */
  86. this.writeString(viewTalk, 8, 'WAVE');
  87. /* format chunk identifier */
  88. this.writeString(viewTalk, 12, 'fmt ');
  89. /* format chunk length */
  90. viewTalk.setUint32(16, 16, true);
  91. /* sample format (raw) */
  92. viewTalk.setUint16(20, 1, true);
  93. /* channel count */
  94. viewTalk.setUint16(22, channels, true);
  95. /* sample rate */
  96. viewTalk.setUint32(24, sampleRates, true);
  97. /* byte rate (sample rate * block align) */
  98. viewTalk.setUint32(28, sampleRates * 2, true);
  99. /* block align (channel count * bytes per sample)/8 */
  100. viewTalk.setUint16(32, channels * bitsPerSample / 8, true);
  101. /* bits per sample */
  102. viewTalk.setUint16(34, bitsPerSample, true);
  103. /* data chunk identifier */
  104. this.writeString(viewTalk, 36, 'data');
  105. /* data chunk length */
  106. viewTalk.setUint32(40, dataLen, true);
  107. this.setBufferToDataview(viewTalk, 44, dataBuf);
  108. var self = this;
  109. this.oAudioContext.decodeAudioData(viewTalk.buffer, function (buffer) {
  110. var bufferSource = self.oAudioContext.createBufferSource();
  111. if (bufferSource == null) {
  112. return -1;
  113. }
  114. bufferSource.buffer = buffer;
  115. bufferSource.start(0);
  116. if (self.gainNode == null || self.bSetVolume) {
  117. self.gainNode = self.oAudioContext.createGain();
  118. // self.gainNode.gain.value = self.currentVolume;
  119. // // self.currentVolume = self.gainNode.gain.value;
  120. // self.gainNode.connect(self.oAudioContext.destination);
  121. self.bSetVolume = false;
  122. }
  123. self.gainNode.gain.value = self.currentVolume;
  124. // self.currentVolume = self.gainNode.gain.value;
  125. self.gainNode.connect(self.oAudioContext.destination);
  126. bufferSource.connect(self.gainNode);
  127. }, function (e) {
  128. console.log("decode error");
  129. return -1;
  130. });
  131. return 0;
  132. }
  133. /**
  134. * @synopsis 停止播放
  135. *
  136. * @returns 返回音量
  137. */
  138. }, {
  139. key: 'Stop',
  140. value: function Stop() {
  141. if (this.gainNode != null) {
  142. this.gainNode.disconnect();
  143. this.gainNode = null;
  144. }
  145. // this.oAudioContext.close();
  146. // AudioRenderer.unique = undefined;
  147. // __instance() = null;
  148. return true;
  149. }
  150. /**
  151. * @synopsis 设置音量
  152. *
  153. * @param iVolume [IN] 音量
  154. *
  155. * @returns 状态码
  156. */
  157. }, {
  158. key: 'SetVolume',
  159. value: function SetVolume(iVolume) {
  160. this.bSetVolume = true;
  161. this.currentVolume = iVolume;
  162. // 储存当前窗口设置音量值
  163. this.mVolumes.set(this.iWndNum, iVolume);
  164. return true;
  165. }
  166. /**
  167. * @synopsis 设置窗口号
  168. *
  169. * @param iWndNum [IN] 窗口号
  170. *
  171. * @returns 状态码
  172. */
  173. }, {
  174. key: 'SetWndNum',
  175. value: function SetWndNum(iWndNum) {
  176. this.iWndNum = iWndNum;
  177. // 获取当前窗口设置音量值
  178. var iVolume = this.mVolumes.get(iWndNum);
  179. if (iVolume == undefined) {
  180. iVolume = 0.8; // 默认音量
  181. }
  182. this.currentVolume = iVolume;
  183. return true;
  184. }
  185. /**
  186. * @synopsis 获取音量
  187. *
  188. * @returns 返回音量
  189. */
  190. }, {
  191. key: 'GetVolume',
  192. value: function GetVolume() {
  193. // 获取当前窗口设置音量值
  194. var iVolume = this.mVolumes.get(this.iWndNum);
  195. if (iVolume == undefined) {
  196. iVolume = 0.8; // 默认音量
  197. }
  198. return iVolume;
  199. }
  200. }]);
  201. return AudioRenderer;
  202. }();
  203. //# sourceMappingURL=AudioRenderer.js.map