From a5c9e8c74b11a96c1c411414a52bedd88193b350 Mon Sep 17 00:00:00 2001 From: Jaromir Wysoglad Date: Thu, 1 Aug 2019 21:42:38 +0200 Subject: TESTBET: Add TTS tests --- engines/testbed/module.mk | 1 + engines/testbed/speech.cpp | 430 ++++++++++++++++++++++++++++++++++++++++++++ engines/testbed/speech.h | 78 ++++++++ engines/testbed/testbed.cpp | 11 +- 4 files changed, 519 insertions(+), 1 deletion(-) create mode 100644 engines/testbed/speech.cpp create mode 100644 engines/testbed/speech.h (limited to 'engines') diff --git a/engines/testbed/module.mk b/engines/testbed/module.mk index d8ff0e70b5..0dcbfb7411 100644 --- a/engines/testbed/module.mk +++ b/engines/testbed/module.mk @@ -12,6 +12,7 @@ MODULE_OBJS := \ savegame.o \ sound.o \ encoding.o \ + speech.o \ testbed.o \ testsuite.o diff --git a/engines/testbed/speech.cpp b/engines/testbed/speech.cpp new file mode 100644 index 0000000000..65fbbfd65e --- /dev/null +++ b/engines/testbed/speech.cpp @@ -0,0 +1,430 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/text-to-speech.h" +#include "common/system.h" +#include "common/array.h" +#include "engines/testbed/speech.h" + +namespace Testbed { + +TestExitStatus Speechtests::testMale() { + Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager(); + ttsMan->setLanguage("en"); + ttsMan->setVolume(100); + ttsMan->setRate(0); + ttsMan->setPitch(0); + Testsuite::clearScreen(); + Common::String info = "Male voice test. You should expect a male voice to say \"Testing text to speech with male voice.\""; + + Common::Point pt(0, 100); + Testsuite::writeOnScreen("Testing male TTS voice", pt); + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : testMale\n"); + return kTestSkipped; + } + + Common::Array maleVoices = ttsMan->getVoiceIndicesByGender(Common::TTSVoice::MALE); + if (maleVoices.size() == 0) { + Testsuite::displayMessage("No male voice available"); + return kTestFailed; + } + ttsMan->setVoice(maleVoices[0]); + ttsMan->say("Testing text to speech with male voice."); + while (ttsMan->isSpeaking()) { + g_system->delayMillis(1000); + } + Common::String prompt = "Did you hear male voice saying: \"Testing text to speech with male voice.\" ?"; + if (!Testsuite::handleInteractiveInput(prompt, "Yes", "No", kOptionLeft)) { + Testsuite::logDetailedPrintf("Male TTS failed\n"); + return kTestFailed; + } + return kTestPassed; +} + +TestExitStatus Speechtests::testFemale() { + Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager(); + ttsMan->setLanguage("en"); + ttsMan->setVolume(100); + ttsMan->setRate(0); + ttsMan->setPitch(0); + Testsuite::clearScreen(); + Common::String info = "Female voice test. You should expect a female voice to say \"Testing text to speech with female voice.\""; + + Common::Point pt(0, 100); + Testsuite::writeOnScreen("Testing female TTS voice", pt); + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : testFemale\n"); + return kTestSkipped; + } + + Common::Array femaleVoices = ttsMan->getVoiceIndicesByGender(Common::TTSVoice::FEMALE); + if (femaleVoices.size() == 0) { + Testsuite::displayMessage("No female voice available"); + } + ttsMan->setVoice(femaleVoices[0]); + ttsMan->say("Testing text to speech with female voice."); + while (ttsMan->isSpeaking()) { + g_system->delayMillis(1000); + } + Common::String prompt = "Did you hear female voice saying: \"Testing text to speech with female voice.\" ?"; + if (!Testsuite::handleInteractiveInput(prompt, "Yes", "No", kOptionLeft)) { + Testsuite::logDetailedPrintf("Female TTS failed\n"); + return kTestFailed; + } + return kTestPassed; +} + +TestExitStatus Speechtests::testStop() { + Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager(); + ttsMan->setLanguage("en"); + ttsMan->setVolume(100); + ttsMan->setRate(0); + ttsMan->setPitch(0); + ttsMan->setVoice(0); + Testsuite::clearScreen(); + Common::String info = "Text to speech stop test. You should expect a voice to start speaking and after approximately a second it should stop the speech"; + + Common::Point pt(0, 100); + Testsuite::writeOnScreen("Testing TTS stop", pt); + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : testStop\n"); + return kTestSkipped; + } + + ttsMan->say("Testing text to speech, the speech should stop after approximately a second after it started, so it shouldn't have the time to read this."); + g_system->delayMillis(1000); + ttsMan->stop(); + Common::String prompt = "Did you hear a voice saying: \"Testing text to speech, the speech should stop after approximately a second after it started, so it shouldn't have the time to read this.\" but stopping in the middle?"; + if (!Testsuite::handleInteractiveInput(prompt, "Yes", "No", kOptionLeft)) { + Testsuite::logDetailedPrintf("TTS stop failed\n"); + return kTestFailed; + } + return kTestPassed; +} + +TestExitStatus Speechtests::testPauseResume() { + Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager(); + ttsMan->setLanguage("en"); + ttsMan->setVolume(100); + ttsMan->setRate(0); + ttsMan->setPitch(0); + ttsMan->setVoice(0); + Testsuite::clearScreen(); + Common::String info = "Text to speech pause test. You should expect a voice to start speaking, then after approximately a second of speech, it should pause for about a second and then continue from where it left."; + + Common::Point pt(0, 100); + Testsuite::writeOnScreen("Testing TTS pause", pt); + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : testPauseResume\n"); + return kTestSkipped; + } + + ttsMan->say("Testing text to speech, the speech should pause after a second and then resume again."); + g_system->delayMillis(1000); + ttsMan->pause(); + g_system->delayMillis(2000); + ttsMan->resume(); + while (ttsMan->isSpeaking()) + g_system->delayMillis(1000); + Common::String prompt = "Did you hear a voice saying: \"Testing text to speech, the speech should pause after a second and then resume again.\" but with a second long pause in the middle?"; + if (!Testsuite::handleInteractiveInput(prompt, "Yes", "No", kOptionLeft)) { + Testsuite::logDetailedPrintf("TTS pauseResume failed\n"); + return kTestFailed; + } + return kTestPassed; +} + +TestExitStatus Speechtests::testRate() { + Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager(); + ttsMan->setLanguage("en"); + ttsMan->setVolume(100); + ttsMan->setRate(0); + ttsMan->setPitch(0); + ttsMan->setVoice(0); + Testsuite::clearScreen(); + Common::String info = "Text to speech rate test. You should expect a voice to say: \"Text to speech slow rate.\" really slowly and then \"Text to speech fast rate\" really fast"; + + Common::Point pt(0, 100); + Testsuite::writeOnScreen("Testing TTS rate", pt); + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : testRate\n"); + return kTestSkipped; + } + + ttsMan->setRate(-100); + ttsMan->say("Text to speech slow rate."); + while (ttsMan->isSpeaking()) + g_system->delayMillis(1000); + ttsMan->setRate(100); + ttsMan->say("Text to speech fast rate."); + while (ttsMan->isSpeaking()) + g_system->delayMillis(1000); + Common::String prompt = "Did you hear a voice saying: \"Text to speech slow rate.\" slowly and then \"Text to speech fast rate.\" fast?"; + if (!Testsuite::handleInteractiveInput(prompt, "Yes", "No", kOptionLeft)) { + Testsuite::logDetailedPrintf("TTS rate failed\n"); + return kTestFailed; + } + return kTestPassed; +} + +TestExitStatus Speechtests::testVolume() { + Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager(); + ttsMan->setLanguage("en"); + ttsMan->setVolume(100); + ttsMan->setRate(0); + ttsMan->setPitch(0); + ttsMan->setVoice(0); + Testsuite::clearScreen(); + Common::String info = "Text to speech volume test. You should expect a voice to say: \"Text to speech low volume.\" quietly and then \"Text to speech max volume\" at a higher volume"; + + Common::Point pt(0, 100); + Testsuite::writeOnScreen("Testing TTS volume", pt); + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : testVolume\n"); + return kTestSkipped; + } + + ttsMan->setVolume(20); + ttsMan->say("Text to speech low volume."); + while (ttsMan->isSpeaking()) + g_system->delayMillis(1000); + ttsMan->setVolume(100); + ttsMan->say("Text to speech max volume."); + while (ttsMan->isSpeaking()) + g_system->delayMillis(1000); + Common::String prompt = "Did you hear a voice saying: \"Text to speech low volume.\" quietly and then \"Text to speech max volume.\" at a higher volume?"; + if (!Testsuite::handleInteractiveInput(prompt, "Yes", "No", kOptionLeft)) { + Testsuite::logDetailedPrintf("TTS volume failed\n"); + return kTestFailed; + } + return kTestPassed; +} + +TestExitStatus Speechtests::testPitch() { + Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager(); + ttsMan->setLanguage("en"); + ttsMan->setVolume(100); + ttsMan->setRate(0); + ttsMan->setPitch(0); + ttsMan->setVoice(0); + Testsuite::clearScreen(); + Common::String info = "Text to speech pitch test. You should expect a high pitched voice to say: \"Text to speech high pitch.\" and then a low pitched voice: \"Text to speech low pitch\""; + + Common::Point pt(0, 100); + Testsuite::writeOnScreen("Testing TTS pitch", pt); + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : testPitch\n"); + return kTestSkipped; + } + + ttsMan->setPitch(100); + ttsMan->say("Text to speech high pitch."); + while (ttsMan->isSpeaking()) + g_system->delayMillis(1000); + ttsMan->setPitch(-100); + ttsMan->say("Text to speech low pitch."); + while (ttsMan->isSpeaking()) + g_system->delayMillis(1000); + Common::String prompt = "Did you hear a high pitched voice saying: \"Text to speech high pitch.\" and then a low pitched voice: \"Text to speech low pitch.\" ?"; + if (!Testsuite::handleInteractiveInput(prompt, "Yes", "No", kOptionLeft)) { + Testsuite::logDetailedPrintf("TTS pitch failed\n"); + return kTestFailed; + } + return kTestPassed; +} + +TestExitStatus Speechtests::testStateStacking() { + Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager(); + ttsMan->setLanguage("en"); + ttsMan->setVolume(100); + ttsMan->setRate(0); + ttsMan->setPitch(0); + ttsMan->setVoice(0); + Testsuite::clearScreen(); + Common::String info = "Text to speech state stacking test. You should expect a speech from three different voices (different pitch, gender, volume and speech rate), each voice will say: \"Voice number X is speaking.\", the voices will speak in this order: 1, 2, 3, 2, 1. A voice with the same number should sound the same every time"; + + Common::Point pt(0, 100); + Testsuite::writeOnScreen("Testing TTS state stacking", pt); + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : testStateStacking\n"); + return kTestSkipped; + } + + ttsMan->say("Voice number 1 is speaking"); + while (ttsMan->isSpeaking()) + g_system->delayMillis(1000); + ttsMan->pushState(); + Common::Array femaleVoices = ttsMan->getVoiceIndicesByGender(Common::TTSVoice::FEMALE); + Common::Array allVoices = ttsMan->getVoicesArray(); + if (femaleVoices.size() == 0) + ttsMan->setVoice(1 % allVoices.size()); + else + ttsMan->setVoice(femaleVoices[0]); + ttsMan->setVolume(80); + ttsMan->setPitch(40); + ttsMan->setRate(-30); + ttsMan->say("Voice number 2 is speaking"); + while (ttsMan->isSpeaking()) + g_system->delayMillis(1000); + ttsMan->pushState(); + ttsMan->setVoice(2 % allVoices.size()); + ttsMan->setVolume(90); + ttsMan->setPitch(-80); + ttsMan->setRate(-50); + ttsMan->say("Voice number 3 is speaking"); + while (ttsMan->isSpeaking()) + g_system->delayMillis(1000); + ttsMan->popState(); + ttsMan->say("Voice number 2 is speaking"); + while (ttsMan->isSpeaking()) + g_system->delayMillis(1000); + ttsMan->popState(); + ttsMan->say("Voice number 1 is speaking"); + while (ttsMan->isSpeaking()) + g_system->delayMillis(1000); + + Common::String prompt = "Did you hear three different voices speaking in this order: 1, 2, 3, 2, 1 and each time the same voice spoke, it sounded the same?"; + if (!Testsuite::handleInteractiveInput(prompt, "Yes", "No", kOptionLeft)) { + Testsuite::logDetailedPrintf("TTS state stacking\n"); + return kTestFailed; + } + return kTestPassed; +} + +TestExitStatus Speechtests::testQueueing() { + Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager(); + ttsMan->setLanguage("en"); + ttsMan->setVolume(100); + ttsMan->setRate(0); + ttsMan->setPitch(0); + ttsMan->setVoice(0); + Testsuite::clearScreen(); + Common::String info = "Text to speech queue test. You should expect a voice to say: \"This is first speech. This is queued second speech\""; + + Common::Point pt(0, 100); + Testsuite::writeOnScreen("Testing TTS queue", pt); + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : testQueueing\n"); + return kTestSkipped; + } + + ttsMan->say("This is first speech."); + ttsMan->say("This is second speech.", Common::TextToSpeechManager::QUEUE); + while (ttsMan->isSpeaking()) + g_system->delayMillis(1000); + Common::String prompt = "Did you hear a voice saying: \"This is first speech. This is second speech\" ?"; + if (!Testsuite::handleInteractiveInput(prompt, "Yes", "No", kOptionLeft)) { + Testsuite::logDetailedPrintf("TTS queue failed\n"); + return kTestFailed; + } + return kTestPassed; +} + +TestExitStatus Speechtests::testInterrupting() { + Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager(); + ttsMan->setLanguage("en"); + ttsMan->setVolume(100); + ttsMan->setRate(0); + ttsMan->setPitch(0); + ttsMan->setVoice(0); + Testsuite::clearScreen(); + Common::String info = "Text to speech interrupt test. You should expect a voice to start saying english alphabet and after about a second it should get interrupted and say: \"Speech intprrupted\" instead."; + + Common::Point pt(0, 100); + Testsuite::writeOnScreen("Testing TTS interrupt", pt); + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : testInterrupting\n"); + return kTestSkipped; + } + + ttsMan->say("A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z"); + g_system->delayMillis(1000); + ttsMan->say("Speech interrupted", Common::TextToSpeechManager::INTERRUPT); + while (ttsMan->isSpeaking()) + g_system->delayMillis(1000); + Common::String prompt = "Did you hear a voice saying the engilsh alphabet, but it got interrupted and said: \"Speech interrupted\" instead?"; + if (!Testsuite::handleInteractiveInput(prompt, "Yes", "No", kOptionLeft)) { + Testsuite::logDetailedPrintf("TTS interrupt failed\n"); + return kTestFailed; + } + return kTestPassed; +} + +TestExitStatus Speechtests::testDroping() { + Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager(); + ttsMan->setLanguage("en"); + ttsMan->setVolume(100); + ttsMan->setRate(0); + ttsMan->setPitch(0); + ttsMan->setVoice(0); + Testsuite::clearScreen(); + Common::String info = "Text to speech drop test. You should expect a voice to start say:\"Today is a really nice weather, perfect day to use ScummVM, don't you think?\" and nothing else."; + + Common::Point pt(0, 100); + Testsuite::writeOnScreen("Testing TTS drop", pt); + + if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) { + Testsuite::logPrintf("Info! Skipping test : testDroping\n"); + return kTestSkipped; + } + + ttsMan->say("Today is a really nice weather, perfect day to use ScummVM, don't you think?"); + ttsMan->say("Speech interrupted, fail", Common::TextToSpeechManager::DROP); + while (ttsMan->isSpeaking()) + g_system->delayMillis(1000); + Common::String prompt = "Did you hear a voice say: \"Today is a really nice weather, perfect day to use ScummVM, don't you think?\" and nothing else?"; + if (!Testsuite::handleInteractiveInput(prompt, "Yes", "No", kOptionLeft)) { + Testsuite::logDetailedPrintf("TTS drop failed\n"); + return kTestFailed; + } + return kTestPassed; +} + +SpeechTestSuite::SpeechTestSuite() { + _isTsEnabled = true; + if (!g_system->getTextToSpeechManager()) + _isTsEnabled = false; + addTest("testMale", &Speechtests::testMale, true); + addTest("testFemale", &Speechtests::testFemale, true); + addTest("testStop", &Speechtests::testStop, true); + addTest("testPauseResume", &Speechtests::testPauseResume, true); + addTest("testRate", &Speechtests::testRate, true); + addTest("testVolume", &Speechtests::testVolume, true); + addTest("testPitch", &Speechtests::testPitch, true); + addTest("testStateStacking", &Speechtests::testStateStacking, true); + addTest("testQueueing", &Speechtests::testQueueing, true); + addTest("testInterrupting", &Speechtests::testInterrupting, true); + addTest("testDroping", &Speechtests::testDroping, true); +} + +} // End of namespace Testbed diff --git a/engines/testbed/speech.h b/engines/testbed/speech.h new file mode 100644 index 0000000000..a5f576d300 --- /dev/null +++ b/engines/testbed/speech.h @@ -0,0 +1,78 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef TESTBED_TEMPLATE_H +#define TESTBED_TEMPLATE_H + +#include "testbed/testsuite.h" +#include "common/text-to-speech.h" + +namespace Testbed { + +namespace Speechtests { + +// Helper functions for Speech tests + +// will contain function declarations for Speech tests +// add more here + +TestExitStatus testMale(); +TestExitStatus testFemale(); +TestExitStatus testStop(); +TestExitStatus testPauseResume(); +TestExitStatus testRate(); +TestExitStatus testVolume(); +TestExitStatus testPitch(); +TestExitStatus testStateStacking(); +TestExitStatus testQueueing(); +TestExitStatus testInterrupting(); +TestExitStatus testDroping(); + + +} // End of namespace Speechtests + +class SpeechTestSuite : public Testsuite { +public: + /** + * The constructor for the XXXTestSuite + * For every test to be executed one must: + * 1) Create a function that would invoke the test + * 2) Add that test to list by executing addTest() + * + * @see addTest() + */ + SpeechTestSuite(); + ~SpeechTestSuite() {} + const char *getName() const { + return "Speech"; + } + + const char *getDescription() const { + return "Speech Subsystem"; + } + +}; + + +} // End of namespace Testbed + +#endif // TESTBED_TEMPLATE_H diff --git a/engines/testbed/testbed.cpp b/engines/testbed/testbed.cpp index 1b0c2dd776..44d491fe04 100644 --- a/engines/testbed/testbed.cpp +++ b/engines/testbed/testbed.cpp @@ -46,6 +46,9 @@ #ifdef USE_SDL_NET #include "testbed/webserver.h" #endif +#ifdef USE_TTS +#include "testbed/speech.h" +#endif namespace Testbed { @@ -120,8 +123,14 @@ TestbedEngine::TestbedEngine(OSystem *syst) DebugMan.enableDebugChannel("LOG"); // Initialize testsuites here + Testsuite *ts; +#ifdef USE_TTS + // TextToSpeech + ts = new SpeechTestSuite(); + _testsuiteList.push_back(ts); +#endif // GFX - Testsuite *ts = new GFXTestSuite(); + ts = new GFXTestSuite(); _testsuiteList.push_back(ts); // FS ts = new FSTestSuite(); -- cgit v1.2.3