| <!DOCTYPE html> | |
| <html lang="en"> | |
| <meta name="timeout" content="long"> | |
| <title>SpeechRecognition Phrases</title> | |
| <script src="/resources/testdriver.js"></script> | |
| <script src="/resources/testdriver-vendor.js"></script> | |
| <script src="/resources/testharness.js"></script> | |
| <script src="/resources/testharnessreport.js"></script> | |
| <script> | |
| async function getAudioTrackFromFile(filePath) { | |
| const audioContext = new AudioContext(); | |
| const response = await fetch(filePath); | |
| const arrayBuffer = await response.arrayBuffer(); | |
| const audioBuffer = await audioContext.decodeAudioData(arrayBuffer); | |
| const source = audioContext.createBufferSource(); | |
| source.buffer = audioBuffer; | |
| const destination = audioContext.createMediaStreamDestination(); | |
| source.connect(destination); | |
| source.start(); | |
| return destination.stream.getAudioTracks()[0]; | |
| } | |
| promise_test(async (t) => { | |
| window.SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; | |
| // Install en-US for on-device speech recognition. | |
| const installOptions = { langs: ["en-US"], processLocally: true }; | |
| const installPromise = test_driver.bless( | |
| "Install on-device en-US speech recognition", | |
| () => SpeechRecognition.install(installOptions) | |
| ); | |
| assert_true( | |
| installPromise instanceof Promise, | |
| "SpeechRecognition.install() should return a Promise." | |
| ); | |
| const installResult = await installPromise; | |
| assert_true( | |
| installResult, | |
| "SpeechRecognition.install() for en-US should resolve with true." | |
| ); | |
| // Verify the audio track for recognition context exists. | |
| const audioTrack = await getAudioTrackFromFile("/media/recognition_context.mp3"); | |
| assert_true( | |
| audioTrack instanceof MediaStreamTrack, | |
| "Audio track should be a valid MediaStreamTrack" | |
| ); | |
| // Create the first speech recognition with a mode that does not support contextual biasing. | |
| // Note that this may vary between browsers in the future. | |
| const recognition1 = new SpeechRecognition(); | |
| recognition1.processLocally = false; | |
| recognition1.lang = "en-US"; | |
| recognition1.onerror = function(event) { | |
| assert_equals( | |
| event.error, | |
| "phrases-not-supported", | |
| "First speech recognition should throw a phrases-not-supported error" | |
| ); | |
| }; | |
| recognition1.phrases = new SpeechRecognitionPhraseList([ | |
| new SpeechRecognitionPhrase("test", 1.0) | |
| ]); | |
| // Create the second speech recognition with a mode that supports contextual biasing. | |
| const recognition2 = new SpeechRecognition(); | |
| recognition2.processLocally = true; | |
| recognition2.lang = "en-US"; | |
| recognition2.onerror = function(event) { | |
| // Currently WPT may not be able to detect that SODA is available and | |
| // will throw a "language-not-supported" error here. | |
| assert_unreached("Caught an error: " + event.error); | |
| }; | |
| recognition2.phrases = new SpeechRecognitionPhraseList([ | |
| new SpeechRecognitionPhrase("ASIC", 1.0), | |
| new SpeechRecognitionPhrase("FPGA", 1.0) | |
| ]); | |
| const recognitionPromise = new Promise((resolve) => { | |
| recognition2.onresult = (event) => { | |
| const transcript = event.results[0][0].transcript; | |
| const words = transcript.toLowerCase().split(' '); | |
| // Resolve when the last word is "expectations". | |
| if (words.length > 0 && words[words.length - 1] === "expectations") { | |
| resolve(transcript); | |
| } | |
| }; | |
| }); | |
| recognition2.start(audioTrack); | |
| const transcript = await recognitionPromise; | |
| assert_equals( | |
| transcript.toLowerCase(), | |
| "the report confirmed that the asic's throughput and " + | |
| "the fpga's latency were both below expectations", | |
| "Second speech recognition should correctly recognize the phrases" | |
| ); | |
| }, "SpeechRecognition should recognize speech with the given contextual information."); | |
| </script> | |
| </html> |