replace with a more robust state engine implementation
This commit is contained in:
parent
d79a1396a6
commit
b1ac8caf9b
@ -331,7 +331,9 @@ ImaAdpcmCodec.prototype.reset = function() {
|
|||||||
this.synchronized = 0;
|
this.synchronized = 0;
|
||||||
this.syncWord = "SYNC";
|
this.syncWord = "SYNC";
|
||||||
this.syncCounter = 0;
|
this.syncCounter = 0;
|
||||||
this.skip = 0;
|
this.phase = 0;
|
||||||
|
this.syncBuffer = new Uint8Array(4);
|
||||||
|
this.syncBufferIndex = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
ImaAdpcmCodec.imaIndexTable = [ -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 ];
|
ImaAdpcmCodec.imaIndexTable = [ -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8 ];
|
||||||
@ -359,38 +361,45 @@ ImaAdpcmCodec.prototype.decode = function(data) {
|
|||||||
|
|
||||||
ImaAdpcmCodec.prototype.decodeWithSync = function(data) {
|
ImaAdpcmCodec.prototype.decodeWithSync = function(data) {
|
||||||
var output = new Int16Array(data.length * 2);
|
var output = new Int16Array(data.length * 2);
|
||||||
var index = this.skip;
|
|
||||||
var oi = 0;
|
var oi = 0;
|
||||||
while (index < data.length) {
|
for (var index = 0; index < data.length; index++) {
|
||||||
while (this.synchronized < 4 && index < data.length) {
|
switch (this.phase) {
|
||||||
if (data[index] === this.syncWord.charCodeAt(this.synchronized)) {
|
case 0:
|
||||||
this.synchronized++;
|
// search for sync word
|
||||||
} else {
|
if (data[index] !== this.syncWord.charCodeAt(this.synchronized++)) {
|
||||||
|
// reset if data is unexpected
|
||||||
this.synchronized = 0;
|
this.synchronized = 0;
|
||||||
}
|
}
|
||||||
index++;
|
// if sync word has been found pass on to next phase
|
||||||
if (this.synchronized === 4) {
|
if (this.synchronized === 4) {
|
||||||
if (index + 4 < data.length) {
|
this.syncBufferIndex = 0;
|
||||||
var syncData = new Int16Array(data.buffer.slice(index, index + 4));
|
this.phase = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// read codec runtime data from stream
|
||||||
|
this.syncBuffer[this.syncBufferIndex++] = data[index];
|
||||||
|
// if data is complete, apply and pass on to next phase
|
||||||
|
if (this.syncBufferIndex === 4) {
|
||||||
|
var syncData = new Int16Array(this.syncBuffer.buffer);
|
||||||
this.stepIndex = syncData[0];
|
this.stepIndex = syncData[0];
|
||||||
this.predictor = syncData[1];
|
this.predictor = syncData[1];
|
||||||
}
|
|
||||||
this.syncCounter = 1000;
|
this.syncCounter = 1000;
|
||||||
index += 4;
|
this.phase = 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
case 2:
|
||||||
}
|
// decode actual audio data
|
||||||
while (index < data.length) {
|
|
||||||
if (this.syncCounter-- < 0) {
|
|
||||||
this.synchronized = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
output[oi++] = this.decodeNibble(data[index] & 0x0F);
|
output[oi++] = this.decodeNibble(data[index] & 0x0F);
|
||||||
output[oi++] = this.decodeNibble(data[index] >> 4);
|
output[oi++] = this.decodeNibble(data[index] >> 4);
|
||||||
index++;
|
// if the next sync keyword is due, reset and return to phase 0
|
||||||
|
if (this.syncCounter-- === 0) {
|
||||||
|
this.synchronized = 0;
|
||||||
|
this.phase = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.skip = index - data.length;
|
|
||||||
return output.slice(0, oi);
|
return output.slice(0, oi);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user