Skip to content

Commit cc574f1

Browse files
committed
new SEPIA VAD worker using Meyda + updated test; smaller tweaks;
1 parent 7482b72 commit cc574f1

File tree

11 files changed

+479
-19
lines changed

11 files changed

+479
-19
lines changed

src/modules/sepia-vad-worker.js

Lines changed: 405 additions & 0 deletions
Large diffs are not rendered by default.

src/modules/shared/common.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,21 @@ function ChannelCountException(message){
2525

2626
var CommonConverters = {};
2727

28-
CommonConverters.floatTo16BitPCM = function (output, input){
28+
CommonConverters.singleSampleFloatTo16BitPCM = function(s){
29+
s = Math.max(-1, Math.min(1, s));
30+
return (s < 0 ? s * 0x8000 : s * 0x7FFF);
31+
}
32+
CommonConverters.floatTo16BitPCM = function(output, input){
33+
for (let i = 0; i < input.length; i++) {
34+
output[i] = CommonConverters.singleSampleFloatTo16BitPCM(input[i]);
35+
}
36+
}
37+
CommonConverters.singleSampleInt16ToFloat32BitAudio = function(s){
38+
//s = Math.max(-32768, Math.min(32767, s));
39+
return Math.max(-1.0, Math.min(1.0, s/32768));
40+
}
41+
CommonConverters.int16ToFloat32BitAudio = function(output, input){
2942
for (let i = 0; i < input.length; i++) {
30-
let s = Math.max(-1, Math.min(1, input[i]));
31-
output[i] = s < 0 ? s * 0x8000 : s * 0x7FFF;
43+
return CommonConverters.singleSampleInt16ToFloat32BitAudio(input[i]);
3244
}
3345
}

src/modules/shared/meyda.min.compressed.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/modules/shared/ring-buffer.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/modules/webrtc-vad-worker.js

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ importScripts('./shared/common.js');
33
importScripts('./shared/ring-buffer.min.js');
44
importScripts('./webrtc-vad/webrtc-vad-interface.min.js');
55
importScripts('./webrtc-vad/webrtc-vad-wasm.js');
6+
//importScripts('./shared/meyda.min.compressed.js'); //we import this on demand below
67

78
var vadModule;
89

@@ -52,6 +53,9 @@ let voiceEnergyCap = 50;
5253
let voiceEnergyDropRate = 2;
5354
let _samplesToTimeMsFactor;
5455

56+
let meydaAnalyzer;
57+
let _meydaFeatures;
58+
5559
let _processRingBuffer; //holds multiple vadFrames
5660
let _vadFrames; //each frame processes one chunk of '_vadBufferSize' as long as '_processRingBuffer' has enough samples
5761
let _vadFrameTimeMs; //real time (ms) of one vadFrame (defined by sample-rate and buffer size)
@@ -109,7 +113,7 @@ function init(){
109113

110114
_isFirstValidProcess = true;
111115
}
112-
function ready(skipResampler){
116+
function ready(){
113117
postMessage({
114118
moduleState: 1,
115119
moduleInfo: {
@@ -136,6 +140,7 @@ function constructWorker(options) {
136140
processBufferSize = options.setup.bufferSize || inputSampleSize;
137141
vadMode = (options.setup.vadMode != undefined)? options.setup.vadMode : 3;
138142
isFloat32Input = (options.setup.isFloat32 != undefined)? options.setup.isFloat32 : false;
143+
139144
if (options.setup.voiceEnergyCap != undefined) voiceEnergyCap = options.setup.voiceEnergyCap;
140145
if (options.setup.voiceEnergyDropRate) voiceEnergyDropRate = options.setup.voiceEnergyDropRate;
141146
if (options.setup.sequence){
@@ -148,6 +153,28 @@ function constructWorker(options) {
148153
}else{
149154
useSequenceAnalyzer = false;
150155
}
156+
157+
//TODO: unused so far ... keep or remove?
158+
meydaAnalyzer = options.setup.meydaAnalyzer || {};
159+
var meydaSettingsKeys = Object.keys(meydaAnalyzer);
160+
if (meydaSettingsKeys.length > 0){
161+
//import on demand
162+
importScripts('./shared/meyda.min.compressed.js');
163+
//setup
164+
meydaSettingsKeys.forEach(function(k, i){
165+
if (k == "features"){
166+
_meydaFeatures = meydaAnalyzer[k];
167+
}else{
168+
Meyda[k] = meydaAnalyzer[k];
169+
}
170+
});
171+
Meyda.sampleRate = targetSampleRate;
172+
Meyda.bufferSize = inputSampleSize;
173+
if (!Meyda.bufferSize || (Meyda.bufferSize & (Meyda.bufferSize -1) != 0)){
174+
throw {name: "VadModuleMeydaError", message: "Meyda buffer-size must be power of 2, e.g. 128, 256, 512, 1024, ..."};
175+
}
176+
}
177+
151178
init();
152179

153180
function onVadLog(msg){
@@ -273,8 +300,8 @@ function process(data) {
273300
throw JSON.stringify(new SampleRateException(msg)); //NOTE: this needs to be a string to show up in worker.onerror properly :-/
274301
return;
275302
}
276-
var inputArrayType = data.type || data.samples[0].constructor.name;
277-
var isFloat32 = (inputArrayType.indexOf("Float32") >= 0);
303+
let inputArrayType = data.type || data.samples[0].constructor.name;
304+
let isFloat32 = (inputArrayType.indexOf("Float32") >= 0);
278305
if (isFloat32 != isFloat32Input){
279306
var msg = "Array type mismatch! Input samples are of type '" + inputArrayType + "' but expected: " + (isFloat32Input? "Float32" : "Int16");
280307
console.error("Audio Worker type exception - Msg.: " + msg);

src/processor.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ if (!(typeof SepiaFW == "object")){
652652
//INTERFACE
653653

654654
thisProcessor.start = function(){
655-
if (!isProcessing){
655+
if (isInitialized && !isProcessing){
656656
startFun(function(){
657657
var startTime = new Date().getTime(); //TODO: is this maybe already too late?
658658
setStateProcessing();

src/resources/meyda.min.compressed.js

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/resources/meyda.min.js

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/resources/speex/index.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@ class SpeexResampler {
3333
if (chunk.constructor.name.indexOf("Int16Array") != 0) {
3434
throw new Error("Chunk format has to be 'Int16Array'");
3535
}else{
36-
chunk = new Uint8Array(chunk.buffer); //TODO: I've tried to simply set 'speexModule.HEAP16' (see below) but it gives no result ...
36+
chunk = new Uint8Array(chunk.buffer); //TODO: I've tried to simply set 'speexModule.HEAP16' (see below) but it gives no result ... WHY DOES THIS WORK instead of real conversion??
37+
//C interface: speex_resampler_process_int(SpeexResamplerState *st, unsigned int channel_index, const short *in, unsigned int *in_len, short *out, unsigned int *out_len)
38+
/*
39+
unsigned int -> HEAPU32
40+
short -> HEAP16
41+
*/
3742
}
3843
// We check that we have as many chunks for each channel and that the last chunk is full (2 bytes)
3944
if (chunk.length % (this.channels * Uint16Array.BYTES_PER_ELEMENT) !== 0) {
@@ -54,7 +59,7 @@ class SpeexResampler {
5459
if (this._inBufferPtr !== -1) {
5560
speexModule._free(this._inBufferPtr);
5661
}
57-
this._inBufferPtr = speexModule._malloc(chunk.length);
62+
this._inBufferPtr = speexModule._malloc(chunk.length); //TODO: can we use Int16 and (chunk.length * chunk.BYTES_PER_ELEMENT)?
5863
this._inBufferSize = chunk.length;
5964
}
6065
// Resizing the output buffer in the WASM memory space to match what we need

test-commons.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,11 @@ var fixedPlots = {
4343
use: (document.getElementById("usePlot2")? document.getElementById("usePlot2").checked : true)
4444
},
4545
3: {
46-
graph: (new uPlot.lazy.AutoSeries(document.getElementById('chart3'), 50, {
46+
graph: (new uPlot.lazy.AutoSeries(document.getElementById('chart3'), 150, {
4747
//rememberMax: true
4848
}, {
49-
yRange: [-0.1, 1.1]
49+
showAxisX: false
50+
//yRange: [-0.1, 1.1]
5051
})),
5152
use: (document.getElementById("usePlot3")? document.getElementById("usePlot3").checked : true)
5253
},
@@ -74,11 +75,15 @@ function addChartContainerToPage(){
7475
(document.getElementById("mainView") || document.body).appendChild(ele);
7576
return ele;
7677
}
77-
function plotData(data, plotIndex){
78+
function plotData(data, plotIndex, expandData){
7879
var p = fixedPlots[plotIndex];
7980
if (p){
8081
if (p.use){
81-
p.graph.addValues(data);
82+
if (expandData){
83+
p.graph.addValues(...data);
84+
}else{
85+
p.graph.addValues(data);
86+
}
8287
p.graph.draw();
8388
}
8489
}else{

0 commit comments

Comments
 (0)