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.

78 line
2.8KB

  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. for(var i=0;i<padLength;i++) {
  27. outputData.push('0x00000000');
  28. }
  29. var outputFileHolder = document.getElementById('outputFileHolder');
  30. var downloadLink = document.createElement('a');
  31. var formattedName = fileName.split('.')[0];
  32. formattedName = formattedName.charAt(0).toUpperCase() + formattedName.slice(1).toLowerCase();
  33. downloadLink.href = generateOutputFile(generateCPPFile(fileName, formattedName, outputData));
  34. downloadLink.setAttribute('download', 'AudioSample' + formattedName + '.cpp');
  35. downloadLink.innerHTML = 'download link';
  36. outputFileHolder.appendChild(downloadLink);
  37. });
  38. }
  39. function floatToUnsignedInt16(f) {
  40. f = Math.max(-1, Math.min(1, f));
  41. var uint;
  42. // horrible hacks going on here - basically i don't understand bitwise operators
  43. if(f>=0) uint = Math.round(f * 32767);
  44. else uint = Math.round((f + 1) * 32767 + 32768);
  45. return uint;
  46. }
  47. // compute the extra padding needed
  48. function padding(sampleLength, block) {
  49. var extra = sampleLength % block;
  50. if (extra == 0) return 0;
  51. return block - extra;
  52. }
  53. function generateOutputFile(fileContents) {
  54. var textFileURL = null;
  55. var blob = new Blob([fileContents], {type: 'text/plain'});
  56. textFileURL = window.URL.createObjectURL(blob);
  57. return textFileURL;
  58. }
  59. function generateCPPFile(fileName, formattedName, audioData) {
  60. var formattedName = fileName.split('.')[0];
  61. formattedName = formattedName.charAt(0).toUpperCase() + formattedName.slice(1).toLowerCase();
  62. var out = "";
  63. out += '// Audio data converted from audio file by wav2sketch_js\n\n';
  64. out += '#include "AudioSample' + formattedName + '.h"\n\n';
  65. out += 'const unsigned int AudioSample' + formattedName + '[' + audioData.length + '] = {';
  66. out += audioData.join(',') + ',};';
  67. return out;
  68. }