Repeat sample trial with audio recording

PennController for IBEX Forums Support Repeat sample trial with audio recording

This topic contains 3 replies, has 2 voices, and was last updated by Jeremy Jeremy 1 week, 4 days ago.

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #6706
    Avatar
    adamliter
    Participant

    I’m trying to create an experiment with a sample trial that has an audio recording component that the participant can repeat, if they so choose. I’m trying to do what was suggested in this thread: https://www.pcibex.net/forums/topic/multiple-trial-repetition/

    However, I’m running in to two issues when redoing the sample trial. One issue is that there is actually a brief flash of the trial (description3) that comes after the sample trial when clicking the “Redo sample trial” button. The second issue is that after clicking “Redo”, the trial starts over, but it stalls at the end of the DashedSentence controller. It won’t show the math problem for a second time, for whatever reason. Any idea what I might be doing wrong? Here’s a trimmed down version of the main.js file.

    const ParticipantID = b64_md5((Date.now() + Math.random()).toString());
    
    const PracticeTrial = () => [
        newText("practice-fixation-text", "%%%%")
            .settings.center()
            .print()
        ,
        newTimer("practice-fixation", 300)
            .start()
            .wait()
        ,
        clear()
        ,
        newTimer("practice-clear", 350)
            .start()
            .wait()
        ,
        newController("DashedSentence", {s: "This is a sample sentence to memorize and repeat.", display: "in place", mode: "speeded acceptability", wordTime: 200, wordPauseTime: 100})
            .settings.center()
            .print()
            .wait()
            .log()
            .remove()
        ,
        newText("practice-math-problem", "12 - 7")
            .settings.center()
            .print()
        ,
        newTextInput("practice-math-answer", "")
            .settings.center()
            .settings.log()
            .settings.length(4)
            .print()
        ,
        newButton("send-practice-math-prob-answer", "Submit answer")
            .settings.center()
            .print()
            .wait()
            .remove()
        ,
        clear()
        ,
        newMediaRecorder("practice-recorder", "audio")
            .log()
            .record()
        ,
        newButton("Stop and play recording")
            .settings.center()
            .callback(getMediaRecorder("practice-recorder").stop().play())
            .print()
            .wait()
            .remove()
        ,
        newText("practice-recording-preview", "Recording is now playing ... <br/><br/> If your recording sounds good, click the 'Proceed' button. If you'd like to redo the sample trial, click the 'Redo' button.<br/><br/>")
            .settings.center()
            .print()
    ]
    
    PennController.ResetPrefix(null);
    
    //DebugOff();
    
    Sequence("setcounter", "description1", "audio-permission", "description2", "practice-trial", "description3", "send");
    
    newTrial("description1",
        newHtml("description", "description1.html")
            .print()
        ,
        newButton("start", "Click to set up audio")
            .settings.center()
            .print()
            .wait()
    )
    .log("ParticipantID", ParticipantID);
    
    InitiateRecorder("https://MY_DOMAIN/recording.php",
        "<p style='margin:2rem;'>This experiment collects recording samples from its participants. Your browser should now be prompting a permission request to use your recording device. By giving your authorization to record, you are giving permission to the designers of this experiment to anonymously collect the samples recorded during this experiment. The recordings will be uploaded to, and hosted on, a server designated by the experimenters. If you accept the request, a label will remain visible at the top of this window throughout the whole experiment, indicating whether you are currently being recorded.</p>"
        ).label("audio-permission")
    
    newTrial("description2",
        newHtml("description", "description2.html")
            .print()
        ,
        newButton("start", "Click to start practice trial")
            .settings.center()
            .print()
            .wait()
    )
    .log("ParticipantID", ParticipantID);
    
    newTrial("practice-trial",
            newButton("launch-practice-trial").callback(
                ...PracticeTrial()
                ,
                getButton("proceed").print()
                ,
                getButton("redo").print()
                )
                .click()
            ,
            newButton("proceed", "Proceed")
                .settings.center()
                .callback(end())
            ,
            newButton("redo", "Redo sample trial")
                .settings.center()
                .callback(getButton("launch-practice-trial").click())
                .wait()
    )
    .log("ParticipantID", ParticipantID);
    
    newTrial("description3",
        newHtml("description", "description3.html")
            .print()
        ,
        newButton("start", "Click to begin experiment")
            .settings.center()
            .print()
            .wait()
    )
    .log("ParticipantID", ParticipantID);
    
    SendResults("send");
    
    SetCounter("setcounter");
    
    #6708
    Jeremy
    Jeremy
    Keymaster

    Hi,

    This is a problem that has to do with how I coded the Controller element. Add this to your script, and replace .print().wait().remove() with simply .run() on your Controller element:

    PennController._AddStandardCommands( function(PennEngine) {
        this.actions = {
            run: async function(resolve){
                if (this.type != "Controller" || this.controller != "DashedSentence")
                    return resolve();
                this.done = false;
                await new Promise(r=>PennEngine.elements.standardCommands.actions.print.call(this,r));
                const oldCallback = this.finishedCallback;
                await new Promise(r=>this.finishedCallback=function(){
                    oldCallback.call(this);
                    this.jQueryContainer.detach();
                    r();
                });
                resolve();
            }
        }
    })

    You also want to change your trial’s code slightly:

    newTrial("practice-trial",
        newButton("launch-practice-trial", "Redo")
            .callback(
                ...PracticeTrial()
                ,
                getButton("proceed").print()
                ,
                getButton("launch-practice-trial").print()
            )
            .center()
            .click()
        ,
        newButton("proceed", "Proceed")
            .center()
            .wait()
    )

    Here’s a demo link: https://farm.pcibex.net/r/AjyfGD/

    Let me know if you have any questions

    Jeremy

    #6892
    Avatar
    adamliter
    Participant

    Thanks, Jeremy! I’m just getting back to this after working on some other stuff. I can no longer see the demo experiment you posted because it uses DashedSentence, but I’ve tried to implement your suggestions and it seems like it is mostly working with the new PennController.js. The only issue is that there is no “Redo” button. The only thing I see at the end of the practice trial is the “Proceed” button. How can I add a “Redo” button so that they could redo the practice trial if they want to. Thanks in advance!

    #6893
    Jeremy
    Jeremy
    Keymaster

    Hi Adam,

    I fixed the problem with the Controller element in PennController 2.0.alpha, so you no longer need the run workaround. I have updated the project from my previous message, if you want to take a look

    This line getButton("launch-practice-trial").print() is the one that prints the “Redo” button

    Jeremy

Viewing 4 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic.