@voice-ping/cognitive-services-speech
Version:
VoicePing Cognitive Services Speech SDK for JavaScript forked from Microsoft
181 lines (179 loc) • 8.53 kB
JavaScript
;
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
Object.defineProperty(exports, "__esModule", { value: true });
var Exports_1 = require("../common.speech/Exports");
var Exports_2 = require("../common/Exports");
var AudioStreamFormat_1 = require("../sdk/Audio/AudioStreamFormat");
var FileAudioSource = /** @class */ (function () {
function FileAudioSource(file, audioSourceId) {
var _this = this;
this.privStreams = {};
this.turnOn = function () {
if (typeof FileReader === "undefined") {
var errorMsg = "Browser does not support FileReader.";
_this.onEvent(new Exports_2.AudioSourceErrorEvent(errorMsg, "")); // initialization error - no streamid at this point
return Exports_2.PromiseHelper.fromError(errorMsg);
}
else if (_this.privFile.name.lastIndexOf(".wav") !== _this.privFile.name.length - 4) {
var errorMsg = _this.privFile.name + " is not supported. Only WAVE files are allowed at the moment.";
_this.onEvent(new Exports_2.AudioSourceErrorEvent(errorMsg, ""));
return Exports_2.PromiseHelper.fromError(errorMsg);
}
_this.onEvent(new Exports_2.AudioSourceInitializingEvent(_this.privId)); // no stream id
_this.onEvent(new Exports_2.AudioSourceReadyEvent(_this.privId));
return Exports_2.PromiseHelper.fromResult(true);
};
this.id = function () {
return _this.privId;
};
this.attach = function (audioNodeId) {
_this.onEvent(new Exports_2.AudioStreamNodeAttachingEvent(_this.privId, audioNodeId));
return _this.upload(audioNodeId).onSuccessContinueWith(function (stream) {
_this.onEvent(new Exports_2.AudioStreamNodeAttachedEvent(_this.privId, audioNodeId));
return {
detach: function () {
stream.readEnded();
delete _this.privStreams[audioNodeId];
_this.onEvent(new Exports_2.AudioStreamNodeDetachedEvent(_this.privId, audioNodeId));
_this.turnOff();
},
id: function () {
return audioNodeId;
},
read: function () {
return stream.read();
},
};
});
};
this.detach = function (audioNodeId) {
if (audioNodeId && _this.privStreams[audioNodeId]) {
_this.privStreams[audioNodeId].close();
delete _this.privStreams[audioNodeId];
_this.onEvent(new Exports_2.AudioStreamNodeDetachedEvent(_this.privId, audioNodeId));
}
};
this.turnOff = function () {
for (var streamId in _this.privStreams) {
if (streamId) {
var stream = _this.privStreams[streamId];
if (stream && !stream.isClosed) {
stream.close();
}
}
}
_this.onEvent(new Exports_2.AudioSourceOffEvent(_this.privId)); // no stream now
return Exports_2.PromiseHelper.fromResult(true);
};
this.readHeader = function () {
// Read the wave header.
var header = _this.privFile.slice(0, 44);
var headerReader = new FileReader();
var headerResult = new Exports_2.Deferred();
var processHeader = function (event) {
var header = event.target.result;
var view = new DataView(header);
// RIFF 4 bytes.
var riff = String.fromCharCode(view.getUint8(0), view.getUint8(1), view.getUint8(2), view.getUint8(3));
if ("RIFF" !== riff) {
headerResult.reject("Invalid WAV header in file, RIFF was not found");
}
// length, 4 bytes
// RIFF Type & fmt 8 bytes
var type = String.fromCharCode(view.getUint8(8), view.getUint8(9), view.getUint8(10), view.getUint8(11), view.getUint8(12), view.getUint8(13), view.getUint8(14));
if ("WAVEfmt" !== type) {
headerResult.reject("Invalid WAV header in file, WAVEfmt was not found");
}
var channelCount = view.getUint16(22, true);
var sampleRate = view.getUint32(24, true);
var bitsPerSample = view.getUint16(34, true);
headerResult.resolve(AudioStreamFormat_1.AudioStreamFormat.getWaveFormatPCM(sampleRate, bitsPerSample, channelCount));
};
headerReader.onload = processHeader;
headerReader.readAsArrayBuffer(header);
return headerResult.promise();
};
this.upload = function (audioNodeId) {
return _this.turnOn()
.onSuccessContinueWithPromise(function (_) {
return _this.privAudioFormatPromise.onSuccessContinueWith(function (format) {
var fileStream = new Exports_2.ChunkedArrayBufferStream(3200);
var reader = new FileReader();
var stream = new Exports_2.ChunkedArrayBufferStream(format.avgBytesPerSec / 10, audioNodeId);
_this.privStreams[audioNodeId] = stream;
var processFile = function (event) {
if (stream.isClosed) {
return; // output stream was closed (somebody called TurnOff). We're done here.
}
stream.writeStreamChunk({
buffer: reader.result,
isEnd: false,
timeReceived: Date.now(),
});
stream.close();
};
reader.onload = processFile;
reader.onerror = function (event) {
var errorMsg = "Error occurred while processing '" + _this.privFile.name + "'. " + event;
_this.onEvent(new Exports_2.AudioStreamNodeErrorEvent(_this.privId, audioNodeId, errorMsg));
throw new Error(errorMsg);
};
var chunk = _this.privFile.slice(44);
reader.readAsArrayBuffer(chunk);
return stream;
});
});
};
this.onEvent = function (event) {
_this.privEvents.onEvent(event);
Exports_2.Events.instance.onEvent(event);
};
this.privId = audioSourceId ? audioSourceId : Exports_2.createNoDashGuid();
this.privEvents = new Exports_2.EventSource();
this.privFile = file;
// Read the header.
this.privAudioFormatPromise = this.readHeader();
}
Object.defineProperty(FileAudioSource.prototype, "format", {
get: function () {
return this.privAudioFormatPromise;
},
enumerable: true,
configurable: true
});
Object.defineProperty(FileAudioSource.prototype, "blob", {
get: function () {
return Exports_2.PromiseHelper.fromResult(this.privFile);
},
enumerable: true,
configurable: true
});
Object.defineProperty(FileAudioSource.prototype, "events", {
get: function () {
return this.privEvents;
},
enumerable: true,
configurable: true
});
Object.defineProperty(FileAudioSource.prototype, "deviceInfo", {
get: function () {
return this.privAudioFormatPromise.onSuccessContinueWithPromise(function (result) {
return Exports_2.PromiseHelper.fromResult({
bitspersample: result.bitsPerSample,
channelcount: result.channels,
connectivity: Exports_1.connectivity.Unknown,
manufacturer: "Speech SDK",
model: "File",
samplerate: result.samplesPerSec,
type: Exports_1.type.File,
});
});
},
enumerable: true,
configurable: true
});
return FileAudioSource;
}());
exports.FileAudioSource = FileAudioSource;
//# sourceMappingURL=FileAudioSource.js.map