Add button that extracts time stamps from audio | XM Community
Solved

Add button that extracts time stamps from audio

  • 27 February 2019
  • 5 replies
  • 18 views

I want to add an audio clip that participants are required to listen to. While listening to the audio clip, participants are supposed to prove that they are listening by pressing a button (or perhaps some more straightforward input paradigm) whenever they hear the word "dog." In the backend, I want to extract the total number of times the button was pressed, and the time stamps that corresponded to the button presses.

I've been having trouble designing the least confusing set-up. The button should only be active while the audio clip is playing. At the same time, if the user "accidentally" presses the button when they didn't intend to, I want to allow them to re-do the whole process. What is the best way to set this up?
icon

Best answer by parseltongue 28 February 2019, 15:02

View original

5 replies

Userlevel 5
Badge +6
Hi @parseltongue,
you could use 2 buttons. One will be pressed when hearing "dog" and the other to play your audio. If you don't want users to accidentally press buttons, just disable them when appropriate.
You could get your timestamps by subtracting the start time from the current time (`Date.now() - startTime`).
So your code could look somehow like this:

Qualtrics.SurveyEngine.addOnload(function()
{
var audio = new Audio('http://www.music.helsinki.fi/tmt/opetus/uusmedia/esim/a2002011001-e02.wav') ;
var startTime;
var timestamps = [];
var alltrials = "";


function play(){ //function which will be run when the play button is pressed
timestamps = [];
document.getElementById("b_dog").disabled = false;
document.getElementById("b_play").disabled = true;
audio.play();
startTime = Date.now(); //get start day
}

function get_time(){ //function which will be run when the dog button is pressed
timestamps.push(Date.now() - startTime); //adding timestamp into the array of all timestamps
alert(timestamps); //pop-up window to check the variable, will be removed before finalization
}

audio.onended = function() { //function which will be run when the audio finishes
alltrials += timestamps.join() + ";"; //adds current array with timestamps to a text variable with all trials; particular trials will be separated by semi-column
alert(alltrials);
Qualtrics.SurveyEngine.setEmbeddedData('t',alltrials); //Sends variable to the embedded field; otherwise your value won't be in output; don´t forget to define the field in the survey flow

document.getElementById("b_play").disabled = false;
document.getElementById("b_dog").disabled = true;
alert("If you want to try again, press PLAY");
};

jQuery( "#b_play" ).click(function () {play()})
jQuery( "#b_dog" ).click(function () {get_time()})

});

And the HTML code for buttons is here:
`<button id="b_play">Play</button><br />`
` <br />`
`<button disabled="disabled" id="b_dog">Dog</button>`

Note: by default it isn't visible whether the button is disabled or not. Therefore you should define some CSS styles for your buttons in Look & feel settings. Here is a nice example of code you can use.
This is incredibly helpful. Thanks so much for taking the time -- really appreciate it!
@fleb,

A quick follow-up. How would I code up a button that enables the user to "reset" the entire process (if, for example, they click the "dog" button too many times, and would like to retry?)
Userlevel 5
Badge +6
Hi @parseltongue,
I realized, there is one more problem while working on the reset button. I don't know whether it does matter or not, but your data won't be stored if the user clicks the Next (or the Previous button) before the audio finishes. I have solved both tasks here.
1) Create function end which will be run every time audio finishes from any reason.

function end(){
alltrials += timestamps.join() + ";";
alert(alltrials);
Qualtrics.SurveyEngine.setEmbeddedData('t',alltrials);
}

2) Design the reset button in the same way as previous two (i.e.: `<button disabled="disabled" id="b_reset">Reset</button>`)

3) Create a new function which will be run when the user clicks the rest button and assign this function to the reset button using `jQuery`.

function reset(){
audio.pause();
audio.currentTime = 0;
end();
play();
}

4) Run the `end` function also when the audio finishes itself instead of having the same commands twice in the script to have a more elegant code.

audio.onended = function() {
alert("If you want to try again, press PLAY");
end();

document.getElementById("b_play").disabled = false;
document.getElementById("b_dog").disabled = true;
};

5) Run the `end` function also the Next (or Previous if applicable) button is clicked: `document.getElementById('NextButton').onclick = function() {end()}`

6) Add commands to disable or enable the new button on appropriate places.

7) Test the code carefully, since I didn't.
You're amazing. Will test this and let you know if it works. Thanks!

Leave a Reply