Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

124 rindas
4.4KB

  1. /*
  2. TODO
  3. non-44100 sample rates
  4. u-law encoding
  5. */
  6. var audioFileChooser = document.getElementById('audioFileChooser');
  7. audioFileChooser.addEventListener('change', readFile);
  8. function readFile() {
  9. for(var i = 0; i < audioFileChooser.files.length; i++) {
  10. var fileReader = new FileReader();
  11. fileReader.readAsArrayBuffer(audioFileChooser.files[i]);
  12. fileReader.addEventListener('load', function(fileName, ev) {
  13. processFile(ev.target.result, fileName);
  14. }.bind(null, audioFileChooser.files[i].name));
  15. }
  16. }
  17. function processFile(file, fileName) {
  18. var context = new OfflineAudioContext(1,10*44100,44100);
  19. context.decodeAudioData(file, function(buffer) {
  20. var monoData = [];
  21. if(buffer.numberOfChannels == 1) {
  22. monoData = buffer.getChannelData(0);
  23. } else if(buffer.numberOfChannels == 2) {
  24. var leftData = buffer.getChannelData(0);
  25. var rightData = buffer.getChannelData(1);
  26. for(var i=0;i<buffer.length;i++) {
  27. monoData[i] = (leftData[i] + rightData[i]) / 2;
  28. }
  29. } else {
  30. alert("ONLY MONO AND STEREO FILES ARE SUPPORTED");
  31. }
  32. var outputData = [];
  33. for(var i=0;i<monoData.length;i+=2) {
  34. var a = floatToUnsignedInt16(monoData[i]);
  35. var b = floatToUnsignedInt16(monoData[i+1]);
  36. var out = (65536*b + a).toString(16);
  37. while(out.length < 8) out = '0' + out;
  38. out = '0x' + out;
  39. outputData.push(out);
  40. }
  41. var padLength = padding(outputData.length, 128);
  42. var statusInt = (outputData.length*2).toString(16);
  43. while(statusInt.length < 6) statusInt = '0' + statusInt;
  44. if(outputData.length*2>0xFFFFFF) alert("DATA TOO LONG");
  45. statusInt = '0x81' + statusInt;
  46. outputData.unshift(statusInt);
  47. for(var i=0;i<padLength;i++) {
  48. outputData.push('0x00000000');
  49. }
  50. var outputFileHolder = document.getElementById('outputFileHolder');
  51. var downloadLink1 = document.createElement('a');
  52. var downloadLink2 = document.createElement('a');
  53. var formattedName = fileName.split('.')[0];
  54. formattedName = formattedName.charAt(0).toUpperCase() + formattedName.slice(1).toLowerCase();
  55. downloadLink1.href = generateOutputFile(generateCPPFile(fileName, formattedName, outputData));
  56. downloadLink1.setAttribute('download', 'AudioSample' + formattedName + '.cpp');
  57. downloadLink1.innerHTML = 'Download AudioSample' + formattedName + '.cpp';
  58. downloadLink2.href = generateOutputFile(generateHeaderFile(formattedName, outputData));
  59. downloadLink2.setAttribute('download', 'AudioSample' + formattedName + '.h');
  60. downloadLink2.innerHTML = 'Download AudioSample' + formattedName + '.h';
  61. outputFileHolder.appendChild(downloadLink1);
  62. outputFileHolder.appendChild(document.createElement('br'));
  63. outputFileHolder.appendChild(downloadLink2);
  64. outputFileHolder.appendChild(document.createElement('br'));
  65. });
  66. }
  67. function floatToUnsignedInt16(f) {
  68. f = Math.max(-1, Math.min(1, f));
  69. var uint;
  70. // horrible hacks going on here - basically i don't understand bitwise operators
  71. if(f>=0) uint = Math.round(f * 32767);
  72. else uint = Math.round((f + 1) * 32767 + 32768);
  73. return uint;
  74. }
  75. // compute the extra padding needed
  76. function padding(sampleLength, block) {
  77. var extra = sampleLength % block;
  78. if (extra == 0) return 0;
  79. return block - extra;
  80. }
  81. function generateOutputFile(fileContents) {
  82. var textFileURL = null;
  83. var blob = new Blob([fileContents], {type: 'text/plain'});
  84. textFileURL = window.URL.createObjectURL(blob);
  85. return textFileURL;
  86. }
  87. function formatAudioData(audioData) {
  88. var outputString = '';
  89. for(var i = 0; i < audioData.length; i ++) {
  90. if(i%8==0 && i>0) outputString += '\n'
  91. outputString += audioData[i] + ',';
  92. }
  93. return outputString;
  94. }
  95. function generateCPPFile(fileName, formattedName, audioData) {
  96. var formattedName = fileName.split('.')[0];
  97. formattedName = formattedName.charAt(0).toUpperCase() + formattedName.slice(1).toLowerCase();
  98. var out = "";
  99. out += '// Audio data converted from audio file by wav2sketch_js\n\n';
  100. out += '#include "AudioSample' + formattedName + '.h"\n\n';
  101. out += 'const unsigned int AudioSample' + formattedName + '[' + audioData.length + '] = {\n';
  102. out += formatAudioData(audioData) + '\n};';
  103. return out;
  104. }
  105. function generateHeaderFile(formattedName, audioData) {
  106. var out = "";
  107. out += '// Audio data converted from audio file by wav2sketch_js\n\n';
  108. out += 'extern const unsigned int AudioSample' + formattedName + '[' + audioData.length + '];';
  109. return out;
  110. }