diff --git a/client/ws-client.js b/client/ws-client.js index b210d04..cfdcbab 100644 --- a/client/ws-client.js +++ b/client/ws-client.js @@ -7,7 +7,8 @@ var SpeechRecognitionEvent = SpeechRecognitionEvent || webkitSpeechRecognitionEv // #region state management var state = ''; var question = 0; -var rePrompt = false; +// currently disabled feature +// var rePrompt = false; var partTwo = false; var questionThreeCount = 0; var strike = 0; @@ -20,20 +21,25 @@ const QUESTION_TWO = 'Nennen Sie mir bitte so viel Dinge wie möglich, die man i const QUESTION_THREE = 'Ich werde Ihnen jetzt eine Zahlenreihe nennen, die Sie mir dann bitte in umgekehrter Reihenfolge wiederholen sollen. Wenn ich beispielsweise, vier - fünf sage, dann sagen Sie bitte, fünf - vier.'; const QUESTION_FOUR = 'Wir kommen nun zur vierten Frage. Bitte zählen Sie von 76 an rückwärts. Nennen Sie die Zahlen abwechselnd als ganze Zahlen und als einzelne Ziffern. Zum Beispiel:'; const QUESTION_FOUR_PT2 = ['34', '3, 3', '32', '3, 1']; +const QUESTION_FIVE = 'Ganz am Anfang dieses Tests habe ich Ihnen 10 Worte genannt. Können Sie sich noch an diese Worte erinnern?'; // #endregion +const FINISH = 'Sie sind jetzt fertig mit dem Test, Vielen Dank.'; + // #region intents const WELCOME_INTENT = 'Default Welcome Intent'; const WELCOME_FOLLOWUP_YES = 'Default Welcome Intent - yes'; const WELCOME_FOLLOWUP_NO = 'Default Welcome Intent - no'; -const MORE_TIME = 'Add Time Intent'; -const MORE_TIME_YES = 'Add Time Intent - yes'; -const MORE_TIME_NO = 'Add Time Intent - no'; +// currently disabled feature +// const MORE_TIME = 'Add Time Intent'; +// const MORE_TIME_YES = 'Add Time Intent - yes'; +// const MORE_TIME_NO = 'Add Time Intent - no'; const QUIT_INTENT = 'Quit Intent'; const FALLBACK_INTENT = 'Default Fallback Intent'; const HELP_INTENT = 'Help Intent'; const CHOOSE_QUESTION = 'Frage_Starten'; -const NEXT_QUESTION = 'Nächste Frage'; +// disabled feature +// const NEXT_QUESTION = 'Nächste Frage'; // #endregion // #region questions and expected results @@ -102,7 +108,7 @@ recognition.lang = 'de-DE'; recognition.maxAlternatives = 1; recognition.continuous = true; var answerQuery = ''; -var skipRecording = false; +var proceedWithRecording = false; // #endregion // #region speech synthesis initialization @@ -125,23 +131,11 @@ window.speechSynthesis.onvoiceschanged = function () { }; speechsynth.onend = function (event) { - switch (question) { - case 1: - break; - case 2: - break; - case 3: - break; - case 4: - break; - case 5: - break; - } - if (!skipRecording) { + if (proceedWithRecording) { recognition.start(); console.log('reocgnition started. Question: ' + question); } - skipRecording = false; + proceedWithRecording = false; diagnosticPara.textContent = ''; console.log('global speech end'); }; @@ -156,7 +150,6 @@ ws.onopen = function () { ws.onmessage = function (payload) { var dialogflowResult = JSON.parse(payload.data); checkIntent(dialogflowResult); - // document.querySelector('h1').innerHTML = dialogflowResult.intent.displayName; }; // #endregion @@ -165,48 +158,52 @@ function checkIntent (result) { switch (result.intent.displayName) { case QUIT_INTENT: state = 'quit'; - if (timerId !== undefined) { - clearTimeout(timerId); - } - skipRecording = true; + stopRecognitionFallback(); speak('Beende die Durchführung.'); break; case WELCOME_INTENT: state = 'detect'; + proceedWithRecording = true; speak(result.fulfillmentText); break; case WELCOME_FOLLOWUP_YES: startQuestion(1); break; case WELCOME_FOLLOWUP_NO: - skipRecording = true; - speak('Okay, Danke fürs Benutzen.'); + speak('Alles klar. Danke fürs Benutzen.'); break; - case MORE_TIME: - state = 'detect'; - speak('Brauchen Sie noch etwas Zeit?'); - break; - case MORE_TIME_YES: - rePrompt = true; - state = 'answer'; - speak('Alles klar'); - break; - case MORE_TIME_NO: - skipRecording = true; - state = 'answer'; - speak('Verstanden'); + /// /// /// currently disabled feature + // case MORE_TIME: + // state = 'detect'; + // proceedWithRecording = true; + // speak('Brauchen Sie noch etwas Zeit?'); + // break; + // case MORE_TIME_YES: + // rePrompt = true; + // state = 'answer'; + // proceedWithRecording = true; + // speak('Alles klar'); + // break; + // case MORE_TIME_NO: + // state = 'answer'; + // speak('Verstanden'); + // recognition.stop(); + // ws.send(answerQuery); + // break; + // case CHOOSE_QUESTION: + // question = result.parameters.fields.num.numberValue; + // state = 'answer'; + // handleQuestion(); + // break; + /// /// /// + case HELP_INTENT: + stopRecognitionFallback(); recognition.stop(); - ws.send(answerQuery); - break; - case CHOOSE_QUESTION: - question = result.parameters.fields.num.numberValue; - state = 'answer'; - handleQuestion(); + startQuestion(question); break; case FALLBACK_INTENT: - // if (state === 'answer') { - // handleAnswer(result.queryText) - // } + // fallback what should happen if no intent is detected + // this is handled in the processSpeech() function break; default: break; @@ -217,6 +214,7 @@ function checkIntent (result) { function startQuestion (number) { question = number; state = 'answer'; + answerQuery = ''; questionNumDisplay.textContent = 'Question: ' + question; handleQuestion(); } @@ -224,9 +222,7 @@ function startQuestion (number) { function handleQuestion () { switch (question) { case 1: - skipRecording = true; - speak(QUESTION_ONE); - readQuestionOne(); + readQuestionOne(QUESTION_ONE); break; case 2: readQuestionTwo(); @@ -238,11 +234,14 @@ function handleQuestion () { readQuestionFour(); break; case 5: + proceedWithRecording = true; + speak(QUESTION_FIVE); break; } } -function readQuestionOne () { +function readQuestionOne (questionText) { + speak(questionText); for (let i = 0; i < QUESTION_ONE_QUESTIONS.length; i++) { let utterance = new SpeechSynthesisUtterance(); utterance.voice = voices[2]; @@ -280,7 +279,6 @@ function readQuestionTwo () { } function readQuestionThree () { - skipRecording = true; speak('Dankeschön, weiter geht es mit der nächsten Frage.'); let utterance = new SpeechSynthesisUtterance(); utterance.voice = voices[2]; @@ -288,13 +286,13 @@ function readQuestionThree () { utterance.rate = 0.88; window.speechSynthesis.speak(utterance); utterance.onend = function (event) { + proceedWithRecording = true; speak(QUESTION_THREE_QUESTIONS_PT1[questionThreeCount]); }; } function readQuestionFour () { - // skipRecording = true; - // speak(QUESTION_FOUR); + speak(QUESTION_FOUR); for (let i = 0; i < QUESTION_FOUR_PT2.length; i++) { let utterance = new SpeechSynthesisUtterance(); utterance.voice = voices[2]; @@ -302,7 +300,7 @@ function readQuestionFour () { utterance.text = QUESTION_FOUR_PT2[i]; window.speechSynthesis.speak(utterance); } - // speak('Sie haben hierfür 1 Minute Zeit.'); + speak('Sie haben hierfür 1 Minute Zeit.'); } function handleAnswer (query) { @@ -317,37 +315,33 @@ function handleAnswer (query) { handleAnswerToThirdQuestion(query); break; case 4: + // not possible with the current state of web speech api + // handleAnswerToFourthQuestion(query); break; case 5: + handleAnswerToFifthQuestion(query); break; } } function handleAnswerToFirstQuestion (answer) { - var tokens = answer.split(new RegExp(separators.join('|'), 'g')); - questionPoints[question] += calculatePoints(tokens, QUESTION_ONE_ANSWERS); + deconstructAndCalculateAnswer(answer); if (partTwo) { partTwo = false; - console.log('question 1 points: ' + questionPoints[question]); - skipRecording = true; speak('Vielen Dank, nun geht es weiter mit der nächsten Frage'); startQuestion(2); - // state = 'detect' } else { - rePrompt = false; - skipRecording = true; + // currently disabled feature + // rePrompt = false; speak(QUESTION_ONE_PT2); - readQuestionOne(QUESTION_ONE); + readQuestionOne(QUESTION_ONE_PT2); partTwo = true; } } function handleAnswerToSecondQuestion (answer) { - var tokens = answer.split(new RegExp(separators.join('|'), 'g')); - questionPoints[question] = calculatePoints(tokens, QUESTION_TWO_ANSWERS); - console.log('question 2 points: ' + questionPoints[question]); + deconstructAndCalculateAnswer(answer); startQuestion(3); - // state = 'detect' } function handleAnswerToThirdQuestion (query) { @@ -376,41 +370,58 @@ function handleAnswerToThirdQuestion (query) { if (strike === 2 || questionThreeCount === 5) { speechsynth.rate = 0.88; console.log('question 3 points: ' + questionPoints[question]); - skipRecording = true; speak('weiter geht es mit der Nächsten Frage'); - startQuestion(4); + // Question 4 is not possible to take, because of technical limitation + // startQuestion(4); + + startQuestion(5); return; } - + proceedWithRecording = true; speak(questionArray[questionThreeCount]); console.log('count: ' + questionThreeCount + ', strike: ' + strike + ', points: ' + questionPoints[question]); } + +// not possible with the current state of web speech api +// function handleAnswerToFourthQuestion (answer) { +// // In order to evaluate the answer, the recognizer has to distinguish between the number 77 spoken "seventy seven" and 7-7 spoken "seven seven", which it doesnt +// startQuestion(5); +// } + +function handleAnswerToFifthQuestion (answer) { + deconstructAndCalculateAnswer(answer); + speak(FINISH); +} + // #endregion +// NOT SUPPORTED // function recognizeSpeech () { -// if (state === 'answer') { // var arr; // switch (question) { // case 1: // arr = QUESTION_ONE_QUESTIONS; // break; // case 2: -// // arr = QUESTION_TWO_QUESTIONS; +// arr = QUESTION_TWO_QUESTIONS; // break; // case 3: // arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]; // break; // case 4: +// arr = ['eins', 'zwei', 'drei', 'vier', 'fünf', 'sechs', 'sieben', 'acht', 'neun']; // break; // case 5: // break; // } -// // var grammar = '#JSGF V1.0; grammar colors; public = ' + arr.join(' | ') + ' ;'; -// // var speechRecognitionList = new SpeechGrammarList(); -// // speechRecognitionList.addFromString(grammar, 1); -// // recognition.grammars = speechRecognitionList; +// var grammar = '#JSGF V1.0; grammar arr; public = ' + arr.join(' | ') + ' ;'; +// var speechRecognitionList = new SpeechGrammarList(); +// speechRecognitionList.addFromString(grammar, 1); +// recognition.grammars = speechRecognitionList; + +// recognition.start(); // } // #region speech recognition event @@ -506,18 +517,16 @@ function processSpeech (speechResult) { } if (state === 'answer') { - if (timerId != undefined) { - clearTimeout(timerId); - } + stopRecognitionFallback(); answerQuery += speechResult; timerId = window.setTimeout( function () { + // currently disabled // if (!rePrompt) { // ws.send('ich brauche noch etwas Zeit') // } else { console.log('recording end. Evaluate: ' + answerQuery); handleAnswer(answerQuery); - answerQuery = ''; diagnosticPara.textContent = ''; // } recognition.stop(); @@ -539,14 +548,7 @@ function startDemenzScreening () { } function testSpeechOut () { - readQuestionFour(); - - // speechsynth.text = 'test 123'; - // speechsynth.volume = 1; - // speechsynth.rate = 1; - // console.log(speechsynth); - // window.speechSynthesis.speak(speechsynth); - // console.log(window.speechSynthesis); + question = 4; } function speak (sentence) { @@ -554,6 +556,29 @@ function speak (sentence) { window.speechSynthesis.speak(speechsynth); } +function stopRecognitionFallback () { + if (timerId != undefined) { + clearTimeout(timerId); + } +} + +function deconstructAndCalculateAnswer (answer) { + let questionAnswers; + switch (question) { + case 1: + questionAnswers = QUESTION_ONE_ANSWERS; + break; + case 2: + questionAnswers = QUESTION_TWO_ANSWERS; + break; + case 5: + questionAnswers = QUESTION_ONE_ANSWERS; + break; + } + var tokens = answer.split(new RegExp(separators.join('|'), 'g')); + questionPoints[question] += calculatePoints(tokens, questionAnswers); +} + function calculatePoints (tokens, d) { let points = 0; let dict = {};