Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

104 lines
3.8KB

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