PageRenderTime 53ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/app-showcase/walkie-talkie/recorder-worker.js

https://github.com/mayoz/pubnub-api
JavaScript | 160 lines | 106 code | 18 blank | 36 comment | 3 complexity | ed74bd94eb5657fd21b9f6df3dc1f254 MD5 | raw file
Possible License(s): Apache-2.0
  1. var recorded_samples = 0
  2. , recorded_buffers = []
  3. , channels = 1 // Mono or Stereo
  4. , sample_rate = 44100 // Sample Rate
  5. , bits = 16; // Bits Per Sample (16bit)
  6. /*
  7. PUBNUB.publish({
  8. channels : my_channel,
  9. message : 'init'
  10. });
  11. */
  12. this.onmessage = function(e){
  13. switch(e.data.command){
  14. case 'init':
  15. init(e.data.config);
  16. break;
  17. case 'record':
  18. record(e.data.buffer);
  19. break;
  20. case 'exportWAV':
  21. exportWAV(e.data.type);
  22. break;
  23. case 'clear':
  24. clear();
  25. break;
  26. }
  27. };
  28. function init(config) {
  29. channels = config.channels;
  30. sample_rate = config.sample_rate;
  31. bits = config.bits;
  32. }
  33. function record(inputBuffer){
  34. recorded_buffers.push(inputBuffer[0]);
  35. recorded_samples += inputBuffer[0].length;
  36. }
  37. function exportWAV(type) {
  38. var buffer = join_buffers( recorded_buffers, recorded_samples );
  39. var dataview = encodeWAV(buffer);
  40. //var dataview = encodeLowWAV(buffer);
  41. var audioBlob = new Blob( [dataview], { type : type } );
  42. this.postMessage(audioBlob);
  43. }
  44. function clear(){
  45. recorded_samples = 0;
  46. recorded_buffers = [];
  47. }
  48. function join_buffers( recorded_buffers, recorded_samples ) {
  49. var result = new Float32Array(recorded_samples);
  50. var offset = 0;
  51. for (var i = 0; i < recorded_buffers.length; i++){
  52. result.set(recorded_buffers[i], offset);
  53. offset += recorded_buffers[i].length;
  54. }
  55. return result;
  56. }
  57. /*jjjjjjj
  58. function interleave(inputL, inputR){
  59. var length = inputL.length + inputR.length;
  60. var result = new Float32Array(length);
  61. var index = 0,
  62. inputIndex = 0;
  63. while (index < length){
  64. result[index++] = inputL[inputIndex];
  65. result[index++] = inputR[inputIndex];
  66. inputIndex++;
  67. }
  68. return result;
  69. }
  70. */
  71. function floatTo16BitPCM( view, offset, samples ) {
  72. for (var i = 0; i < samples.length; i++, offset+=2) {
  73. var s = Math.max( -1, Math.min( 1, samples[i] ) );
  74. view.setInt16( offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true );
  75. }
  76. }
  77. function writeString( view, offset, string ) {
  78. for (var i = 0; i < string.length; i++) {
  79. view.setUint8( offset + i, string.charCodeAt(i) );
  80. }
  81. }
  82. function reduce_sample_rate(samples) {
  83. return samples.filter(function( sample, position ) {
  84. return !(position % 2);
  85. } );
  86. }
  87. function encodeLowWAV(samples) {
  88. var block_align = (channels * bits) / 8
  89. , byte_rate = sample_rate * block_align
  90. , data_size = (samples.length * bits) / 8
  91. , buffer = new ArrayBuffer(44 + data_size)
  92. , view = new DataView(buffer);
  93. writeString( view, 0, 'RIFF' );
  94. view.setUint32( 4, 32 + data_size, true ); //!!!
  95. writeString( view, 8, 'WAVE' );
  96. writeString( view, 12, 'fmt' );
  97. view.setUint32( 16, 16, true );
  98. view.setUint16( 20, 1, true );
  99. view.setUint16( 22, channels, true );
  100. view.setUint32( 24, sample_rate, true );
  101. view.setUint32( 28, byte_rate, true );
  102. view.setUint16( 32, block_align, true );
  103. view.setUint16( 34, bits, true );
  104. writeString( view, 36, 'data' );
  105. view.setUint32( 40, data_size, true ); //!!!
  106. floatTo16BitPCM( view, 44, samples );
  107. return view;
  108. }
  109. function encodeWAV(samples){
  110. var buffer = new ArrayBuffer(44 + samples.length * 2);
  111. var view = new DataView(buffer);
  112. /* RIFF identifier */
  113. writeString(view, 0, 'RIFF');
  114. /* file length */
  115. view.setUint32(4, 32 + samples.length * 2, true);
  116. /* RIFF type */
  117. writeString(view, 8, 'WAVE');
  118. /* format chunk identifier */
  119. writeString(view, 12, 'fmt ');
  120. /* format chunk length */
  121. view.setUint32(16, 16, true);
  122. /* sample format (raw) */
  123. view.setUint16(20, 1, true);
  124. /* channel count */
  125. view.setUint16(22, channels, true);
  126. /* sample rate */
  127. view.setUint32(24, sample_rate, true);
  128. /* byte rate (sample rate * block align) */
  129. view.setUint32(28, sample_rate * channels * 2, true);
  130. /* block align (channel count * bytes per sample) */
  131. view.setUint16(32, channels * 2, true);
  132. /* bits per sample */
  133. view.setUint16(34, 16, true);
  134. /* data chunk identifier */
  135. writeString(view, 36, 'data');
  136. /* data chunk length */
  137. view.setUint32(40, samples.length * 2, true);
  138. floatTo16BitPCM(view, 44, samples);
  139. return view;
  140. }