PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/client/public/jsmad/frame.js

https://github.com/dekz/pianode
JavaScript | 417 lines | 265 code | 94 blank | 58 comment | 69 complexity | 83baff71712aea0cfac704ea2942236d MD5 | raw file
  1. var bitrate_table /* [5][15] */ = [
  2. /* MPEG-1 */
  3. [ 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */
  4. 256000, 288000, 320000, 352000, 384000, 416000, 448000 ],
  5. [ 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */
  6. 128000, 160000, 192000, 224000, 256000, 320000, 384000 ],
  7. [ 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */
  8. 112000, 128000, 160000, 192000, 224000, 256000, 320000 ],
  9. /* MPEG-2 LSF */
  10. [ 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */
  11. 128000, 144000, 160000, 176000, 192000, 224000, 256000 ],
  12. [ 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layers */
  13. 64000, 80000, 96000, 112000, 128000, 144000, 160000 ] /* II & III */
  14. ];
  15. var samplerate_table /* [3] */ = [ 44100, 48000, 32000 ];
  16. var decoder_table = [
  17. function() { console.log("Layer I decoding is not implemented!"); },
  18. function() { console.log("Layer II decoding is not implemented!"); },
  19. Mad.layer_III
  20. ];
  21. Mad.Layer = {
  22. I: 1,
  23. II: 2,
  24. III: 3
  25. };
  26. Mad.Mode = {
  27. SINGLE_CHANNEL : 0,
  28. DUAL_CHANNEL : 1, /* dual channel */
  29. JOINT_STEREO : 2, /* joint (MS/intensity) stereo */
  30. STEREO : 3 /* normal LR stereo */
  31. };
  32. Mad.Emphasis = {
  33. NONE : 0, /* no emphasis */
  34. _50_15_US : 1, /* 50/15 microseconds emphasis */
  35. CCITT_J_17 : 3, /* CCITT J.17 emphasis */
  36. RESERVED : 2 /* unknown emphasis */
  37. };
  38. Mad.Header = function () {
  39. this.layer = 0; /* audio layer (1, 2, or 3) */
  40. this.mode = 0; /* channel mode (see above) */
  41. this.mode_extension = 0; /* additional mode info */
  42. this.emphasis = 0; /* de-emphasis to use (see above) */
  43. this.bitrate = 0; /* stream bitrate (bps) */
  44. this.samplerate = 0; /* sampling frequency (Hz) */
  45. this.crc_check = 0; /* frame CRC accumulator */
  46. this.crc_target = 0; /* final target CRC checksum */
  47. this.flags = 0; /* flags (see below) */
  48. this.private_bits = 0; /* private bits (see below) */
  49. //this.duration = mad_timer_zero; /* audio playing time of frame */
  50. };
  51. Mad.Header.prototype.nchannels = function () {
  52. return this.mode == 0 ? 1 : 2;
  53. }
  54. Mad.Header.prototype.nbsamples = function() {
  55. return (this.layer == Mad.Layer.I ? 12 :
  56. ((this.layer == Mad.Layer.III && (this.flags & Mad.Flag.LSF_EXT)) ? 18 : 36));
  57. }
  58. /* libmad's decode_header */
  59. Mad.Header.actually_decode = function(stream) {
  60. var header = new Mad.Header();
  61. header.flags = 0;
  62. header.private_bits = 0;
  63. /* header() */
  64. /* syncword */
  65. stream.ptr.skip(11);
  66. /* MPEG 2.5 indicator (really part of syncword) */
  67. if (stream.ptr.read(1) == 0) {
  68. header.flags |= Mad.Flag.MPEG_2_5_EXT;
  69. }
  70. /* ID */
  71. if (stream.ptr.read(1) == 0) {
  72. header.flags |= Mad.Flag.LSF_EXT;
  73. } else if (header.flags & Mad.Flag.MPEG_2_5_EXT) {
  74. stream.error = Mad.Error.LOSTSYNC;
  75. return null;
  76. }
  77. /* layer */
  78. header.layer = 4 - stream.ptr.read(2);
  79. if (header.layer == 4) {
  80. stream.error = Mad.Error.BADLAYER;
  81. return header;
  82. }
  83. /* protection_bit */
  84. if (stream.ptr.read(1) == 0) {
  85. header.flags |= Mad.Flag.PROTECTION;
  86. // TODO: crc
  87. //header.crc_check = mad_bit_crc(stream.ptr, 16, 0xffff);
  88. stream.ptr.skip(16);
  89. }
  90. /* bitrate_index */
  91. var index = stream.ptr.read(4);
  92. if (index == 15) {
  93. stream.error = Mad.Error.BADBITRATE;
  94. return header;
  95. }
  96. if (header.flags & Mad.Flag.LSF_EXT) {
  97. header.bitrate = bitrate_table[3 + (header.layer >> 1)][index];
  98. } else {
  99. header.bitrate = bitrate_table[header.layer - 1][index];
  100. }
  101. /* sampling_frequency */
  102. index = stream.ptr.read(2);
  103. if (index == 3) {
  104. stream.error = Mad.Error.BADSAMPLERATE;
  105. return header;
  106. }
  107. header.samplerate = samplerate_table[index];
  108. if (header.flags & Mad.Flag.LSF_EXT) {
  109. header.samplerate /= 2;
  110. if (header.flags & Mad.Flag.MPEG_2_5_EXT)
  111. header.samplerate /= 2;
  112. }
  113. /* padding_bit */
  114. if (stream.ptr.read(1))
  115. header.flags |= Mad.Flag.PADDING;
  116. /* private_bit */
  117. if (stream.ptr.read(1))
  118. header.private_bits |= Mad.Private.HEADER;
  119. /* mode */
  120. header.mode = 3 - stream.ptr.read(2);
  121. /* mode_extension */
  122. header.mode_extension = stream.ptr.read(2);
  123. /* copyright */
  124. if (stream.ptr.read(1))
  125. header.flags |= Mad.Flag.COPYRIGHT;
  126. /* original/copy */
  127. if (stream.ptr.read(1))
  128. header.flags |= Mad.Flag.ORIGINAL;
  129. /* emphasis */
  130. header.emphasis = stream.ptr.read(2);
  131. /* error_check() */
  132. /* crc_check */
  133. if (header.flags & Mad.Flag.PROTECTION)
  134. header.crc_target = stream.ptr.read(16);
  135. return header;
  136. }
  137. /* libmad's mad_header_decode */
  138. Mad.Header.decode = function(stream) {
  139. var header = null;
  140. // those are actually pointers. javascript powa.
  141. var ptr = stream.next_frame;
  142. var end = stream.bufend;
  143. var pad_slot = 0;
  144. var N = 0;
  145. /* stream skip */
  146. if (stream.skiplen) {
  147. if (!stream.sync)
  148. ptr = stream.this_frame;
  149. if (end - ptr < stream.skiplen) {
  150. stream.skiplen -= end - ptr;
  151. stream.next_frame = end;
  152. stream.error = Mad.Error.BUFLEN;
  153. return null;
  154. }
  155. ptr += stream.skiplen;
  156. stream.skiplen = 0;
  157. stream.sync = 1;
  158. }
  159. // emulating goto in JS, yay! this was a 'sync:' label
  160. var syncing = true;
  161. while(syncing) {
  162. syncing = false;
  163. /* synchronize */
  164. try {
  165. if (stream.sync) {
  166. if (end - ptr < Mad.BUFFER_GUARD) {
  167. stream.next_frame = ptr;
  168. stream.error = Mad.Error.BUFLEN;
  169. return null;
  170. } else if (!(stream.getU8(ptr) == 0xff && (stream.getU8(ptr + 1) & 0xe0) == 0xe0)) {
  171. /* mark point where frame sync word was expected */
  172. stream.this_frame = ptr;
  173. stream.next_frame = ptr + 1;
  174. stream.error = Mad.Error.LOSTSYNC;
  175. return null;
  176. }
  177. } else {
  178. stream.ptr = new Mad.Bit(stream.stream, ptr);
  179. if (stream.doSync() == -1) {
  180. if (end - stream.next_frame >= Mad.BUFFER_GUARD)
  181. stream.next_frame = end - Mad.BUFFER_GUARD;
  182. stream.error = Mad.Error.BUFLEN;
  183. return null;
  184. }
  185. ptr = stream.ptr.nextbyte();
  186. }
  187. } catch (e) {
  188. console.log("Synchronization error: " + e);
  189. stream.error = Mad.Error.BUFLEN;
  190. return null;
  191. }
  192. /* begin processing */
  193. stream.this_frame = ptr;
  194. stream.next_frame = ptr + 1; /* possibly bogus sync word */
  195. stream.ptr = new Mad.Bit(stream.stream, stream.this_frame);
  196. header = Mad.Header.actually_decode(stream);
  197. if(header == null) return null; // well Duh^2
  198. // console.log("============= Decoding layer " + header.layer + " audio mode " +
  199. // header.mode + " with " + header.bitrate +
  200. // " bps and a samplerate of " + header.samplerate);
  201. /* calculate frame duration */
  202. //mad_timer_set(&header.duration, 0, 32 * MAD_NSBSAMPLES(header), header.samplerate);
  203. /* calculate free bit rate */
  204. if (header.bitrate == 0) {
  205. console.log("Uh oh, a free bitrate stream. We're fucked.");
  206. stream.error = Mad.Error.BADDATAPTR; // best guess
  207. return null;
  208. // if ((stream.freerate == 0 || !stream.sync ||
  209. // (header.layer == Mad.Layer.III && stream.freerate > 640000)) &&
  210. // free_bitrate(stream, header) == -1)
  211. // return null;
  212. //
  213. // header.bitrate = stream.freerate;
  214. // header.flags |= Mad.Flag.FREEFORMAT;
  215. }
  216. /* calculate beginning of next frame */
  217. pad_slot = (header.flags & Mad.Flag.PADDING) ? 1 : 0;
  218. if (header.layer == Mad.Layer.I) {
  219. N = (((12 * header.bitrate / header.samplerate) << 0) + pad_slot) * 4;
  220. } else {
  221. var slots_per_frame = (header.layer == Mad.Layer.III &&
  222. (header.flags & Mad.Flag.LSF_EXT)) ? 72 : 144;
  223. //console.log("slots_per_frame = " + slots_per_frame + ", bitrate = " + header.bitrate + ", samplerate = " + header.samplerate);
  224. N = ((slots_per_frame * header.bitrate / header.samplerate) << 0) + pad_slot;
  225. }
  226. /* verify there is enough data left in buffer to decode this frame */
  227. if (N + Mad.BUFFER_GUARD > end - stream.this_frame) {
  228. stream.next_frame = stream.this_frame;
  229. stream.error = Mad.Error.BUFLEN;
  230. return null;
  231. }
  232. stream.next_frame = stream.this_frame + N;
  233. // console.log("N = " + N + ", pad_slot = " + pad_slot + ", next_frame = " + stream.next_frame);
  234. if (!stream.sync) {
  235. /* check that a valid frame header follows this frame */
  236. ptr = stream.next_frame;
  237. if (!(stream.getU8(ptr) == 0xff && (stream.getU8(ptr + 1) & 0xe0) == 0xe0)) {
  238. ptr = stream.next_frame = stream.this_frame + 1;
  239. // emulating 'goto sync'
  240. syncing = true;
  241. continue;
  242. }
  243. stream.sync = 1;
  244. }
  245. } // end of goto emulation (label 'sync')
  246. header.flags |= Mad.Flag.INCOMPLETE;
  247. return header;
  248. }
  249. Mad.Frame = function () {
  250. this.header = new Mad.Header(); /* MPEG audio header */
  251. this.options = 0; /* decoding options (from stream) */
  252. // sbsample[2][36][32]
  253. this.sbsample = []; /* synthesis subband filter samples */
  254. for(var ch = 0; ch < 2; ch++) {
  255. this.sbsample[ch] = [];
  256. for(var grp = 0; grp < 36; grp++) {
  257. // this.sbsample[ch][grp] = new Float64Array(new ArrayBuffer(8 * 32));
  258. this.sbsample[ch][grp] = [];
  259. for(var i = 0; i < 32; i++) {
  260. this.sbsample[ch][grp][i] = 0;
  261. }
  262. }
  263. }
  264. // overlap[2][32][18]
  265. this.overlap = []; /* Layer III block overlap data */
  266. for(var ch = 0; ch < 2; ch++) {
  267. this.overlap[ch] = [];
  268. for(var sb = 0; sb < 32; sb++) {
  269. // this.overlap[ch][sb] = new Float64Array(new ArrayBuffer(8 * 18));
  270. this.overlap[ch][sb] = [];
  271. for(var i = 0; i < 18; i++) {
  272. this.overlap[ch][sb][i] = 0;
  273. }
  274. }
  275. }
  276. };
  277. Mad.Frame.decode = function(frame, stream) {
  278. if (stream.options != null) {
  279. frame.options = stream.options;
  280. }
  281. /* header() */
  282. /* error_check() */
  283. if (!(frame.header.flags & Mad.Flag.INCOMPLETE)) {
  284. frame.header = Mad.Header.decode(stream);
  285. if(frame.header == null) {
  286. // something went wrong
  287. return null;
  288. }
  289. }
  290. /* audio_data() */
  291. frame.header.flags &= ~Mad.Flag.INCOMPLETE;
  292. // TODO: actually decode the data :)
  293. if (decoder_table[frame.header.layer - 1](stream, frame) == -1) {
  294. if (!Mad.recoverable(stream.error))
  295. stream.next_frame = stream.this_frame;
  296. return null;
  297. }
  298. return frame;
  299. };
  300. Mad.sbsampleIndex = function (i, j, k) {
  301. return i * 36 * 32 + j * 32 + k;
  302. };
  303. Mad.overlapIndex = function (i, j, k) {
  304. return i * 32 * 18 + j * 18 + k;
  305. };
  306. Mad.Flag = {
  307. NPRIVATE_III : 0x0007, /* number of Layer III private bits */
  308. INCOMPLETE : 0x0008, /* header but not data is decoded */
  309. PROTECTION : 0x0010, /* frame has CRC protection */
  310. COPYRIGHT : 0x0020, /* frame is copyright */
  311. ORIGINAL : 0x0040, /* frame is original (else copy) */
  312. PADDING : 0x0080, /* frame has additional slot */
  313. I_STEREO : 0x0100, /* uses intensity joint stereo */
  314. MS_STEREO : 0x0200, /* uses middle/side joint stereo */
  315. FREEFORMAT : 0x0400, /* uses free format bitrate */
  316. LSF_EXT : 0x1000, /* lower sampling freq. extension */
  317. MC_EXT : 0x2000, /* multichannel audio extension */
  318. MPEG_2_5_EXT : 0x4000 /* MPEG 2.5 (unofficial) extension */
  319. };
  320. Mad.Private = {
  321. HEADER : 0x0100, /* header private bit */
  322. III : 0x001f /* Layer III private bits (up to 5) */
  323. };