You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 line
3.6KB

  1. var audioFileChooser = document.getElementById('audioFileChooser');
  2. audioFileChooser.addEventListener('change', readFile);
  3. function readFile() {
  4. // TODO: deal with multiple files
  5. var fileReader = new FileReader();
  6. fileReader.readAsArrayBuffer(audioFileChooser.files[0]);
  7. window.testFile = audioFileChooser;
  8. fileReader.addEventListener('load', function(ev) {
  9. processFile(ev.target.result, audioFileChooser.files[0].name);
  10. });
  11. }
  12. function processFile(file, fileName) {
  13. var context = new OfflineAudioContext(1,10*44100,44100);
  14. context.decodeAudioData(file, function(buffer) {
  15. var monoData = buffer.getChannelData(0); // start with mono, do stereo later
  16. var outputData = [];
  17. for(var i=0;i<monoData.length;i+=2) {
  18. var a = floatToUnsignedInt16(monoData[i]);
  19. var b = floatToUnsignedInt16(monoData[i+1]);
  20. var out = (65536*b + a).toString(16);
  21. while(out.length < 8) out = '0' + out;
  22. out = '0x' + out;
  23. outputData.push(out);
  24. }
  25. var padLength = padding(outputData.length, 128);
  26. var statusInt = (outputData.length*2).toString(16);
  27. while(statusInt.length < 4) statusInt = '0' + statusInt;
  28. statusInt = '0x8100' + statusInt;
  29. outputData.unshift(statusInt);
  30. for(var i=0;i<padLength;i++) {
  31. outputData.push('0x00000000');
  32. }
  33. var outputFileHolder = document.getElementById('outputFileHolder');
  34. var downloadLink1 = document.createElement('a');
  35. var downloadLink2 = document.createElement('a');
  36. var formattedName = fileName.split('.')[0];
  37. formattedName = formattedName.charAt(0).toUpperCase() + formattedName.slice(1).toLowerCase();
  38. downloadLink1.href = generateOutputFile(generateCPPFile(fileName, formattedName, outputData));
  39. downloadLink1.setAttribute('download', 'AudioSample' + formattedName + '.cpp');
  40. downloadLink1.innerHTML = 'Download AudioSample' + formattedName + '.cpp';
  41. downloadLink2.href = generateOutputFile(generateHeaderFile(formattedName, outputData));
  42. downloadLink2.setAttribute('download', 'AudioSample' + formattedName + '.h');
  43. downloadLink2.innerHTML = 'Download AudioSample' + formattedName + '.h';
  44. outputFileHolder.appendChild(downloadLink1);
  45. outputFileHolder.appendChild(document.createElement('br'));
  46. outputFileHolder.appendChild(downloadLink2);
  47. });
  48. }
  49. function floatToUnsignedInt16(f) {
  50. f = Math.max(-1, Math.min(1, f));
  51. var uint;
  52. // horrible hacks going on here - basically i don't understand bitwise operators
  53. if(f>=0) uint = Math.round(f * 32767);
  54. else uint = Math.round((f + 1) * 32767 + 32768);
  55. return uint;
  56. }
  57. // compute the extra padding needed
  58. function padding(sampleLength, block) {
  59. var extra = sampleLength % block;
  60. if (extra == 0) return 0;
  61. return block - extra;
  62. }
  63. function generateOutputFile(fileContents) {
  64. var textFileURL = null;
  65. var blob = new Blob([fileContents], {type: 'text/plain'});
  66. textFileURL = window.URL.createObjectURL(blob);
  67. return textFileURL;
  68. }
  69. function generateCPPFile(fileName, formattedName, audioData) {
  70. var formattedName = fileName.split('.')[0];
  71. formattedName = formattedName.charAt(0).toUpperCase() + formattedName.slice(1).toLowerCase();
  72. var out = "";
  73. out += '// Audio data converted from audio file by wav2sketch_js\n\n';
  74. out += '#include "AudioSample' + formattedName + '.h"\n\n';
  75. out += 'const unsigned int AudioSample' + formattedName + '[' + audioData.length + '] = {';
  76. out += audioData.join(',') + ',};';
  77. return out;
  78. }
  79. function generateHeaderFile(formattedName, audioData) {
  80. var out = "";
  81. out += '// Audio data converted from audio file by wav2sketch_js\n\n';
  82. out += 'extern const unsigned int AudioSample' + formattedName + '[' + audioData.length + '];';
  83. return out;
  84. }