Timer function help

to explain the whole program as it is now: there are 6 tracks. I have speech recognition running where user speech is detected and when he speaks the first track is played fully and stopped when the track is over. then it starts listening for speech and when it is detected the second track plays so on until track 6.

what i want to change: is have the first track play… wait for user speech response and if no response after 5 seconds play next track. but if user response is detected then go to next track immediately.

function parseResult() {
    var mostrecentword = myRec.resultString.split(' ').pop();
        if (mostrecentword.indexOf("") !== -1) {
            setInterval(myTimer, 1);
            songs[currentSong].playMode('untilDone');
            songs[currentSong].play();
            background(0, 255, 0);
        }
}


function myTimer() {
    if (millis() > startT + fiveSeconds) {
        startT = millis();
        console.log(startT);
        currentSong++;
        background(0, 0, 255);
    }

}

there is nothing in function draw() its empty.

function setup() {
    frameRate(1);
    createCanvas(600, 600);
    background(255, 255, 255);
    fill(0, 0, 0, 255);
    myRec.start();
    startT = millis();
}

and thats the setup. im using https://github.com/IDMNYU/p5.js-speech for speech recog (this part works great, no trouble at all)

1 Like

somewhere you need to (re)start your timer code.

pls take a look here
https://editor.p5js.org/kll/sketches/9mkQG9HXN

1 Like
var myRec = new p5.SpeechRec('en-US', parseResult);
myRec.continuous = true;
myRec.interimResults = false; //was getting detection errors with this turned on, not sure what the fuck this is
myRec.onEnd = restart;
var songs = [];
var songNames = ['one.wav', 'two.m4a', 'three.m4a', 'come_closer.m4a', 'four.wav', 'five.m4a'];
var songCount = songNames.length;
var currentSong = 0;
var song;
var startT;
var fiveSeconds = 5000;

function restart() { // the dirty hack
    myRec.start();
}

function preload() {
    soundFormats('wav', 'm4a');
    for (let i = 0; i < songNames.length; i++) {
        songs.push(loadSound('audioFiles/' + songNames[i]));
    }
}

function setup() {
    frameRate(1);
    createCanvas(600, 600);
    background(255, 255, 255);
    fill(0, 0, 0, 255);
    myRec.start();
    startT = millis();
}

function draw() {
    myTimer();
}

function parseResult() {
    var mostrecentword = myRec.resultString.split(' ').pop();
        if (mostrecentword.indexOf("") !== -1) {
            setInterval(myTimer, 1);
            songs[currentSong].playMode('untilDone');
            songs[currentSong].play();
            background(0, 255, 0);
        }
    console.log(mostrecentword);
    console.log(currentSong);
    console.log(songCount);
    //song = loadSound('audioFiles/' + songs[currentSong%songCount]);
}

function myTimer() {
    if (millis() > startT + fiveSeconds) {
        startT = millis();
        console.log(startT);
        currentSong++;
        background(0, 0, 255);
    }

}

function receiveOsc(address, value) {
    console.log("received OSC: " + address + ", " + value);
    if (address == '/start') {
        console.log(value);
    }
}

function sendOsc(address, value) {
    if (currentSong > 0) {
        socket.emit('message', [address].concat(value));
    }
}

function setupOsc(oscPortIn, oscPortOut) {
    var socket = io.connect('http://127.0.0.1:8081', { port: 8081, rememberTransport: false });
    socket.on('connect', function() {
        socket.emit('config', {
            server: { port: oscPortIn, host: '127.0.0.1' },
            client: { port: oscPortOut, host: '127.0.0.1' }
        });
    });
    socket.on('message', function(msg) {
        if (msg[0] == '#bundle') {
            for (var i = 2; i < msg.length; i++) {
                receiveOsc(msg[i][0], msg[i].splice(1));
            }
        } else {
            receiveOsc(msg[0], msg.splice(1));
        }
    });
}

so this is the entire thing. ignore the osc stuff in the bottom. did not understand the need to restart timer code? but i added it in anyway. but what i really need is the logic for play the first track when the program is loaded then wait 5 sec for user voice input here: if user input is received before the 5 sec is up then go to the next track and if no input after 5 sec then go to the next track anyway.

1 Like

got an answer from @lassekorsgaard

let currentSongIndex = 0
let totalSongs = 6
let canPlay = true
let timer = null

function playSong() {
    if (timer) {
        clearTimeout(timer)
        timer = null
    }

    songs[currentSongIndex].play()
    timer = setTimeout(nextSong, 5000)
}

function nextSong() {
    if (currentSongIndex < totalSongs) {
        currentSongIndex++
    }else{
        currentSongIndex = 0
    }

    playSong()
}


function speechResult() {
    var resultArray = myRec.resultString.split(' ').pop()

    if (resultArray.indexOf('') > -1 && canPlay) {
        nextSong()
    }
}
1 Like