cognitive-services-speech-s.../tests/PushInputStreamTests.ts

239 строки
8.2 KiB
TypeScript

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
import { setTimeout } from "timers";
import {
IAudioStreamNode,
IStreamChunk,
} from "../src/common/Exports";
import {
PushAudioInputStreamImpl,
} from "../src/sdk/Audio/AudioInputStream";
import {
AudioStreamFormat,
AudioStreamFormatImpl,
} from "../src/sdk/Audio/AudioStreamFormat";
import { Settings } from "./Settings";
let bufferSize: number;
beforeAll(() => {
// Override inputs, if necessary
Settings.LoadSettings();
bufferSize = (AudioStreamFormat.getDefaultInputFormat() as AudioStreamFormatImpl).avgBytesPerSec / 10;
});
// eslint-disable-next-line no-console
beforeEach(() => console.info("------------------Starting test case: " + expect.getState().currentTestName + "-------------------------"));
test("Push segments into small blocks", (done: jest.DoneCallback) => {
const ps: PushAudioInputStreamImpl = new PushAudioInputStreamImpl();
const ab: ArrayBuffer = new ArrayBuffer(bufferSize * 4);
const abView: Uint8Array = new Uint8Array(ab);
for (let i: number = 0; i < bufferSize * 4; i++) {
abView[i] = i % 256;
}
let j: number = 0;
for (j = 0; j < bufferSize * 4; j += 100) {
ps.write(ab.slice(j, j + 100));
}
ps.write(ab.slice(j));
ps.attach("id").then((audioNode: IAudioStreamNode) => {
let bytesRead: number = 0;
const readLoop = () => {
audioNode.read().then((audioBuffer: IStreamChunk<ArrayBuffer>) => {
try {
expect(audioBuffer.buffer.byteLength).toBeGreaterThanOrEqual(bufferSize);
expect(audioBuffer.buffer.byteLength).toBeLessThanOrEqual(bufferSize);
const readView: Uint8Array = new Uint8Array(audioBuffer.buffer);
for (let i: number = 0; i < audioBuffer.buffer.byteLength; i++) {
expect(readView[i]).toEqual(bytesRead++ % 256);
}
} catch (error) {
done(error);
}
if (bytesRead < bufferSize * 4) {
readLoop();
} else {
done();
}
}, (error: string) => done(error));
};
readLoop();
}, (error: string) => done(error));
});
test("Stream returns all data when closed", (done: jest.DoneCallback) => {
const ps: PushAudioInputStreamImpl = new PushAudioInputStreamImpl();
const ab: ArrayBuffer = new ArrayBuffer(bufferSize * 4);
const abView: Uint8Array = new Uint8Array(ab);
for (let i: number = 0; i < bufferSize * 4; i++) {
abView[i] = i % 256;
}
let j: number = 0;
for (j = 0; j < bufferSize * 4; j += 100) {
ps.write(ab.slice(j, j + 100));
}
ps.write(ab.slice(j));
ps.close();
ps.attach("id").then((audioNode: IAudioStreamNode) => {
let bytesRead: number = 0;
const readLoop = () => {
audioNode.read().then((audioBuffer: IStreamChunk<ArrayBuffer>) => {
try {
expect(audioBuffer).not.toBeUndefined();
if (bytesRead === bufferSize * 4) {
expect(audioBuffer.isEnd).toEqual(true);
expect(audioBuffer.buffer).toEqual(null);
done();
} else {
expect(audioBuffer.buffer).not.toBeUndefined();
expect(audioBuffer.isEnd).toEqual(false);
const readView: Uint8Array = new Uint8Array(audioBuffer.buffer);
for (let i: number = 0; i < audioBuffer.buffer.byteLength; i++) {
expect(readView[i]).toEqual(bytesRead++ % 256);
}
readLoop();
}
} catch (error) {
done(error);
}
}, (error: string) => done(error));
};
readLoop();
}, (error: string) => done(error));
});
test("Stream blocks when not closed", (done: jest.DoneCallback) => {
const ps: PushAudioInputStreamImpl = new PushAudioInputStreamImpl();
const ab: ArrayBuffer = new ArrayBuffer(bufferSize * 4);
const abView: Uint8Array = new Uint8Array(ab);
for (let i: number = 0; i < bufferSize * 4; i++) {
abView[i] = i % 256;
}
let j: number = 0;
for (j = 0; j < bufferSize * 4; j += 100) {
ps.write(ab.slice(j, j + 100));
}
ps.write(ab.slice(j));
ps.attach("id").then((audioNode: IAudioStreamNode) => {
let bytesRead: number = 0;
let readCallCount: number = 0;
let shouldBeEnd: boolean = false;
const readLoop = () => {
audioNode.read().then((audioBuffer: IStreamChunk<ArrayBuffer>) => {
readCallCount++;
try {
expect(audioBuffer).not.toBeUndefined();
if (!shouldBeEnd) {
expect(audioBuffer.buffer).not.toBeUndefined();
const readView: Uint8Array = new Uint8Array(audioBuffer.buffer);
for (let i: number = 0; i < audioBuffer.buffer.byteLength; i++) {
expect(readView[i]).toEqual(bytesRead++ % 256);
}
if (bytesRead === bufferSize * 4) {
// The next call should block.
const currentReadCount: number = readCallCount;
// Schedule a check that the number of calls has not increased.
setTimeout(() => {
try {
expect(readCallCount).toEqual(currentReadCount);
shouldBeEnd = true;
// Release the blocking read and finish when it does.
ps.close();
} catch (error) {
done(error);
}
}, 2000);
}
readLoop();
} else {
expect(audioBuffer.buffer).toEqual(null);
expect(audioBuffer.isEnd).toEqual(true);
done();
}
} catch (error) {
done(error);
}
}, (error: string) => done(error));
};
readLoop();
}, (error: string) => done(error));
}, 15000);
test("nonAligned data is fine", (done: jest.DoneCallback) => {
const ps: PushAudioInputStreamImpl = new PushAudioInputStreamImpl();
const dataSize: number = bufferSize * 1.25;
const ab: ArrayBuffer = new ArrayBuffer(dataSize);
const abView: Uint8Array = new Uint8Array(ab);
for (let i: number = 0; i < dataSize; i++) {
abView[i] = i % 256;
}
ps.write(ab);
ps.close();
ps.attach("id").then((audioNode: IAudioStreamNode) => {
let bytesRead: number = 0;
const readLoop = () => {
audioNode.read().then((audioBuffer: IStreamChunk<ArrayBuffer>) => {
try {
expect(audioBuffer).not.toBeUndefined();
if (bytesRead === dataSize) {
expect(audioBuffer.isEnd).toEqual(true);
expect(audioBuffer.buffer).toEqual(null);
done();
} else {
expect(audioBuffer.buffer).not.toBeUndefined();
expect(audioBuffer.isEnd).toEqual(false);
const readView: Uint8Array = new Uint8Array(audioBuffer.buffer);
for (let i: number = 0; i < audioBuffer.buffer.byteLength; i++) {
expect(readView[i]).toEqual(bytesRead++ % 256);
}
readLoop();
}
} catch (error) {
done(error);
}
}, (error: string) => done(error));
};
readLoop();
}, (error: string) => done(error));
});