A library that provides simple, clear access to the Web Speech and Speech Recognition APIs, allowing for the easy creation of sketches that can talk and listen.
See Synthesis Example and
Recognition Example
SocketIO allows you to connect to a socket connection to make multiple sketches speak in realtime. To use OpenProcessing Echo Socket Server, you can use the code below: var socket = io.connect($OP.getEchoServerURL(513052));Learn moreSee an example
“myCollab3” by Joshua Kery
https://openprocessing.org/sketch/513052
License CreativeCommons Attribution ShareAlike
https://creativecommons.org/licenses/by-sa/3.0
{{filePath}}
{{width}} x {{height}}
Report Sketch
Oh, that naughty sketch! Please let us know what the issue is below.
Apply Template
Applying this template will reset your sketch and remove all your changes. Are you sure you would like to continue?
Report Sketch
Report Comment
Please confirm that you would like to report the comment below.
We will review your submission and take any actions necessary per our Community Guidelines. In addition to reporting this comment, you can also block the user to prevent any future interactions.
Please report comments only when necessary. Unnecessary or abusive use of this tool may result in your own account being suspended.
Are you sure you want to delete your sketch?
Any files uploaded will be deleted as well.
Delete Comment?
This will also delete all the replies to this comment.
Delete this tab? Any code in it will be deleted as well.
Select a collection to submit your sketch
We Need Your Support
Since 2008, OpenProcessing has provided tools for creative coders to learn, create, and share over a million open source projects in a friendly environment.
Niche websites like ours need your continued support for future development and maintenance, while keeping it an ad-free platform that respects your data and privacy!
Please consider subscribing below to show your support with a "Plus" badge on your profile and get access to many other features!
CC Attribution ShareAlike
myCollab3
Kery
xxxxxxxxxx
// The speech recognizer
var mySpeechRecognizer;
var mostRecentSpokenWord;
var mostRecentConfidence;
// The RiTa Lexicon
var myRitaLexicon;
//Socket
var socket = io.connect(":30000?sketch=-1000");
var userNumber = 0;
var playerWord = "nothing";
var botWord = "nothing";
var speakers;
var numSpeakers = 4;
var numPlayers = 2;
var humanRevealed = false;
var answerCorrect = false;
var showResultText = false;
var opponentAnswered = false;
var IAnswered = false;
var opponentReadyToReset = false;
var myTurn = false;
var timer = 0;
var timeUntilQuiz = 3000; //calls of draw function
var quizTime = false;
var fontSize = 12;
var charWidth = 30;
var charHeight = 30;
var charWordMargin = 20;
var eyeSpacing = 15;
var eyeRadius = 5;
var mouthSpacing = 5;
var mouthHeight = 5;
var earRadius = 8;
var botMouthSquare = 3;
var bubbleWidth = 100;
var bubbleHeight = 30;
var bubbleTailWidth = 10;
var bubbleTailHeight = 10;
var newGameWidth = 180;
var newGameHeight = 40;
//===============================================
function Speaker(number, type) {
var speaker = {
number: number,
type: type,
voice: null,
word: "",
}
return speaker;
}
//===============================================
function setup() {
createCanvas(windowWidth, windowHeight);
//speech stuff:
mostRecentConfidence = 0;
mostRecentSpokenWord = "";
initializeMySpeechRecognizer();
myTurn = true;
// Create the RiTa lexicon
myRitaLexicon = new RiLexicon();
socket.on('connection', setNewPlayer);
socket.emit('connection');
socket.on("sendToOtherPlayer",receiveOpponentInput);
socket.on("updatePlayerNum",updatePlayerNum);
socket.on("revealHuman",revealHuman);
socket.on("switchQuizTime",switchQuizTime);
socket.on('submitAnswer',receiveAnswer);
socket.on('resetGame',resetGame);
socket.on('readyToReset',setReadyToReset);
socket.on('endTimer',endTimer);
socket.on('updateSpeakers',updateSpeakers);
if (speakers == null) {
//Initialize speakers array:
speakers = [];
for (var i=0; i<numSpeakers; i++) {
speakers[i] = null;
}
//Initialize Player One:
index = getIndex();
speakers[index] = Speaker(userNumber, 'human');
//Initialize bots:
var botNumber = -1;
for (var i=0; i<speakers.length-numPlayers; i++) {
var botIndex = getIndex();
speakers[botIndex] = Speaker(botNumber, 'robot');
botNumber -= 1;
}
}
textFont('Helvetica');
textSize(fontSize);
}
//-----------Socket Stuff-------------------
function setNewPlayer() {
var newPlayerNum = userNumber + 1;
socket.emit('updatePlayerNum',newPlayerNum);
var newPlayerIndex = getIndex();
speakers[newPlayerIndex] = Speaker(newPlayerNum, 'human');
shuffleSpeakers();
socket.emit('updateSpeakers',speakers);
myTurn = false;
}
function updatePlayerNum(playerNum) {
userNumber = playerNum;
}
function revealHuman() {
humanRevealed = !humanRevealed;
}
function switchQuizTime() {
quizTime = !quizTime;
}
function receiveAnswer() {
opponentAnswered = true;
}
function resetGame() {
console.log('resetting game');
if (userNumber == numPlayers-1) {
myTurn = true;
initializeMySpeechRecognizer();
shuffleSpeakers();
socket.emit('updateSpeakers',speakers);
}
humanRevealed = false;
answerCorrect = false;
showResultText = false;
opponentAnswered = false;
IAnswered = false;
opponentReadyToReset = false;
timer = 0;
quizTime = false;
}
function setReadyToReset() {
opponentReadyToReset = true;
}
function endTimer() {
timer = timeUntilQuiz;
}
function updateSpeakers(speakerList) {
speakers = speakerList;
}
function getIndex() {
available = [];
for (var i=0; i<speakers.length; i++) {
if (speakers[i] == null) {
available.push(i);
}
}
var j = floor(random(0,available.length));
return available[j];
}
function shuffleSpeakers() {
var aux = []
for (var i=0; i<speakers.length; i++) {
aux[i] = speakers[i];
speakers[i] = null;
}
for (var i=0; i<aux.length; i++) {
var j = getIndex();
speakers[j] = aux[i];
}
}
function parseAnswer(speaker) {
if (speaker.type == 'human') {
answerCorrect = true;
}
}
//-----------Speech Stuff-------------------
function initializeMySpeechRecognizer(){
mySpeechRecognizer = new p5.SpeechRec('en-US');
mySpeechRecognizer.continuous = true; // do continuous recognition
mySpeechRecognizer.interimResults = false; // allow partial recognition
mySpeechRecognizer.onResult = parseResult; // recognition callback
mySpeechRecognizer.start(); // start engine
console.log(mySpeechRecognizer);
console.log("initalized");
}
function parseResult() {
if (!myTurn) {
console.log('will not parse.');
return;
}
console.log('parsing...');
mostRecentConfidence = mySpeechRecognizer.resultConfidence;
if (mostRecentConfidence > 0.0){ // some confidence threshold...
console.log (mySpeechRecognizer.resultString);
// The Recognition system will often append words into phrases.
// So the hack here is to only use the last word:
mostRecentSpokenWord = mySpeechRecognizer.resultString.split(' ').pop();
socket.emit("sendToOtherPlayer",mostRecentSpokenWord,userNumber);
myTurn = false;
}
}
function receiveOpponentInput(input,number) {
//First: Show Opponent's Word and Generate Bot Words.
for (var i=0; i<speakers.length; i++) {
var speaker = speakers[i];
if (speaker != null) {
if (speaker.number == number) {
speaker.word = input;
}
if (speaker.type == 'robot') {
speaker.word = getBotWord();
}
}
}
socket.emit('updateSpeakers',speakers);
//Second: If timer up, show question and wait for answer.
if (timer>=timeUntilQuiz) { //This is an event.
timer = 0;
quizTime = true;
socket.emit('switchQuizTime');
} else {
//Else, pass turn along.
initializeMySpeechRecognizer();
myTurn = true;
}
}
function getBotWord() {
var word = myRitaLexicon.randomWord();
if (random(0,1)>0.85) {
word = word.charAt(0).toUpperCase() + word.slice(1);
//Thank you Paulund for giving me this with a quick Google search.
//https://paulund.co.uk/capitalize-first-letter-string-javascript
}
return word;
}
//===============================================
function mousePressed() {
if (quizTime) {
console.log('clicking anywhere');
if ((opponentAnswered) && (showResultText)) {
var bX = width/2;
var bY = (height/2)-(2*charHeight)-charWordMargin;
var bW = newGameWidth;
var bH = newGameHeight;
if ((mouseX >= bX-(bW/2)) && (mouseX <= bX+(bW/2)) &&
(mouseY >= bY-(bH/2)) && (mouseY <= bY+(bH/2))) {
console.log("button clicked");
if (opponentReadyToReset) {
resetGame();
socket.emit('resetGame');
} else {
console.log('waiting for opponent');
IAnswered = true;
socket.emit('readyToReset');
}
}
}
for (var i=0; i<speakers.length; i++) {
var speaker = speakers[i];
if (speaker.number == userNumber) {
//Don't respond to clicking on yourself.
continue;
}
var cx = ((width/(numSpeakers+2))*(i+1));
var cy = height/2;
if ((mouseX >= cx-(charWidth/2)) && (mouseX <= cx+(charWidth/2)) &&
(mouseY >= cy-(charHeight/2)) && (mouseY <= cy+(charHeight/2))) {
console.log("clicked");
parseAnswer(speaker);
showResultText = true;
revealHuman();
socket.emit('submitAnswer');
}
}
}
}
function keyPressed() {
var question;
if (keyCode==UP_ARROW) {
switchQuizTime();
socket.emit('switchQuizTime');
if (quizTime==false) {
initializeMySpeechRecognizer();
myTurn = true;
}
} else if (keyCode==RIGHT_ARROW) {
question = "hi";
socket.emit("sendToOtherPlayer",question);
} else if (keyCode==LEFT_ARROW) {
revealHuman();
socket.emit('revealHuman')
} else if (keyCode==DOWN_ARROW) {
console.log('down pressed');
console.log(speakers);
}
}
//===============================================
function draw() {
if ((userNumber == numPlayers-1) && (!quizTime)) {
timer += 1;
if (timer >= timeUntilQuiz) {
timer = timeUntilQuiz;
socket.emit('endTimer');
}
}
background(255);
//text(userNumber,30,30);
var myTurnFill;
textAlign(LEFT);
textSize(fontSize);
fill(0);
noStroke();
if (myTurn) {
myTurnFill = color(0,255,0);
text("It's your turn! Say something!",60,40);
} else {
myTurnFill = color(255,0,0);
text("Waiting for your opponent's word.",60,40);
}
fill(myTurnFill);
ellipse(50,35,5,5);
//text("Timer: " + timer, 30,60);
//text("Quiz Time? " + quizTime, 30,90);
drawInstructions();
if (quizTime) {
if (showResultText) {
drawResultText();
if (opponentAnswered) {
if (IAnswered) {
drawWaitingText();
} else {
drawNewGameButton();
}
}
} else {
drawQuiz();
}
}
for (var i=0; i<speakers.length; i++) {
var speaker = speakers[i];
drawSpeaker(speaker, i);
}
}
function drawSpeaker(speaker, i) {
if (speaker == null) {
noStroke();
fill(0);
ellipse(((width/(numSpeakers+2))*(i+1)),height/2,10,10);
} else if (speaker.type == 'human') {
drawHuman(speaker, i);
} else if (speaker.type == 'robot') {
drawBot(speaker, i);
}
}
function drawHuman(speaker, i) {
noStroke();
if (speaker.number == userNumber) { //Draw yourself.
drawYourself(i);
} else { //Draw your opponent.
if (humanRevealed) {
drawWord(speaker.word, i); //Uncomment and replace with winning text.
if (answerCorrect) {
drawHappyOpponent(i);
} else { //answer incorrect
drawSadOpponent(i);
}
} else { //Opponent still disguised:
drawBot(speaker, i);
}
}
}
function drawBot(speaker, i) {
drawWord(speaker.word, i);
var cx = (width/(numSpeakers+2))*(i+1);
var cy = height/2;
fill(73, 85, 102);
noStroke();
rectMode(CENTER);
rect(cx,cy,charWidth,charHeight);
fill(40, 255, 212);
rect(cx-(eyeSpacing/2),cy,eyeRadius,eyeRadius);
rect(cx+(eyeSpacing/2),cy,eyeRadius,eyeRadius);
//fill(255, 193, 38);
rect(cx-(eyeSpacing/2),cy+mouthSpacing+mouthHeight,
botMouthSquare,botMouthSquare);
rect(cx-(eyeSpacing/4),cy+mouthSpacing+mouthHeight,
botMouthSquare,botMouthSquare);
rect(cx,cy+mouthSpacing+mouthHeight,
botMouthSquare,botMouthSquare);
rect(cx+(eyeSpacing/4),cy+mouthSpacing+mouthHeight,
botMouthSquare,botMouthSquare);
rect(cx+(eyeSpacing/2),cy+mouthSpacing+mouthHeight,
botMouthSquare,botMouthSquare);
}
function drawWord(word, i) {
if ((!myTurn) || (word=="")) {
return
}
var cx = (width/(numSpeakers+2))*(i+1);
var cy = (height/2)-(charHeight)-charWordMargin;
var w = bubbleWidth;
var h = bubbleHeight;
var tw = bubbleTailWidth;
var th = bubbleTailHeight;
fill(255);
stroke(0);
beginShape();
vertex(cx-(w/2),cy-(h/2));
vertex(cx+(w/2),cy-(h/2));
vertex(cx+(w/2),cy+(h/2));
vertex(cx+(tw/2),cy+(h/2));
vertex(cx,cy+(h/2)+th);
vertex(cx-(tw/2),cy+(h/2));
vertex(cx-(w/2),cy+(h/2));
vertex(cx-(w/2),cy-(h/2));
endShape();
fill(0);
noStroke();
textAlign(CENTER);
text(word,cx,cy+(fontSize/4));
}
function drawYourself(i) {
var cx = (width/(numSpeakers+2))*(i+1);
var cy = height/2;
fill(255,238,0);
ellipse(cx,cy,charWidth,charHeight);
ellipse(cx-(charWidth/2),cy+(mouthSpacing/3),earRadius);
ellipse(cx+(charWidth/2),cy+(mouthSpacing/3),earRadius);
fill(75);
ellipse(cx-(eyeSpacing/2),cy,eyeRadius);
ellipse(cx+(eyeSpacing/2),cy,eyeRadius);
noFill();
stroke(75);
strokeWeight(2);
bezier(cx-(eyeSpacing/2),cy+mouthSpacing,
cx-(eyeSpacing/4),cy+mouthSpacing+mouthHeight,
cx+(eyeSpacing/4),cy+mouthSpacing+mouthHeight,
cx+(eyeSpacing/2),cy+mouthSpacing);
strokeWeight(1);
}
function drawHappyOpponent(i) {
var cx = (width/(numSpeakers+2))*(i+1);
var cy = height/2;
fill(255,199,0);
ellipse(cx,cy,charWidth,charHeight);
ellipse(cx-(charWidth/2),cy+(mouthSpacing/3),earRadius);
ellipse(cx+(charWidth/2),cy+(mouthSpacing/3),earRadius);
fill(50);
ellipse(cx-(eyeSpacing/2),cy,eyeRadius);
ellipse(cx+(eyeSpacing/2),cy,eyeRadius);
noFill();
stroke(50);
strokeWeight(2);
bezier(cx-(eyeSpacing/2),cy+mouthSpacing,
cx-(eyeSpacing/4),cy+mouthSpacing+mouthHeight,
cx+(eyeSpacing/4),cy+mouthSpacing+mouthHeight,
cx+(eyeSpacing/2),cy+mouthSpacing);
strokeWeight(1);
}
function drawSadOpponent(i) {
var cx = (width/(numSpeakers+2))*(i+1);
var cy = height/2;
fill(255,199,0);
ellipse(cx,cy,charWidth,charHeight);
ellipse(cx-(charWidth/2),cy+(mouthSpacing/3),earRadius);
ellipse(cx+(charWidth/2),cy+(mouthSpacing/3),earRadius);
fill(50);
ellipse(cx-(eyeSpacing/2),cy,eyeRadius);
ellipse(cx+(eyeSpacing/2),cy,eyeRadius);
noFill();
stroke(50);
strokeWeight(2);
bezier(cx-(eyeSpacing/4),cy+mouthSpacing+mouthHeight,
cx-(eyeSpacing/2),cy+mouthSpacing,
cx+(eyeSpacing/2),cy+mouthSpacing,
cx+(eyeSpacing/4),cy+mouthSpacing+mouthHeight);
strokeWeight(1);
}
function drawQuiz() {
var quiz = "Which bot is the other human?";
fill(0);
noStroke();
textAlign(CENTER);
textSize(fontSize*2);
text(quiz,width/2,(height/2)-150);
}
function drawResultText() {
var result;
if (answerCorrect) {
result = "You got it right!";
} else {
result = "Nope! That's a bot!";
}
fill(0);
textAlign(CENTER);
textSize(fontSize*2)
text(result,width/2,(height/2)-150);
}
function drawNewGameButton() {
var buttonText = "Start New Round?";
fill(255);
stroke(0);
rectMode(CENTER);
rect(width/2,(height/2)-(2*charHeight)-charWordMargin,
newGameWidth,newGameHeight);
fill(0);
noStroke();
textAlign(CENTER);
textSize(fontSize*(3/2))
text(buttonText,width/2,
(height/2)-(2*charHeight)-charWordMargin+(fontSize*(3/8)));
}
function drawWaitingText() {
var waitingText = "Waiting for Opponent...";
fill(0);
noStroke();
textAlign(CENTER);
textSize(fontSize);
text(waitingText,width/2,(height/2)-100);
}
function drawInstructions() {
var line1 = "In this game, you pass words between your";
var line2 = "computer and your opponent's. Your";
var line3 = "opponent is disguised as one of the bots,";
var line4 = "who are also passing you words. After 30";
var line5 = "seconds, guess which bot is really your";
var line6 = "opponent!";
var lines = [line1,line2,line3,line4,line5,line6];
var yStart = 70;
var x = 50;
textSize(fontSize);
textAlign(LEFT);
fill(150);
noStroke();
for (var i=0; i<lines.length; i++) {
text(lines[i],x,yStart+(20*i));
}
}
See Synthesis Example and Recognition Example
Example
var socket = io.connect($OP.getEchoServerURL(513052));
Learn more See an exampleSee More Shortcuts