Millisecond Forums

Randomized stimuli in two "strands"

https://forums.millisecond.com/Topic15203.aspx

By Jurre - 12/15/2014

Hi everyone,

For my pitch discrimination experiment, I want to present my subjects with 2 "strands" of stimuli: one with two musical pitches where the second one is higher, and one where the second one is lower.
These musical pitches will get closer together if they respond correctly 3 times in a row, and if they make one mistake it needs to go back a step. The upwards and downwards stimuli need to be randomized.
Now, the problem is how to code these two strands so they move seperately, but still intermingle them randomly.

I have tried several things using the / branch attribute in the trials or in the blocks. Nothing has worked yet.

Here's an example of my trial/block setup now:
- trial.srrt , srtt3 and srtt5 are upwards pitches, trial.srtt2, srtt4 and srtt6 are downwards pitches

<trial SRTT>
/ pretrialpause = 1000
/ ontrialbegin = [if (values.speakerfixed == 1)
{values.targetspeaker = list.targetchannel.nextvalue}]
/ ontrialbegin = [if (values.volumefixed == 1)
{values.volumeadjust = list.targetvolumeadjust.nextvalue}]
/ branch = [if(trial.srtt.percentcorrect == 100 && trial.srtt.count >= 3) trial.srtt3]
/ stimulustimes = [0=target; 1500=target3]
/ inputdevice=keyboard
/ validresponse=(200, 208)
/ correctresponse = (200)
/ ontrialend = [trial.SRTT.resetstimulusframes()]
</trial>

<trial SRTT2>
/ pretrialpause = 1000
/ ontrialbegin = [if (values.speakerfixed == 1)
{values.targetspeaker = list.targetchannel.nextvalue}]
/ ontrialbegin = [if (values.volumefixed == 1)
{values.volumeadjust = list.targetvolumeadjust.nextvalue}]
/ branch = [if(trial.srtt2.percentcorrect == 100 && trial.srtt2.count >= 3) trial.srtt4]
/ stimulustimes = [0=target; 1500=target4]
/ inputdevice=keyboard
/ validresponse=(200, 208)
/ correctresponse = (208)
/ ontrialend = [trial.SRTT2.resetstimulusframes()]
</trial>

<trial SRTT3>
/ pretrialpause = 1000
/ ontrialbegin = [if (values.speakerfixed == 1)
{values.targetspeaker = list.targetchannel.nextvalue}]
/ ontrialbegin = [if (values.volumefixed == 1)
{values.volumeadjust = list.targetvolumeadjust.nextvalue}]
/ branch = [if(trial.srtt3.percentcorrect == 100 && trial.srtt3.count >= 3) trial.srtt5]
/ branch = [if(trial.srtt3.percentcorrect < 100) trial.srtt]
/ stimulustimes = [0=target; 1500=target5]
/ inputdevice=keyboard
/ validresponse=(200, 208)
/ correctresponse = (200)
/ ontrialend = [trial.SRTT3.resetstimulusframes()]
</trial>

<trial SRTT4>
/ pretrialpause = 1000
/ ontrialbegin = [if (values.speakerfixed == 1)
{values.targetspeaker = list.targetchannel.nextvalue}]
/ ontrialbegin = [if (values.volumefixed == 1)
{values.volumeadjust = list.targetvolumeadjust.nextvalue}]
/ branch = [if(trial.srtt4.percentcorrect == 100 && trial.srtt4.count >= 3) trial.srtt6]
/ branch = [if(trial.srtt4.percentcorrect < 100) trial.srtt2]
/ stimulustimes = [0=target; 1500=target6]
/ inputdevice=keyboard
/ validresponse=(200, 208)
/ correctresponse = (208)
/ ontrialend = [trial.SRTT4.resetstimulusframes()]
</trial>

<trial SRTT5>
/ pretrialpause = 1000
/ ontrialbegin = [if (values.speakerfixed == 1)
{values.targetspeaker = list.targetchannel.nextvalue}]
/ ontrialbegin = [if (values.volumefixed == 1)
{values.volumeadjust = list.targetvolumeadjust.nextvalue}]
/ branch = [if(trial.srtt5.percentcorrect == 100 && trial.srtt5.count >= 3) trial.srtt]
/ branch = [if(trial.srtt5.percentcorrect < 100) trial.srtt3]
/ stimulustimes = [0=target; 1500=target7]
/ inputdevice=keyboard
/ validresponse=(200, 208)
/ correctresponse = (200)
/ ontrialend = [trial.SRTT5.resetstimulusframes()]
</trial>

<trial SRTT6>
/ pretrialpause = 1000
/ ontrialbegin = [if (values.speakerfixed == 1)
{values.targetspeaker = list.targetchannel.nextvalue}]
/ ontrialbegin = [if (values.volumefixed == 1)
{values.volumeadjust = list.targetvolumeadjust.nextvalue}]
/ branch = [if(trial.srtt6.percentcorrect == 100 && trial.srtt6.count >= 3) trial.srtt2]
/ branch = [if(trial.srtt6.percentcorrect < 100) trial.srtt4]
/ stimulustimes = [0=target; 1500=target8]
/ inputdevice=keyboard
/ validresponse=(200, 208)
/ correctresponse = (208)
/ ontrialend = [trial.SRTT6.resetstimulusframes()]
</trial>

<block SRTTblock>
/ onblockbegin = [text.focus.textcolor = values.screencolor; text.focus.textbgcolor = values.screencolor]
/ onblockbegin = [block.SRTTblock.screencolor = values.screencolor]
/ trials = [1-6=noreplace(SRTT, SRTT2)]
/ bgstim = (focus)
</block>


This setup runs the first two trials 3 times each randomly, but then only runs the next ones (2 and 4) once. It does not carry on running trial 2 and 4 three times and then moving on to 3 and 6, because the branch attribute only reads it as the 'next event'. How do I code it so that it will carry on stepwise when the subjects make three correct responses, and goes one step back when they make a mistake, but keep this seperately for upwards and downwards pitches? So, if someone makes a mistake in the upwards pitch but not in the downwards pitch, the downwards pitch will move on and the upwards pitch will go back.
I hope this all makes some kind of sense. Ask away if something isn't clear, and please help!
By Dave - 12/15/2014

Make just two <trial> elements -- one for each of your two "strands". I.e <trial up> and <trial down>.

In your target stimulus (e.g. <sound>) elements, use <values> for selection.

<trial up>
/ stimulustimes = [0=basepitch; 1500=upwardspitch]
...
</trial>

with
<sound upwardspitch>
/ items = ("up1.wav", "up2.wav", "up3.wav", ...)
/ select = values.uplevel
...
</sound>

<values>
/ uplevel = 1
...
</values>

Increase / decrease values.uplevel according to your needs via conditional logic in /ontrialend. Do the same for the downwards pitch strand of trials.
By Jurre - 12/15/2014

Thanks! Very helpful!

I think I'll manage to code it now. Thanks so much!

Sometimes you just need a fresh look, and you provided! It can be so simple sometimes, haha.