Bug 1038061 - Allow specifying audio stream for speech recognition. r=smaug,ggp sr=smaug

This commit is contained in:
Shih-Chiang Chien 2014-07-16 09:38:59 +08:00
parent 30e903768b
commit 9be768a35c
11 changed files with 44 additions and 50 deletions

View File

@ -584,19 +584,12 @@ SpeechRecognition::Observe(nsISupports* aSubject, const char* aTopic,
void void
SpeechRecognition::ProcessTestEventRequest(nsISupports* aSubject, const nsAString& aEventName) SpeechRecognition::ProcessTestEventRequest(nsISupports* aSubject, const nsAString& aEventName)
{ {
if (aEventName.EqualsLiteral("EVENT_START")) { if (aEventName.EqualsLiteral("EVENT_ABORT")) {
ErrorResult err;
Start(err);
} else if (aEventName.EqualsLiteral("EVENT_STOP")) {
Stop();
} else if (aEventName.EqualsLiteral("EVENT_ABORT")) {
Abort(); Abort();
} else if (aEventName.EqualsLiteral("EVENT_AUDIO_ERROR")) { } else if (aEventName.EqualsLiteral("EVENT_AUDIO_ERROR")) {
DispatchError(SpeechRecognition::EVENT_AUDIO_ERROR, DispatchError(SpeechRecognition::EVENT_AUDIO_ERROR,
SpeechRecognitionErrorCode::Audio_capture, // TODO different codes? SpeechRecognitionErrorCode::Audio_capture, // TODO different codes?
NS_LITERAL_STRING("AUDIO_ERROR test event")); NS_LITERAL_STRING("AUDIO_ERROR test event"));
} else if (aEventName.EqualsLiteral("EVENT_AUDIO_DATA")) {
StartRecording(static_cast<DOMMediaStream*>(aSubject));
} else { } else {
NS_ASSERTION(mTestConfig.mFakeRecognitionService, NS_ASSERTION(mTestConfig.mFakeRecognitionService,
"Got request for fake recognition service event, but " "Got request for fake recognition service event, but "
@ -693,7 +686,7 @@ SpeechRecognition::SetServiceURI(const nsAString& aArg, ErrorResult& aRv)
} }
void void
SpeechRecognition::Start(ErrorResult& aRv) SpeechRecognition::Start(const Optional<NonNull<DOMMediaStream>>& aStream, ErrorResult& aRv)
{ {
if (mCurrentState != STATE_IDLE) { if (mCurrentState != STATE_IDLE) {
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
@ -713,7 +706,9 @@ SpeechRecognition::Start(ErrorResult& aRv)
MediaStreamConstraints constraints; MediaStreamConstraints constraints;
constraints.mAudio.SetAsBoolean() = true; constraints.mAudio.SetAsBoolean() = true;
if (!mTestConfig.mFakeFSMEvents) { if (aStream.WasPassed()) {
StartRecording(&aStream.Value());
} else {
MediaManager* manager = MediaManager::Get(); MediaManager* manager = MediaManager::Get();
manager->GetUserMedia(false, manager->GetUserMedia(false,
GetOwner(), GetOwner(),

View File

@ -96,7 +96,7 @@ public:
void SetServiceURI(const nsAString& aArg, ErrorResult& aRv); void SetServiceURI(const nsAString& aArg, ErrorResult& aRv);
void Start(ErrorResult& aRv); void Start(const Optional<NonNull<DOMMediaStream>>& aStream, ErrorResult& aRv);
void Stop(); void Stop();

View File

@ -90,6 +90,24 @@ function EventManager(sr) {
} }
} }
self.start = function EventManager_start() {
isSendingAudioData = true;
var audioTag = document.createElement("audio");
audioTag.src = self.audioSampleFile;
var stream = audioTag.mozCaptureStreamUntilEnded();
audioTag.addEventListener("ended", function() {
info("Sample stream ended, requesting queued events");
isSendingAudioData = false;
while (queuedEventRequests.length) {
self.requestFSMEvent(queuedEventRequests.shift());
}
});
audioTag.play();
sr.start(stream);
}
self.requestFSMEvent = function EventManager_requestFSMEvent(eventName) { self.requestFSMEvent = function EventManager_requestFSMEvent(eventName) {
if (isSendingAudioData) { if (isSendingAudioData) {
info("Queuing event " + eventName + " until we're done sending audio data"); info("Queuing event " + eventName + " until we're done sending audio data");
@ -97,27 +115,8 @@ function EventManager(sr) {
return; return;
} }
var subject = null;
if (eventName === "EVENT_AUDIO_DATA") {
isSendingAudioData = true;
var audioTag = document.createElement("audio");
audioTag.src = self.audioSampleFile;
subject = audioTag.mozCaptureStreamUntilEnded();
audioTag.addEventListener("ended", function() {
info("Sample stream ended, requesting queued events");
isSendingAudioData = false;
while (queuedEventRequests.length) {
self.requestFSMEvent(queuedEventRequests.shift());
}
});
audioTag.play();
}
info("requesting " + eventName); info("requesting " + eventName);
Services.obs.notifyObservers(subject, Services.obs.notifyObservers(null,
SPEECH_RECOGNITION_TEST_REQUEST_EVENT_TOPIC, SPEECH_RECOGNITION_TEST_REQUEST_EVENT_TOPIC,
eventName); eventName);
} }
@ -168,6 +167,8 @@ function performTest(options) {
em.audioSampleFile = options.audioSampleFile; em.audioSampleFile = options.audioSampleFile;
} }
em.start();
for (var i = 0; i < options.eventsToRequest.length; i++) { for (var i = 0; i < options.eventsToRequest.length; i++) {
em.requestFSMEvent(options.eventsToRequest[i]); em.requestFSMEvent(options.eventsToRequest[i]);
} }

View File

@ -57,7 +57,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=650295
nextEventIdx++; nextEventIdx++;
performTest({ performTest({
eventsToRequest: ["EVENT_START", "EVENT_AUDIO_DATA"], eventsToRequest: [],
expectedEvents: expectedEvents, expectedEvents: expectedEvents,
doneFunc: (nextEventIdx < eventsToAbortOn.length) ? doNextTest : SimpleTest.finish, doneFunc: (nextEventIdx < eventsToAbortOn.length) ? doNextTest : SimpleTest.finish,
prefs: [["media.webspeech.test.fake_fsm_events", true], ["media.webspeech.test.fake_recognition_service", true]] prefs: [["media.webspeech.test.fake_fsm_events", true], ["media.webspeech.test.fake_recognition_service", true]]

View File

@ -21,7 +21,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=650295
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
performTest({ performTest({
eventsToRequest: ['EVENT_START', 'EVENT_AUDIO_ERROR'], eventsToRequest: ['EVENT_AUDIO_ERROR'],
expectedEvents: { expectedEvents: {
'error': buildErrorCallback(errorCodes.AUDIO_CAPTURE), 'error': buildErrorCallback(errorCodes.AUDIO_CAPTURE),
'end': null 'end': null

View File

@ -20,9 +20,19 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=650295
<script type="text/javascript"> <script type="text/javascript">
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
function createAudioStream() {
var audioTag = document.createElement("audio");
audioTag.src = DEFAULT_AUDIO_SAMPLE_FILE;
var stream = audioTag.mozCaptureStreamUntilEnded();
audioTag.play();
return stream;
}
function endHandler(evt, sr) { function endHandler(evt, sr) {
try { try {
sr.start(); // shouldn't fail sr.start(createAudioStream()); // shouldn't fail
} catch (err) { } catch (err) {
ok(false, "Failed to start() from end() callback"); ok(false, "Failed to start() from end() callback");
} }
@ -32,7 +42,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=650295
function expectExceptionHandler(evt, sr) { function expectExceptionHandler(evt, sr) {
try { try {
sr.start(); sr.start(createAudioStream());
} catch (err) { } catch (err) {
is(err.name, "InvalidStateError"); is(err.name, "InvalidStateError");
return; return;
@ -43,8 +53,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=650295
performTest({ performTest({
eventsToRequest: [ eventsToRequest: [
'EVENT_START',
'EVENT_AUDIO_DATA',
'EVENT_RECOGNITIONSERVICE_FINAL_RESULT' 'EVENT_RECOGNITIONSERVICE_FINAL_RESULT'
], ],
expectedEvents: { expectedEvents: {

View File

@ -66,10 +66,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=650295
*/ */
performTest({ performTest({
eventsToRequest: [ eventsToRequest: [],
"EVENT_START",
"EVENT_AUDIO_DATA",
],
expectedEvents: { expectedEvents: {
"audiostart": abortAndSpinEventLoop, "audiostart": abortAndSpinEventLoop,
"audioend": abortAndSpinEventLoop, "audioend": abortAndSpinEventLoop,

View File

@ -22,8 +22,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=650295
performTest({ performTest({
eventsToRequest: [ eventsToRequest: [
'EVENT_START',
'EVENT_AUDIO_DATA',
'EVENT_RECOGNITIONSERVICE_ERROR' 'EVENT_RECOGNITIONSERVICE_ERROR'
], ],
expectedEvents: { expectedEvents: {

View File

@ -22,8 +22,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=650295
performTest({ performTest({
eventsToRequest: [ eventsToRequest: [
'EVENT_START',
'EVENT_AUDIO_DATA',
'EVENT_RECOGNITIONSERVICE_FINAL_RESULT' 'EVENT_RECOGNITIONSERVICE_FINAL_RESULT'
], ],
expectedEvents: { expectedEvents: {

View File

@ -21,10 +21,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=650295
SimpleTest.waitForExplicitFinish(); SimpleTest.waitForExplicitFinish();
performTest({ performTest({
eventsToRequest: [ eventsToRequest: [],
"EVENT_START",
"EVENT_AUDIO_DATA"
],
expectedEvents: { expectedEvents: {
"start": null, "start": null,
"audiostart": null, "audiostart": null,

View File

@ -29,7 +29,7 @@ interface SpeechRecognition : EventTarget {
// methods to drive the speech interaction // methods to drive the speech interaction
[Throws] [Throws]
void start(); void start(optional MediaStream stream);
void stop(); void stop();
void abort(); void abort();