Skip to content

Commit

Permalink
refactor: load fxgl-intelligence locally, keep consistent package str…
Browse files Browse the repository at this point in the history
…ucture
  • Loading branch information
AlmasB committed Mar 26, 2024
1 parent 27adeae commit 34a1325
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

package com.almasb.fxgl.intelligence;

import com.almasb.fxgl.logging.Logger;

/**
* Stores constants related to web-api projects.
* Changes to these values must be synchronized with the web-api project (https://github.com/AlmasB/web-api).
Expand All @@ -14,11 +16,31 @@
*/
public final class WebAPI {

public static final String TEXT_TO_SPEECH_API = "https://almasb.github.io/web-api/text-to-speech-v1/";
private static final Logger log = Logger.get(WebAPI.class);

public static final String TEXT_TO_SPEECH_API = getURL("tts/index.html");
public static final String SPEECH_RECOGNITION_API = "https://almasb.github.io/web-api/speech-recog-v1/";
public static final String GESTURE_RECOGNITION_API = "https://almasb.github.io/web-api/gesture-recog-v1/";

public static final int TEXT_TO_SPEECH_PORT = 55550;
public static final int SPEECH_RECOGNITION_PORT = 55555;
public static final int GESTURE_RECOGNITION_PORT = 55560;

static {
log.debug("TTS API: " + TEXT_TO_SPEECH_API + ":" + TEXT_TO_SPEECH_PORT);
}

private static String getURL(String relativeURL) {
try {
var url = WebAPI.class.getResource(relativeURL).toExternalForm();

if (url != null)
return url;

} catch (Exception e) {
log.warning("Failed to get url: " + relativeURL, e);
}

return "DUMMY_URL";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ abstract class WebAPIService(server: LocalWebSocketServer, private val apiURL: S

driverSuppliers.forEach { supplier ->
try {
log.debug("WebDriver opening: $url")

val driver = supplier()
driver.get(url)
return driver
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* See LICENSE for details.
*/

package com.almasb.fxgl.gesturerecog
package com.almasb.fxgl.intelligence.gesturerecog

import javafx.geometry.Point3D

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* See LICENSE for details.
*/

package com.almasb.fxgl.gesturerecog
package com.almasb.fxgl.intelligence.gesturerecog

/**
* The ordinal of each item matches the format defined at:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* See LICENSE for details.
*/

package com.almasb.fxgl.gesturerecog
package com.almasb.fxgl.intelligence.gesturerecog

import com.almasb.fxgl.core.EngineService
import com.almasb.fxgl.core.concurrent.Async
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

package com.almasb.fxgl.intelligence.tts

import com.almasb.fxgl.core.concurrent.Async
import com.almasb.fxgl.intelligence.WebAPI
import com.almasb.fxgl.intelligence.WebAPIService
import com.almasb.fxgl.logging.Logger
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const SEPARATOR = "*,,*";
const FUNCTION_CALL_TAG = "F_CALL:";
const FUNCTION_RETURN_TAG = "F_RETURN:";

function rpcRun(funcName, ...args) {
let argsString = "";

for (const arg of args) {
argsString += arg + SEPARATOR;
}

let message = `${FUNCTION_CALL_TAG}${funcName}${SEPARATOR}${argsString}`;

socket.send(message);
}

function rpcReturn(funcName) {
// TODO: unique id?
//socket.send(`${FUNCTION_RETURN_TAG}${funcName}.F_RESULT:${names}`);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width" />
<title>Text-to-speech</title>
</head>

<body>
<h2>Text-to-speech service</h2>

<form id="myForm">
<input id="txt" type="text" class="txt" value="" />

<div class="controls">
<button id="play" type="submit">Play</button>
</div>
</form>

<script src="../rpc-common.js"></script>
<script src="script.js"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
const synth = window.speechSynthesis;
let voices = [];
let selectedVoice = null;

const inputForm = document.querySelector("form");
const inputTxt = document.querySelector(".txt");

const socket = new WebSocket('ws://localhost:55550');

socket.addEventListener('open', function (event) {
voices = synth.getVoices();

if (voices.length == 0) {
// voices are loaded async
window.speechSynthesis.onvoiceschanged = function() {
voices = synth.getVoices();
initVoices();
};
} else {
initVoices();
}
});

socket.addEventListener('message', function (event) {
let message = event.data;

if (message.startsWith(FUNCTION_CALL_TAG)) {
let func = message.substring(FUNCTION_CALL_TAG.length);
let tokens = func.split('*,,*');
let funcName = tokens[0];

if (funcName === "speak") {
// TODO: check length?
let voiceName = tokens[1];
let voiceText = tokens[2];

for (let i = 0; i < voices.length; i++) {
if (voices[i].name === voiceName) {
selectedVoice = voices[i];
break;
}
}

speak(voiceText);
}
}
});

function initVoices() {
let names = voices.map((v) => v.name);

rpcRun("initVoices", names);
}

function speak(text) {
if (synth.speaking || text === "")
return;

const speech = new SpeechSynthesisUtterance(text);

speech.onerror = function (event) {
// TODO:
//socket.send(`Speech synthesis error: ${event.error}`);
};

if (selectedVoice !== null) {
speech.voice = selectedVoice;
}

speech.pitch = 1.0;
speech.rate = 1.0;

synth.speak(speech);
}

inputForm.onsubmit = function (event) {
event.preventDefault();

speak(inputTxt.value);

inputTxt.blur();
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import com.almasb.fxgl.app.GameApplication;
import com.almasb.fxgl.app.GameSettings;
import com.almasb.fxgl.core.math.Vec2;
import com.almasb.fxgl.gesturerecog.HandTrackingService;
import com.almasb.fxgl.intelligence.gesturerecog.HandTrackingService;
import javafx.geometry.Point2D;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
Expand Down

0 comments on commit 34a1325

Please sign in to comment.