我对javascript相当新,而且它更难以实现,因为我在某个复杂的项目中使用它。我正在使用pocketsphinx.js语音启用spring mvc项目的视图。
我在尝试使用类的构造函数时遇到了一些意外错误。以下是代码片段
audioRecorder.js
(function(window) {
var AUDIO_RECORDER_WORKER = getContextPath()
+ '/moduleResources/radiology/audioRecorderWorker.js';
var AudioRecorder = function(source, cfg) {
this.consumers = [];
var config = cfg || {};
var errorCallback = config.errorCallback || function() {
};
var inputBufferLength = config.inputBufferLength || 4096;
var outputBufferLength = config.outputBufferLength || 4000;
this.context = source.context;
this.node = this.context.createScriptProcessor(inputBufferLength);
var worker = new Worker(config.worker || AUDIO_RECORDER_WORKER);
worker.postMessage({
command: 'init',
config: {
sampleRate: this.context.sampleRate,
outputBufferLength: outputBufferLength,
outputSampleRate: (config.outputSampleRate || 16000)
}
});
var recording = false;
this.node.onaudioprocess = function(e) {
if (!recording) return;
worker.postMessage({
command: 'record',
buffer: [e.inputBuffer.getChannelData(0),
e.inputBuffer.getChannelData(1)]
});
};
this.start = function(data) {
this.consumers.forEach(function(consumer, y, z) {
consumer.postMessage({
command: 'start',
data: data
});
recording = true;
return true;
});
recording = true;
return (this.consumers.length > 0);
};
this.stop = function() {
if (recording) {
this.consumers.forEach(function(consumer, y, z) {
consumer.postMessage({
command: 'stop'
});
});
recording = false;
}
worker.postMessage({
command: 'clear'
});
};
this.cancel = function() {
this.stop();
};
myClosure = this;
worker.onmessage = function(e) {
if (e.data.error && (e.data.error == "silent")) errorCallback("silent");
if ((e.data.command == 'newBuffer') && recording) {
myClosure.consumers.forEach(function(consumer, y, z) {
consumer.postMessage({
command: 'process',
data: e.data.data
});
});
}
};
source.connect(this.node);
this.node.connect(this.context.destination);
};
window.AudioRecorder = AudioRecorder;
})(window);
main.js
var recognizer;
var recorder;
var callbackManager;
var audioContext;
// Only when both recorder and recognizer are ready do we have a ready application
// I'm keeping these so I can use them with other applications
var recorderReady = false;
var recognizerReady = false;
// TEMP
var outputContainer;
// the phones we want to detect
var wordList = [["ONE", "W AH N"], ["TWO", "T UW"], ["THREE", "TH R IY"],
["FOUR", "F AO R"], ["FIVE", "F AY V"], ["SIX", "S IH K S"],
["SEVEN", "S EH V AH N"], ["EIGHT", "EY T"], ["NINE", "N AY N"],
["ZERO", "Z IH R OW"], ["NEW-YORK", "N UW Y AO R K"],
["NEW-YORK-CITY", "N UW Y AO R K S IH T IY"], ["PARIS", "P AE R IH S"],
["PARIS(2)", "P EH R IH S"], ["SHANGHAI", "SH AE NG HH AY"],
["SAN-FRANCISCO", "S AE N F R AE N S IH S K OW"],
["LONDON", "L AH N D AH N"], ["BERLIN", "B ER L IH N"],
["SUCKS", "S AH K S"], ["ROCKS", "R AA K S"], ["IS", "IH Z"],
["NOT", "N AA T"], ["GOOD", "G IH D"], ["GOOD(2)", "G UH D"],
["GREAT", "G R EY T"], ["WINDOWS", "W IH N D OW Z"],
["LINUX", "L IH N AH K S"], ["UNIX", "Y UW N IH K S"], ["MAC", "M AE K"],
["AND", "AE N D"], ["AND(2)", "AH N D"], ["O", "OW"], ["S", "EH S"],
["X", "EH K S"]];
var grammars = [{
g: {
numStates: 1,
start: 0,
end: 0,
transitions: [{
from: 0,
to: 0,
word: "ONE"
}, {
from: 0,
to: 0,
word: "TWO"
}, {
from: 0,
to: 0,
word: "THREE"
}, {
from: 0,
to: 0,
word: "FOUR"
}, {
from: 0,
to: 0,
word: "FIVE"
}, {
from: 0,
to: 0,
word: "SIX"
}, {
from: 0,
to: 0,
word: "SEVEN"
}, {
from: 0,
to: 0,
word: "EIGHT"
}, {
from: 0,
to: 0,
word: "NINE"
}, {
from: 0,
to: 0,
word: "ZERO"
}]
}
}];
// When the page is loaded we spawn a new recognizer worker and call getUserMedia to request access to the microphone
window.onload = function() {
recognizer = new Worker(getContextPath()
+ '/moduleResources/radiology/recognizer.js');
callbackManager = new CallbackManager();
// TEMP
outputContainer = document.getElementById("bodyId");
var startBtn = document.getElementsByName('start_button');
var stopBtn = document.getElementsByName('stop_button');
//startBtn.disabled = true;
// stopBtn.disabled = true;
startBtn.onclick = startRecording;
stopBtn.onclick = stopRecording;
// initialize Web Audio variables
try {
window.AudioContext = window.AudioContext || window.webkitAudioContext;
navigator.getUserMedia = navigator.getUserMedia
|| navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
window.URL = window.URL || window.webkitURL;
audioContext = new AudioContext();
} catch (e) {
// report incompatible browser
}
if (navigator.getUserMedia) {
navigator.getUserMedia({
audio: true
}, function(stream) {
var input = audioContext.createMediaStreamSource(stream);
var audioRecorderConfig = {
errorCallback: function(x) {
}
};
recorder = new AudioRecorder(input, audioRecorderConfig);
// If a recognizer is ready we pass it to the recorder
if (recognizer) {
recorder.consumers = [recognizer];
}
recorderReady = true;
}, function(e) {
});
}
recognizer.onmessage = function() {
// I need this nested event listener because the first time a message is triggered we need to trigger other things that we never need to trigger again
recognizer.onmessage = function(e) {
// if an id to be used with the callback manager
// this is needed to start the listening
if (e.data.hasOwnProperty('id')) {
var data = {};
if (e.data.hasOwnProperty('data')) {
data = e.data.data;
}
var callback = callbackManager.get(e.data['id']);
if (callback) {
callback(data);
}
}
// if a new hypothesis has been created
if (e.data.hasOwnProperty('hyp')) {
var hypothesis = e.data.hyp;
if (outputContainer) {
outputContainer.innerHTML = hypothesis;
}
}
// if an error occured
if (e.data.hasOwnProperty('status') && (e.data.status == "error")) {
}
};
// Once the worker is fully loaded, we can call the initialize function
// You can pass parameters to the recognizer, such as : {command: 'initialize', data: [["-hmm", "my_model"], ["-fwdflat", "no"]]}
postRecognizerJob({
command: 'initialize'
}, function() {
if (recorder) {
recorder.consumers = [recognizer];
}
postRecognizerJob({
command: 'addWords',
data: wordList
}, function() {
feedGrammar(grammars, 0);
startRecording();
});
});
};
recognizer.postMessage('');
};
function postRecognizerJob(message, callback) {
var msg = message || {};
if (callbackManager) {
msg.callbackId = callbackManager.add(callback);
}
if (recognizer) {
recognizer.postMessage(msg);
}
}
function feedGrammar(g, index, id) {
if (index < g.length) {
postRecognizerJob({
command: 'addGrammar',
data: g[index].g
}, function(id) {
feedGrammar(grammars, index + 1, {
id: id
});
});
} else {
recognizerReady = true;
}
}
// This starts recording. We first need to get the id of the grammar to use
/*function startRecording() {
if (recorder && recorder.start(0)) {
if (recorder && recorder.start(id)) displayRecording(true);
}
}*/
var startRecording = function() {
var id;
var test = document.get('ryan').value;
if (test == 100) id = 0;
if (recorder && recorder.start(id)) displayRecording(true);
};
// Stops recording
var stopRecording = function() {
recorder && recorder.stop();
displayRecording(false);
};
function displayRecording(display) {
if (display)
document.getElementById('recording_indicator').innerHTML = " ";
else
document.getElementById('recording_indicator').innerHTML = "";
};
现在,当我运行程序时,我在浏览器控制台上收到此错误
未捕获的ReferenceError:未定义AudioRecorder
即使在看了3天之后,我也似乎无法调试出错的地方。任何帮助都感激不尽。 PS:请原谅大代码片段,我打算尽可能明确