Commit 1b6e9f00 authored by Martin LOISEAU's avatar Martin LOISEAU 🎄
Browse files

Rework global system (tts now non blocking) but broke speech recognition

parent f59a3700
......@@ -18,6 +18,7 @@ class Listener implements RecognitionListener
{
result_available = false;
result_strings = null;
already_gave_results = false;
this.mainActivity = mainActivity;
Log.d("Debug2", "Listener created");
}
......
......@@ -40,7 +40,6 @@ public class MainActivity extends AppCompatActivity {
SpeechRecognizer sr;
GoogleApiAvailability m_gga;
public TTSReader ttsreader;
public MainThread mainThread;
private CaptureQR QRActionRequesting;
private CaptureSpeech SpeechRequest;
private Intent recognizerIntent;
......@@ -54,8 +53,8 @@ public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.title_screen);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//Toolbar toolbar = findViewById(R.id.toolbar);
//setSupportActionBar(toolbar);
ttsreader = new TTSReader(this);
Log.d("Debug2", "App launched");
......@@ -67,7 +66,6 @@ public class MainActivity extends AppCompatActivity {
errorDia.show();
}
mainThread = new MainThread(this);
SetUpListener();
Atoms = new ArrayList<Atom>();
......@@ -110,9 +108,38 @@ public class MainActivity extends AppCompatActivity {
NodesToAdd.clear();
}
// mainThread contains the rest of the logic
// threading should prevent blocking of use but as it is user input seems still locked for some actions (TTS)
if(OpenNodes.size()>0) mainThread.run();
if(OpenNodes.size()>0) {
Log.d("Debug2", "CheckOpenNodes called");
Log.d("Debug2", "===================================================================");
Log.d("Debug2", "Open Nodes:");
// First we display every open node and every atom (useful for debug)
for (Node n : OpenNodes) {
String node_info = "ID: " + n.ID + " requires ";
for (Atom a : n.Conditions) {
node_info += a.displayType() + a.GetStringValue() + " ";
}
Log.d("Debug2", node_info);
}
Log.d("Debug2", "Current Atoms : ");
for (Atom a : Atoms) {
Log.d("Debug2", a.displayType() + a.GetStringValue());
}
Log.d("Debug2", "===================================================================");
// Then we check every node and trigger the first one where the conditions are satisfied (every required atom present)
for (Node n : OpenNodes) {
if (n.CheckConditions(Atoms)) {
Log.d("Debug2", "Triggering node " + Integer.toString(n.ID));
n.Trigger();
// Log.d("Debug2", "Node " + Integer.toString(n.ID) + " actions are over.");
break;
}
}
// mainThread contains the rest of the logic
// threading should prevent blocking of use but as it is user input seems still locked for some actions (TTS)
}
else Log.d("Debug2", "NO OPEN NODE - GAME OVER");
}
......@@ -129,6 +156,7 @@ public class MainActivity extends AppCompatActivity {
throw new Error("No existing node has the requested ID: " + ID);
}
private void initializeListeners() {
// initialisation of button, unused in the game but usefull for testing input
......@@ -151,7 +179,7 @@ public class MainActivity extends AppCompatActivity {
public void onClick(View view) {
Snackbar.make(view, "Should read some text out loud using speech synthesis", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
ttsreader.PlayTTS("Bonjour");
//ttsreader.PlayTTS("Bonjour");
}
});
......@@ -180,10 +208,14 @@ public class MainActivity extends AppCompatActivity {
public void LaunchGame(View v) // called when the "play" button is pressed on title screen
{
Log.d("Debug2", "LaunchGame() called");
setContentView(R.layout.background_picture);
CheckOpenNodes();
setContentView(R.layout.activity_main);
initializeListeners();
//setContentView(R.layout.activity_main);
//initializeListeners();
}
@Override
......@@ -240,8 +272,8 @@ public class MainActivity extends AppCompatActivity {
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d("Debug2", "QR data retrieved in main activity: " + data.getStringExtra("QR_CONTENT"));
Snackbar.make(findViewById(R.id.main_layout), "QR code says:" + data.getStringExtra("QR_CONTENT") , Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
// Snackbar.make(findViewById(R.id.background_picture), "QR code says:" + data.getStringExtra("QR_CONTENT") , Snackbar.LENGTH_LONG)
// .setAction("Action", null).show();
if(QRActionRequesting != null) QRActionRequesting.GiveQRResult(data.getStringExtra("QR_CONTENT"));
}
......@@ -249,6 +281,8 @@ public class MainActivity extends AppCompatActivity {
@Override
protected void onPostResume() {
super.onPostResume();
//setContentView(R.layout.background_picture);
// Trigger the end of QRActionRequesting only onPostResume() to avoid a weird crash
if(QRActionRequesting != null) QRActionRequesting.TriggerEnd();
}
......@@ -290,8 +324,9 @@ public class MainActivity extends AppCompatActivity {
this.SpeechRequest = calling_action;
listener = new Listener(this);
Log.d("Debug2", "Listener fully initialized");
sr = SpeechRecognizer.createSpeechRecognizer(this);
Log.d("Debug2", "sr = SpeechRecognizer.createSpeechRecognizer(this); called");
sr.setRecognitionListener(listener);
Log.d("Debug2", "Start listening speech recognizer");
sr.startListening(recognizerIntent);
......
package com.example.qrquest;
import android.util.Log;
import com.example.qrquest.atom.Atom;
import com.example.qrquest.node.Node;
public class MainThread implements Runnable {
private MainActivity mainActivity;
public MainThread(MainActivity mainActivity)
{
super();
this.mainActivity = mainActivity;
}
public void CheckOpenNodes() {
Log.d("Debug2", "CheckOpenNodes called");
Log.d("Debug2", "===================================================================");
Log.d("Debug2", "Open Nodes:");
// First we display every open node and every atom (useful for debug)
for (Node n : mainActivity.OpenNodes)
{
String node_info = "ID: " + n.ID + " requires ";
for (Atom a: n.Conditions)
{
node_info += a.displayType() + a.GetStringValue() + " ";
}
Log.d("Debug2", node_info);
}
Log.d("Debug2", "Current Atoms : ");
for (Atom a : mainActivity.Atoms)
{
Log.d("Debug2", a.displayType() + a.GetStringValue());
}
Log.d("Debug2", "===================================================================");
// Then we check every node and trigger the first one twhere the conditions are satisfied (every required atom present)
for (Node n : mainActivity.OpenNodes)
{
if (n.CheckConditions(mainActivity.Atoms))
{
Log.d("Debug2", "Triggering node " + Integer.toString(n.ID));
n.Trigger();
break;
}
}
}
@Override
public void run() {
this.CheckOpenNodes();
}
}
......@@ -3,12 +3,19 @@ package com.example.qrquest;
import android.content.Context;
import android.os.Build;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.util.Log;
import com.example.qrquest.actions.TTSReading;
import java.util.HashMap;
import java.util.Locale;
public final class TTSReader { // basically a static class
final TextToSpeech tts;
final private TextToSpeech tts;
private UtteranceProgressListener progress_listener;
private HashMap<String, String> map = new HashMap<String, String>();
public TTSReader(Context context)
{
......@@ -20,19 +27,35 @@ public final class TTSReader { // basically a static class
});
}
public boolean PlayTTS(String TextToPlay)
public boolean PlayTTS(String TextToPlay, final TTSReading ActionToNotify)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
tts.speak(TextToPlay,TextToSpeech.QUEUE_FLUSH,null,null);
} else {
tts.speak(TextToPlay, TextToSpeech.QUEUE_FLUSH, null);
}
return true;
}
//if(tts.isSpeaking()) throw new Error("Tried PlayTTS() while text is still playing");
map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "UniqueID");
public boolean isOver()
{
return(!tts.isSpeaking());
}
progress_listener = new UtteranceProgressListener() {
@Override
public void onStart(String utteranceId) {
Log.d("Debug2", "Utterance detect tts reading starting");
}
@Override
public void onDone(String utteranceId) {
Log.d("Debug2", "Utterance detect tts reading over");
ActionToNotify.ReadingFinished();
}
@Override
public void onError(String utteranceId) {
}
};
tts.setOnUtteranceProgressListener(progress_listener);
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// tts.speak(TextToPlay,TextToSpeech.QUEUE_FLUSH,null,null);
//} else {
tts.speak(TextToPlay, TextToSpeech.QUEUE_FLUSH, map);
// }
return true;
}
}
......@@ -16,7 +16,7 @@ public class CaptureSpeech extends Action {
public void Do()
{
Log.d("Debug2", "Capture speed action started");
Log.d("Debug2", "Capture speech action started");
super.Do();
mainActivity.GetSpeech(this);
}
......
......@@ -22,10 +22,12 @@ public class TTSReading extends Action {
{
super.Do();
// read TextToRead
mainActivity.ttsreader.PlayTTS(TextToRead);
mainActivity.ttsreader.PlayTTS(TextToRead, this);
Log.d("Debug2", "Reading : \"" + TextToRead + "\"");
while(!mainActivity.ttsreader.isOver()) {} // block while speaking
// This seems to blocks other inputs from the player such as changing volume
}
public void ReadingFinished()
{
End();
}
......
......@@ -67,6 +67,7 @@ public class Node {
}
else
{
Log.d("Debug2", "No actions remaining for node " + ID + ". Calling CheckOpenNodes()");
mainActivity.CheckOpenNodes();
}
}
......
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/imageView2"
android:layout_width="347dp"
android:layout_height="0dp"
app:srcCompat="@drawable/picture"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="32dp"
tools:layout_editor_absoluteY="89dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
......@@ -134,9 +134,9 @@ Aide Kouzou à fabriquer le miroir afin de le sortir de ce mauvais pas. --></TTS
<action_list>
<ClearAtoms>QRAtom</ClearAtoms>
<ClearNodes></ClearNodes>
<TTSReading>Kouzou arrive à la vieille mine de fer du village. À l'intérieur, il pourra trouver le fer dont il a besoin. Mais sur la porte de la mine,
<TTSReading>Kouzou arrive à la vieille mine de fer du village. <!--À l'intérieur, il pourra trouver le fer dont il a besoin. Mais sur la porte de la mine,
il y a un gros cadenas à 3 chiffres. Au dessus du cadenas, il est marqué : "Pour ouvrir le cadenas tu dois savoir multiplier 7 par 8".
Quel nombre doit saisir Kouzou pour déverrouiller le cadenas ?</TTSReading>
Quel nombre doit saisir Kouzou pour déverrouiller le cadenas ?--></TTSReading>
<CaptureSpeech></CaptureSpeech>
<AddNode>201</AddNode>
<AddNode>202</AddNode>
......@@ -365,9 +365,9 @@ Aide Kouzou à fabriquer le miroir afin de le sortir de ce mauvais pas. --></TTS
<TTSReading>Kouzou apporte chez le forgeron le sable et le fer qu'il a trouvé.
Le forgeron lui dit : Aides moi à faire un peu de tri parmis mes métaux.
Peux tu me dire quel est le métal le plus léger de la liste ?</TTSReading>
<CaptureSpeech></CaptureSpeech>
<AddNode>402</AddNode>
<AddNode>405</AddNode>
<CaptureSpeech></CaptureSpeech>
</action_list>
</node>
......@@ -405,9 +405,9 @@ Aide Kouzou à fabriquer le miroir afin de le sortir de ce mauvais pas. --></TTS
<TTSReading> Le forgeron semble content :
Merci, l'or est bien le métal le plus léger de la liste !
Maintenant peux-tu me dire quel est le métal le plus lourd ?</TTSReading>
<CaptureSpeech></CaptureSpeech>
<AddNode>403</AddNode>
<AddNode>405</AddNode>
<CaptureSpeech></CaptureSpeech>
</action_list>
</node>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment