Browse Source

tweaked padding and word creation mechanism to fix bug with unaligned wav

dds
Matt Bradshaw 6 years ago
parent
commit
a830d24607
1 changed files with 25 additions and 23 deletions
  1. +25
    -23
      extras/wav2sketch/wav2sketch.js

+ 25
- 23
extras/wav2sketch/wav2sketch.js View File

sampleRate = 44100; sampleRate = 44100;
} }
} else { } else {
console.log('using chosen sample rate of ' + sampleRateChoice);
sampleRate = sampleRateChoice; sampleRate = sampleRateChoice;
} }


var context = new OfflineAudioContext(1, 100*sampleRate, sampleRate); // 100 seconds for now
var context = new OfflineAudioContext(1, 100*sampleRate, sampleRate); // arbitrary 100 seconds max length for now, nothing that long would fit on a Teensy anyway
context.decodeAudioData(file, function(buffer) { context.decodeAudioData(file, function(buffer) {
console.log(buffer.sampleRate);
var monoData = []; var monoData = [];
if(buffer.numberOfChannels == 1) { if(buffer.numberOfChannels == 1) {
monoData = buffer.getChannelData(0); monoData = buffer.getChannelData(0);
alert("ONLY MONO AND STEREO FILES ARE SUPPORTED"); alert("ONLY MONO AND STEREO FILES ARE SUPPORTED");
// NB - would be trivial to add support for n channels, given that everything ends up mono anyway // NB - would be trivial to add support for n channels, given that everything ends up mono anyway
} }
var outputData = [];
for(var i=0;i<monoData.length;i+=2) {
var a = toUint16(monoData[i]*0x7fff);
var b = toUint16(monoData[i+1]*0x7fff);
var out = (65536*b + a).toString(16);
while(out.length < 8) out = '0' + out;
out = '0x' + out;
outputData.push(out);
}
var padLength; var padLength;
var compressionCode = '0'; var compressionCode = '0';
var sampleRateCode; var sampleRateCode;
if(true) compressionCode = '8'; // add u-law support here later if(true) compressionCode = '8'; // add u-law support here later
if(sampleRate == 44100) { if(sampleRate == 44100) {
padLength = padding(outputData.length/2, 128);
padLength = padding(monoData.length, 128);
sampleRateCode = '1'; sampleRateCode = '1';
} else if(sampleRate == 22050) { } else if(sampleRate == 22050) {
padLength = padding(outputData.length/2, 64);
padLength = padding(monoData.length, 64);
sampleRateCode = '2'; sampleRateCode = '2';
} else if(sampleRate == 11025) { } else if(sampleRate == 11025) {
padLength = padding(outputData.length/2, 32);
padLength = padding(monoData.length, 32);
sampleRateCode = '3'; sampleRateCode = '3';
} }


var statusInt = (outputData.length*2).toString(16);
var outputData = createWords(monoData, padLength);

var statusInt = (monoData.length).toString(16);
while(statusInt.length < 6) statusInt = '0' + statusInt; while(statusInt.length < 6) statusInt = '0' + statusInt;
if(outputData.length*2>0xFFFFFF) alert("DATA TOO LONG");
if(monoData.length>0xFFFFFF) alert("DATA TOO LONG");
statusInt = '0x' + compressionCode + sampleRateCode + statusInt; statusInt = '0x' + compressionCode + sampleRateCode + statusInt;
outputData.unshift(statusInt); outputData.unshift(statusInt);


for(var i=0;i<padLength/2;i++) {
outputData.push('0x00000000');
}

var outputFileHolder = document.getElementById('outputFileHolder'); var outputFileHolder = document.getElementById('outputFileHolder');
var downloadLink1 = document.createElement('a'); var downloadLink1 = document.createElement('a');
var downloadLink2 = document.createElement('a'); var downloadLink2 = document.createElement('a');
var formattedName = fileName.split('.')[0]; var formattedName = fileName.split('.')[0];
formattedName = formattedName.charAt(0).toUpperCase() + formattedName.slice(1).toLowerCase(); formattedName = formattedName.charAt(0).toUpperCase() + formattedName.slice(1).toLowerCase();
downloadLink1.href = generateOutputFile(generateCPPFile(fileName, formattedName, outputData));
downloadLink1.href = generateOutputFile(generateCPPFile(fileName, formattedName, outputData, sampleRate));
downloadLink1.setAttribute('download', 'AudioSample' + formattedName + '.cpp'); downloadLink1.setAttribute('download', 'AudioSample' + formattedName + '.cpp');
downloadLink1.innerHTML = 'Download AudioSample' + formattedName + '.cpp'; downloadLink1.innerHTML = 'Download AudioSample' + formattedName + '.cpp';
downloadLink2.href = generateOutputFile(generateHeaderFile(formattedName, outputData)); downloadLink2.href = generateOutputFile(generateHeaderFile(formattedName, outputData));
}); });
} }


function createWords(audioData, padLength) {
var totalLength = audioData.length + padLength;
var outputData = [];
for(var i = 0; i < totalLength; i += 2) {
var a = toUint16(i<audioData.length?audioData[i]*0x7fff:0x0000);
var b = toUint16(i+1<audioData.length?audioData[i+1]*0x7fff:0x0000);
var out = (65536*b + a).toString(16);
while(out.length < 8) out = '0' + out;
out = '0x' + out;
outputData.push(out);
}
return outputData;
}

// http://2ality.com/2012/02/js-integers.html // http://2ality.com/2012/02/js-integers.html
function toInteger(x) { function toInteger(x) {
x = Number(x); x = Number(x);
return outputString; return outputString;
} }


function generateCPPFile(fileName, formattedName, audioData) {
function generateCPPFile(fileName, formattedName, audioData, sampleRate, encodingType) {
var out = ""; var out = "";
out += '// Audio data converted from audio file by wav2sketch_js\n\n'; out += '// Audio data converted from audio file by wav2sketch_js\n\n';
out += '#include "AudioSample' + formattedName + '.h"\n\n'; out += '#include "AudioSample' + formattedName + '.h"\n\n';
out += '// Converted from ' + fileName + ', using ' + sampleRate + ' Hz, 16 bit PCM encoding\n';
out += 'const unsigned int AudioSample' + formattedName + '[' + audioData.length + '] = {\n'; out += 'const unsigned int AudioSample' + formattedName + '[' + audioData.length + '] = {\n';
out += formatAudioData(audioData) + '\n};'; out += formatAudioData(audioData) + '\n};';
return out; return out;

Loading…
Cancel
Save