Response terminates sound object not sound end

401 views
Skip to first unread message

Christina Vanden Bosch

unread,
Oct 17, 2016, 4:35:18 PM10/17/16
to E-Prime
I am new to E-prime, but I have programmed in Presentation and in Psyscope before and I'd love to have the same functionality in the current script I'm working on. 

I play a sound object that is 500 ms and then I play a text object that terminates if and only if the user makes a response. However, participants are sometimes responding during the sound and I am not capturing their responses. Further, if they do this, the screen waits on the text object because, while the user thinks they've made the response in the correct window, they have actually made the response during the sound object time. 

How do I collect a response during the sound object (or after it), but not allow the users response to terminate playback of the sound? Documentation tells me I should just set EndAction to "none" on the stimulus slide and then "No" for the StopAfter field. Then in the duration I have set it to infinite and then EndAction to Terminate. 

Unfortunately, this setup allows the user to terminate the sound before it's done playing. 

I have also set all of this up in a slide object, thinking that the SoundObject settings might be more separate from other properties there, but the same thing happens. 

Please, this seems like the simplest thing, but I can find no documentation on it other than what I've listed above. 

Thanks in advance for your help, 

Christina

David McFarlane

unread,
Oct 18, 2016, 10:16:19 AM10/18/16
to e-p...@googlegroups.com
Christina,

First, in order to collect a response to your sound stimulus, where the
response may come either during or after the sound stimulus, use
"extended input" -- see Appendix C in the User's Guide that came with
E-Prime. (And, as folks here have heard me say over & over again, I
also highly advise that you stop everything that you are doing right now
and first work through *all* of the Guides that came with E-Prime.)

On your sound stimulus, you should indeed set End Action to "(none)",
and No for Stop After, and set Time Limit as appropriate (see "extended
input"). Then set Duration as appropriate, e.g., 500, not "(infinite)".
Set PreRelease to 0, for a reason that will become clear later. And
set the logging to log the response.

Now here's the trick: On the TextDisplay that follows your sound, add
an input mask much like the one for your sound stimulus, but in this
case set End Action to Terminate. Do not bother to log this response,
unless you really want to.

Now here's how this works so far: E-Prime will collect a response to
the sound stimulus whether it comes during the sound or after. If it
comes during the sound then the sound stimulus will still complete its
duration (with Stop After set to No the sound output would continue to
play anyway even if the sound object stopped, but that is another
matter). If a response comes during the TextDisplay, then that input
mask will terminate the text stimulus.

So far so good, but if the response comes during the sound stimulus, the
subject would still need to respond again during the TextDisplay, so we
need to fix that. I can only think of using a bit of InLine code here.
Add an InLine after your sound stimulus that goes something like

If MySound.RTTime Then Goto SkipTextLabel

and then add a Label object named "SkipTextLabel" right after your
TextDisplay. That little bit of code checks to see if MySound got a
response, and if so it skips past the TextDisplay, otherwise it runs the
TextDisplay. Look OK? Oh, and we have to set PreRelease of the sound
stimulus to 0, otherwise this bit of code would run too soon. Got it?

This still seems a bit complicated. Anybody else have a better idea?

And Christina, please let us know how this turns out.

---------------
David McFarlane
E-Prime training online:
http://psychology.msu.edu/Workshops_Courses/eprime.aspx
Twitter: @EPrimeMaster (https://twitter.com/EPrimeMaster)

Christina Vanden Bosch der Nederlanden

unread,
Oct 18, 2016, 3:00:57 PM10/18/16
to e-p...@googlegroups.com
Thank you very much for your response!

I implemented this design and it works for the most part, but it still "waits" every once in a while even though I've made a response. I can't figure out exactly why that is happening, so the only thing I can figure is that the response is coming in when it's processing the inline code -- but that seems impossible. Perhaps my keyboard isn't as sensitive as I think it is? It seems to happen when I make a button press right around the end of my sound (500 ms) so perhaps there's some processing that's going on that prevents it from running the if then statement?

Any thoughts about why this is happening would be appreciated!

Best, 

Christina

--
You received this message because you are subscribed to a topic in the Google Groups "E-Prime" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/e-prime/eYwJvy2sqbk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to e-prime+unsubscribe@googlegroups.com.
To post to this group, send email to e-p...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/e-prime/58062EA9.4040004%40msu.edu.

For more options, visit https://groups.google.com/d/optout.



--
Christina M. Vanden Bosch der Nederlanden
chris...@gmail.com

David McFarlane

unread,
Oct 18, 2016, 4:12:56 PM10/18/16
to e-p...@googlegroups.com
Christina,

Hmm ... Indeed, this would happen if the response came just after
running the inline code and before the input mask for the TextDisplay
starts. So I have to ponder this some more ...

-- David McFarlane
>> e-prime+u...@googlegroups.com.

David McFarlane

unread,
Oct 24, 2016, 12:29:48 PM10/24/16
to e-p...@googlegroups.com
Christina,

I had a feeling that my first response was not quite right. I wrote &
posted in haste and failed to notice the flaw. Please scrap that first
answer, and try this one, which I actually tested to see that it works.
The solution I propose uses a bit of deep voodoo that would not occur
to most E-Prime users, but I will also suggest a simplification.

First, let's review the specifications for your Procedure:
- Play a sound, and get a response to that sound. The sound should
complete playback no matter what else happens.
- If response comes within 500 ms after the start of the sound, run out
the remainder of the 500 ms as if nothing happened, and skip past the
TextDisplay that follows the SoundOut.
- If response does not come within 500 ms after the start of the sound,
present a TextDisplay for some Duration.
- If response comes during the TextDisplay, terminate the TextDisplay.

Does that sound right?

Then set up your Procedure something like:
- StimSound
- PostStimText
- SoundRespLabel
- SoundWaitCode
- SoundWait

Set up each object as follows:
- StimSound: Stop After = No, Duration = 500, Time Limit as appropriate
(see "extended input"), End Action = "Jump", Jump Label =
"SoundRespLabel", logging to log the response. (Also see below for note
on timing mode.)

- PostStimText: PreRelease = 0 (so that SoundWaitCode will not run too
early). (All the other object may use PreRelease = "(same as
duration)", or whatever.)

- SoundRespLabel: (This is just a Label object, nothing to set up.)

- SoundWaitCode: This is where I use a bit of deep voodoo. Your code
may consist of a single line, thus,

SetNextTargetOnsetTime StimSound.OnsetTime

- SoundWait: (This is a Wait object) Duration = 500 (same as
StimSound), Timing Mode = Cumulative. Might as well also make sure that
Onset Sync = "(none)" (already the default setting in newer versions of EP).

- Whatever object runs after SoundWait (might be StimSound again):
Timing Mode = Event.


How this works:

If a response comes while StimSound runs, then the program jumps past
PostStimText and runs SoundWaitCode. And here is where the deep voodoo
comes into play. SoundWaitCode uses SetNextTargetOnsetTime to make
SoundWait think that it was supposed to start at the same time as
StimSound. Of course, SoundWait starts later than that, but that
doesn't matter. Because we also set SoundWait to use Cumulative timing
mode (the other bit of deep voodoo), it calculates its end time (and the
TargetOnsetTime of the next object) based on its own Duration (which we
set to the same Duration as StimSound) and the OnsetTime of StimSound.
As a result, SoundWait just takes up the remaining Duration of StimSound
as if nothing had happened, and everything moves on from there.

If a response comes during PostStimText, then the program jumps ahead to
run SoundWaitCode; if a response never comes, then the program just
moves ahead to run SoundWaitCode. In either case, once again
SoundWaitCode uses SetNextTargetOnsetTime to make SoundWait think that
it was supposed to start at the same time as StimSound. This time,
however, SoundWait actually starts later than its own projected ending
time (because SoundWait uses Cumulative timing mode)! No problem,
SoundWait sees that, does nothing, and the program simply moves on to
the next object. In this case, that next object must use Event timing
mode or else its own timing may be off (think it through).

Note the mix of Event & Cumulative timing mode. If your experiment does
not allow that, then you would have to modify this solution accordingly.
I leave that as an exercise. If you find all of this confusing, then
you might find it useful to take my online course.


How you might simplify this:

I used a mixture of SetNextTargetOnsetTime and Cumulative timing mode
because it makes the timing more precise, and I have a deep
understanding of E-Prime and how to use these features. Most ordinary
E-Prime users would not do this, and their programs would work plenty
well enough without my voodoo techniques. Instead, you could put code
in SoundWaitCode to simply recalculate the Duration of SoundWait based
on the current time and StimSound.OnsetTime, use that to set an
attribute, and then use that attribute for the Duration of SoundWait.
This is just a little less precise because it cannot quite account for
timing delays between the end of the InLine code and the onset of
SoundWait, but it would be Good Enough and probably easier to understand
and manage. I leave this as an exercise.


In any case, this does seem a bit complex. I don't know how this
compares to how you would do this in Presentation or PsyScope.

This turned out to be an interesting little puzzle, so thanks for posing
it. And again, please write back and let us know how this works for you.

---------------
David McFarlane
E-Prime training online:
http://psychology.msu.edu/Workshops_Courses/eprime.aspx
Twitter: @EPrimeMaster (https://twitter.com/EPrimeMaster)


Christina Vanden Bosch der Nederlanden

unread,
Oct 26, 2016, 3:05:11 PM10/26/16
to e-p...@googlegroups.com
Thank you, David, for posting an alternative solution. 

I completely understand the code and the deep voodoo, but, even though the timing seems to be right, my sound's playback is being terminated by the Jump code even if it waits later for a full 500ms due to the wait code and wait object. I also can't set my PostStimText to have a 0 preRelease because it is set to infinite. If you'll recall, I want people to be able to wait there for an indeterminite amount of time as I'm running this with kids and I don't want distraction to lead to a bunch of missed trials. I don't think this small change would affect how the code works altogether though, do you?

Let me know if there's something I'm missing. 

By the way, the other code works well except for about an 11ms window after 500ms (length of sound) where it must be running the code. It's very consistent, so that's interesting, but if the participant responds within that 11ms window then the program just waits -- I wonder if I could write a second piece of inline code that checks whether there was a response in the 20ms window after the 500 ms and then go forward, there may be a bit of a lag on the part of the participant, but at least it would move forward without them having to press a second response...

Thanks again for helping with this conundrum!

Christina

--
You received this message because you are subscribed to a topic in the Google Groups "E-Prime" group.
To unsubscribe from this group and all its topics, send an email to e-prime+unsubscribe@googlegroups.com.

To post to this group, send email to e-p...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Christina Vanden Bosch der Nederlanden

unread,
Oct 26, 2016, 5:16:16 PM10/26/16
to e-p...@googlegroups.com
Actually, I think it may be working after all! I was "button jamming" and it was skipping things -- but that may have just been when I am pressing buttons unreasonably fast. I've tried it again with the same parameters and it doesn't seem to be ending sound playback. 

I'll keep you posted when I run a few more pilot subjects. 

Thanks,

Christina

David McFarlane

unread,
Oct 27, 2016, 11:42:00 AM10/27/16
to e-p...@googlegroups.com
Christina,

Glad you got it to work! I was just typing up a response to your
earlier post, after tuning up a little demo program for you, because
everything worked perfectly for me. I would still like to address the
specific concerns in your earlier post ...

- Indeed, I did not consider setting the Duration of PostStimText to
"(infinite)". But that does not matter. The technique I described
works just as well then, as long as the Time Limit for the input mask in
StimSound is set to "(infinite)" or "(end of proc)".

- When you set Duration to "(infinite)", E-Prime already forces
PreRelease to 0.

- Adding a second InLine to the earlier program in my first, flawed
solution would not work. That ~11 ms window is the time between the end
of executing the Inline and the onset of the input mask for follow
TextDisplay that follows it. Adding a second InLine after the first
InLine would just push that window to the time between the end of the
second InLine and the onset of the TextDisplay. And so on, no matter
how many InLines you add. There is nothing you can do about it, that's
why I went to the second solution. Think about it, and if you don't
believe me, please give it a try and prove me wrong :)!

FWIW, I will still send you my demo program off the list.

Best,
-- David McFarlane

Christina Vanden Bosch der Nederlanden

unread,
Nov 1, 2016, 4:09:27 PM11/1/16
to e-p...@googlegroups.com
Thanks, again, David!

This was helpful to look through and I realized that I still had an issue with the cumulative vs. event timing feature. I ended up adding a 1ms wait target that had event mode timing after the 500ms (duration of sound) cumulative mode timing wait object and that made everything work well! Not exactly sure why that is, but it must have something to do with the nuances of how these two timing modes work. 

Last question -- the code that worked previously wouldn't let me set specific target responses because it was just looking for any RT, but am I correct in assuming that this new code will work with target responses? That is, the trial will only jump if the respondent presses the appropriate keys.

Really appreciate all your help, the experiment is humming along nicely!

Christina

--
You received this message because you are subscribed to a topic in the Google Groups "E-Prime" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/e-prime/eYwJvy2sqbk/unsubscribe.
To unsubscribe from this group and all its topics, send an email to e-prime+unsubscribe@googlegroups.com.
To post to this group, send email to e-p...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Christina M. Vanden Bosch der Nederlanden
chris...@gmail.com

David McFarlane

unread,
Nov 3, 2016, 12:20:01 PM11/3/16
to e-p...@googlegroups.com
Christina,

You will note that in my example I have a TextDisplay object after the
cumulative timing mode Wait object that follows the inline code, set to
Event timing mode. Putting something, anything, with Event timing mode
after the cumulative timing mode Wait does make this work, you just need
something to set the NextTargetOnsetTime to the time after the sound or
after the response, whichever comes later. So your second 1 ms Wait
just does the same thing that my TextDisplay does. You could even set
your Wait down to 0 ms (try it!)

As for getting "target responses", do you mean Allowable responses? You
should be able to set Allowable to whatever you like just like always, I
just set it to "{ANY}" for convenience in my example. But as always,
don't take my word for this, go ahead and change the Allowable entry and
see what happens for yourself!

-- David McFarlane

David McFarlane

unread,
Nov 3, 2016, 1:02:00 PM11/3/16
to e-p...@googlegroups.com
Meant to add that I had another situation myself where I used a 0 ms
Wait to reestablish timing after doing some other unusual timing
manipulations. I call it a NullWait. And of course I commented this in
an accompanying InLine object lest I mystify anyone who later looked at
my program.

-- David McFarlane
Reply all
Reply to author
Forward
0 new messages