Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Supported by

Play sound at random points during experiment

Hello,

I am trying to have a click sound play at random points during the training portion of my experiment. The training consists of words being individually presented visually on the screen. When the participant's hear a click sound, they have to press a key as fast as possible, and then we will record the time taken for them to press the key.

I have one variable in my loop table with 20 levels (the number of words presented, named "wordorder"). I have then included an inline script within that to try and get the click sound to play randomly 5 times while the words are being presented. This is what I have so far:

I know I am doing something wrong as the clicks are playing throughout all 20 words instead of at 5 random words, but I am not sure how to resolve the issue.

Thanks for your time :)

Comments

  • Hi,

    How do you present the words then? Your example is a little too incomplete to really understand what is happening (and what isn't). Generally, if you want to make sure that your sounds is presented exactly 5 times in the word loop, you should create a sound sequence before entering the word list. Then, you can index every item of that list on every trial, and play the sound whenever you want. Does this make sense?

    By the way, if you want to make your sound entirely random, that is not just on which trials it is being played but also when inside a trial, you have to use a slightly different approach. In this case, you would have to add while loop to the mix. If this is the case, I can try to give you more help on that.

    Good luck,

    Eduard

  • Hi Eduard,

    Thanks for taking the time to respond. The words will be presented one-by-one on the screen. All the participant has to do is look at the words as they are visually presented individually, and then press a key whenever they hear a click sound.

    I am interested to see what you mean by using the while loop. The actual training phase in the experiment will have over 700 trials, so I am hoping to randomly distribute the click sound maybe 50 times throughout those trials.

  • edited February 10

    Hi Eduard,

    Sorry to bother you, but I am still unable to figure this out as I am still a beginner at python. I've played around with it but I still can't get the clicks to play at 5 random points. With the while loop that you suggested, would it start off something like (I don't know how to format the code properly on this forum so please ignore the tabbing errors):

    clicks = 0 
    while wordorder = true:
    
    for clicks in wordorder:
    if clicks < 5:
    click_sound.play()
    
    clicks = clicks + 1
    
    if clicks == 5:
    break
    

    Am I headed in the right direction? The 'wordorder' variable in my loop table is in a fixed sequential order, so I'm not sure how to randomise the distribution of the clicks while not randomising the wordorder.

  • Ah, so I've sorted out how to get the random click sounds with the below code:
    import random

        #setup sampler
        sound = pool['mouseclick.wav']
        click_sound = sampler(sound, duration=0, volume=1)
    
        #40 nonwords loop
        population = list(range(40))
    
        #select 5 random positions
        click_indices = random.sample(population, k=5)
    
        click_count = 0
    
        if click_count in click_indices:
            click_sound.play()
            click_count = click_count + 1
    
        if click_count == 5:
            click_sound.stop()
    

    But now I've run into issues with recording a subject's keyboard response to the clicks. Participants need to press the 'c' key as soon as they hear the click sound. I'd like to exclude any response that are longer than 1000ms or shorter than 100ms from analyses. If I change the keyboard timeout to 1000ms, it stops the word loop from playing automatically like I'd like it to. At the moment, I have this inline script in the prepare phase:

            my_keyboard = keyboard(keylist=['c'],timeout=0)
            start_time = self.time()
            key, end_time = my_keyboard.get_key()
            subj_click_rt = end_time - start_time
            exp.set("subj_click_rt", subj_click_rt)
    

    But my logger records subj_click_rt as 0 throughout all trials. I've tried to refer to the solution here https://forum.cogsci.nl/discussion/918/solved-response-time-timing but because my clicks will play randomly for every participant, I'm not sure how to approach this correctly.

    Here is a screenshot of my current set up

    Thanks so much again.

  • Ah, so I've sorted out how to get the random click sounds with the below code:

    import random
    
    #setup sampler
    sound = pool['mouseclick.wav']
    click_sound = sampler(sound, duration=0, volume=1)
    

    40 nonwords loop

    population = list(range(40))
    

    select 5 random positions

    click_indices = random.sample(population, k=5)
    
    click_count = 0
    
    if click_count in click_indices:
    click_sound.play()
    click_count = click_count + 1
    
    if click_count == 5:
    click_sound.stop()
    

    But now I've run into issues with recording a subject's keyboard response to the clicks. Participants need to press the 'c' key as soon as they hear the click sound. I'd like to exclude any response that are longer than 1000ms or shorter than 100ms from analyses. If I change the keyboard timeout to 1000ms, it stops the word loop from playing automatically like I'd like it to. At the moment, I have this inline script in the prepare phase:

    my_keyboard = keyboard(keylist=['c'],timeout=0) 
    start_time = self.time() 
    key, end_time = my_keyboard.get_key()
     subj_click_rt = end_time - start_time
     exp.set("subj_click_rt", subj_click_rt)
    

    But my logger records subj_click_rt as 0 throughout all trials. I've tried to refer to the solution here https://forum.cogsci.nl/discussion/918/solved-response-time-timing but because my clicks will play randomly for every participant, I'm not sure how to approach this correctly.

    Here is a screenshot of my current set up

    Thanks so much again

  • Ah, so I've sorted out how to get the random click sounds with the below code:


    import random
    
    #setup sampler
    sound = pool['mouseclick.wav']
click_sound = sampler(sound, duration=0, volume=1)
    
    #40 nonwords loop
    population = list(range(40))
    
    #select 5 random positions
    click_indices = random.sample(population, k=5)
    
    click_count = 0
    if click_count in click_indices:

      click_sound.play()

      click_count = click_count + 1
    
    if click_count == 5:

      click_sound.stop()
    

    But now I've run into issues with recording a subject's keyboard response to the clicks. Participants need to press the 'c' key as soon as they hear the click sound. I'd like to exclude any response that are longer than 1000ms or shorter than 100ms from analyses. If I change the keyboard timeout to 1000ms, it stops the word loop from playing automatically like I'd like it to. At the moment, I have this inline script in the prepare phase:

    my_keyboard = keyboard(keylist=['c'],timeout=0) 
    start_time = self.time() 
    key, end_time = my_keyboard.get_key() 
    subj_click_rt = end_time - start_time 
    exp.set("subj_click_rt", subj_click_rt)
    

    
But my logger records subj_click_rt as 0 throughout all trials. I've tried to refer to the solution here https://forum.cogsci.nl/discussion/918/solved-response-time-timing but because my clicks will play at random points for every participant, I'm not sure how to approach this correctly.

    Here is a screenshot of my current set up


    Thanks so much again.

  • Hi,

    Try this:

    <br />my_keyboard = keyboard(keylist=['c'],timeout=0) 
    start_time = clock.time() 
    while True:
        key, end_time = my_keyboard.get_key() 
        if key != None:
            var.subj_click_rt = end_time - start_time 
        break
    

    That is the basic structure of the while loop that I was talking about. In theory, you can step-by-step make it more complicated by adding the sounds and images to it as well, if needed.

    Hope this helps you.

    Eduard

  • Hi Eduard,

    I have included that, but it is still not recording the RTs to the click sounds (I either get a full column of NA or a mix of NA and zeros). I get the same result when I put all of that code in the prepare phase, or only having the keyboard setup in the prepare phase. Here is the full code I have right now: https://pastebin.com/wyC4fDcE perhaps you might spot something that I am missing or have written incorrectly.

    Thanks for your time and patience.

  • Updated code:
    https://pastebin.com/PTyKaQzM

    I am able to record RTs now, but I had to set my keyboard timeout to 450ms instead of 0ms. Now, each word in the word loop (which I had originally set for a 240ms duration on the sketchpad) is slowed down. Is there any way for me to set the keyboard time out to 1000ms without affecting the 240ms duration of the words displayed in the word loop?

    (Cross posted http://forum.cogsci.nl/index.php?p=/discussion/918/solved-response-time-timing#latest)

  • I have updated my Opensesame so that I can use the co-routine plugin, but I am still having difficulty making the keyboard timeout (1000ms) independent from the word loop presentation timing (240ms).

    Here is the current setup:

    I followed the advice given here http://forum.cogsci.nl/index.php?p=/discussion/2174/simple-coroutine-question and added inline scripts to set up and break the coroutine. I changed the nonword sketchpad duration to 0ms, and made it 240ms on the coroutine itself. I tried to remove the keyboard timeout on the keyboard inline script, but then that meant that I had to keypress in order to proceed during the word loop.

    I would greatly appreciate any insight.

  • edited February 27

    I'm still having trouble with this coroutine. I tried to fix the issue by inserting a keyboard_response item into the coroutine with a timeout of 1000ms. I then imported that keyboard into my keyb_resp_script (as opposed to generating a keyboard with code), and also moved that into the 'run' phase. I set the nonword sketchpad duration to 240ms. I also removed the coroutine_setup and break_coroutine inline scripts because my python kept crashing.

    However, now I have to press the spacebar in order to move forward through the word loop, as opposed to it transitioning to the next word automatically (i.e. every word shown for only 240ms). What am I doing wrong?

    Updated code: https://pastebin.com/TeJDNDNE

  • edited March 1

    Hi,

    I answered in the other discussion. Can you check whether my code helps you? Generally, it would be better to discuss in only a single thread. So, please stick to this one here.

    For completeness sake, I post my answer here again:

    Hi,

    For some reason, your pasted code doesn't load into Opensesame. Can you also share the experiment? Anyway, I wrote a little script that should do what you are looking for. You just have to adapt it to your needs.

    import random
    
    cv = Canvas()
    blank_cv = Canvas()
    kb = Keyboard()
    
    # define and shuffle the word list
    nonwords = ['asd','fewsda', 'htergf']*3
    random.shuffle(nonwords)
    
    # define durations of each phase
    non_duration = 240
    blank_duration = 495
    
    # 10 sounds, randomly in 10 seconds
    sounds = random.sample(range(10000),10)
    # load sound 
    src = pool['bark.ogg']
    my_sampler = Sampler(src, volume=.5)
    # keeps track of which sounds have been played
    sound_idx = 0
    # list to collect all the responses
    var.resps = []
    
    # draw the first word 
    idx = 0 
    cv['word'] = Text(nonwords[idx])
    t0 = cv.show()
    
    # start_timer
    t1,t2 = clock.time(),clock.time()
    while True: 
        # get the key presses
        k,t = kb.get_key(timeout = 1)
        if k != None:
            var.resps.append([k,t])
            kb.flush()
    
        # show a blank and draw the next word
        if clock.time()-t1>240:
            t1+=1000
            t2 = blank_cv.show()
            idx += 1
            if idx == len(nonwords):
                break
            cv['word'].text = nonwords[idx]
    
        # show the next word and reset timers
        if clock.time()-t2>500:
            t1 = cv.show()
            t2 += 1000
    
        # play the sounds if it is time
        if not sound_idx == len(sounds):
            if clock.time()-t0>sounds[sound_idx]:
                my_sampler.play()
                sound_idx += 1
    

    Eduard

    Btw. Which version of Opensesame are you using? From your screenshot it appears to me that it isn't the latest one.

  • Hi Eduard,

    Thanks so much! I've adapted it for my experiment and for the most part it works. Just to clarify, t1 and t2 essentially set two different timers?

    I have run into two different issues though:

    1) When I have my if..else statement to record my subject's RT to the click sounds, i have my else statement "else: var.set('subj_click_rt', 0)" such that if no response is given, it'll be recorded in the data as 0. However, when I include that else statement, all my RTs become 0. When I don't include it, it records the RT, but the data looks messy.

    2) I am now having my nonword stimuli shown for 340ms. However, when I code the duration as 340ms, I've calculated that the stimuli is shown for 800ms+. When I code it to 112ms, the stimuli is shown for anywhere between 330-360ms. Timing is important for my experiment, so is there anyway for me to have the stimuli displayed for consistently, and exactly 340ms? I have read the OS timing documentation and am not sure if it's because of the code that is slowing things down as well? I am on OS 3.2.6, Windows7 (desktop effects disabled), 60hz monitor.

    I have attached a sample of my experiment below (the real version has 712 trials). I'm unable to attach my .wav click sound, so here is a click sound if you need one to test the experiment http://soundbible.com/1705-Click2.html


  • So I changed the backend to legacy, and the timings seem to be a little more consistent. I coded the durations in the inline script to 126ms, and my stimulus presentation ends up being around 340ms-350ms, which is better than before. But I'm still having issues with my if..else statement as mentioned in my previous post.

  • > Thanks so much! I've adapted it for my experiment and for the most part it works. Just to clarify, t1 and t2 essentially set two different timers?

    That is almost correct. t1 and t2 are two different time stamps. So, basically the current time, relative to the start of the experiment.


    > 1) else statement

    The problem is that the loop keeps on running continuously. So, even if your participant has given a response, in the next iteration the response will be overwritten if you have an else statement in there. Can you check whether your experiment works better with the changes that I added? (Basically logging the response, right away after the a key was pressed.)


    > 2) That is odd. So you have a delay of 200 ms more than you plan to have? Is this consistent? maybe something is wrong with the code?

    Eduard

Sign In or Register to comment.