Playing a continuous sound

Hello!

I was wondering if someone here could give me advice.

I want to play sounds with PsychPortAudio. The goal is to have simple tones of different frequencies that play continuously when the mouse hovers over specific areas on the screen. This is very simple when using sound(). For example:

if xMouse == 200 && yMouse == 200;
        sound(tone1, fs);
    elseif xMouse == 400 && yMouse == 400;
        sound(tone2, fs);
end 

If I play the sounds with PsychPortAudio they sound like “beep, beep, beep” instead of one long “beeeeeeeeeep”, which is what I want. Can anybody tell me how to keep playing a tone so that it sounds like it will never end (until you move the mouse away from the indicated position)?

Thank you so much!
Stefanie

I found something that seems to explain my question already, haven’t tried it yet, but looking very promising. Sorry for the spam!

There’s a much simpler solution: In the PsychPortAudio(‘Start’, …, repetitions) command, set repetitions to 0 for infinite looped playback. Sound will play and repeat without a gap until you call PsychPortAudio(‘Stop’, …); If you make sure that the sound vector you specify with ‘FillBuffer’ fits a nice sine-wave or other repetitive sound, then you’ll get the continuous tone. E.g., MakeBeep() does that for sine wave tones.

1 Like

Wow, great, thanks! That’s much better!

I have a new problem though:

 if xMouse == 200 && yMouse == 200;
        PsychPortAudio('FillBuffer', paHandle, tone1);
        startTime1 = PsychPortAudio('Start', paHandle, 0); 
    else PsychPortAudio('Stop', paHandle);
    end

This leads to Matlab crashing because it just plays this beautiful continous sound for all eternity… And I cannot stop it! I don’t want to specify in seconds when to stop playing the sound, I want it to stop playing once the condition is not true anymore (when the mouse moves)… But to be honest I have the impression the mouse moves are not registered anymore once the sound starts playing because it’s like everything else is on hold. Is there something I can do about that?

Thank you so much for your help!
Stefanie

What do you mean with crashing?

What you would want in your case is check mouse position and only do a ‘Stop’, ‘Fillbuffer’, ‘Start’ sequence if the mouse position changes from one target area to another one.

Hello again!

I am sorry to bother you again but I am not successful with the thing I was trying to achieve. I have tried different options.

Option 1:

if xMouse == 200 && yMouse == 200;
    PsychPortAudio('FillBuffer', paHandle, tone1);
    startTime1 = PsychPortAudio('Start', paHandle);
    
 else
     stopTime1 = PsychPortAudio('Stop', paHandle);        
end

This works, but the sound (even though it is a perfect sinusoid tone) still isn’t properly continuous, there is a small pause that makes it sound like discrete tones.

Option 2:

if xMouse == 200 && yMouse == 200;
    PsychPortAudio('FillBuffer', paHandle, tone1);
    startTime1 = PsychPortAudio('Start', paHandle, 0);
    
 else
     stopTime1 = PsychPortAudio('Stop', paHandle);        
end

Here all I change is PsychPortAudio(‘Start’, paHandle, 0) but what happens then is that the sound starts playing once the condition becomes true, and it just continues playing forever and ever. It’s a continuous tone without interruptions but it seems like the rest of the code does not execute anymore. It’s as if the “else” statement is ignored. Can you tell me how I can solve this issue?

Thank you as always for your help!!
Stefanie

Something along the following, assuming you have 3 “zones” each of which needs a different sound. This only stops-fillbuffers-starts playback if the zone is changed:

oldzone = -1
zone = -1

while 1
  [x,y] = GetMouse(window);
  zone = -1;

  if "mouseposition x,y is in zone 1"
    zone = 1;
  end
  if "mouseposition x,y is in zone 2"
    zone = 2;
  end
  if "mouseposition x,y is in zone 3"
    zone = 3;
  end

  if zone ~= oldzone
    oldzone = zone;
    PsychPortAudio('Stop', pahandle);

    switch (zone)
      case 1
        PsychPortAudio('FillBuffer', pahandle, soundforzone1);
      case 2
        PsychPortAudio('FillBuffer', pahandle, soundforzone2);
      case 3
        PsychPortAudio('FillBuffer', pahandle, soundforzone3);
    end

    if zone ~= -1
      PsychPortAudio('Start', pahandle, 0);
    end
  end
end

If you switch zones, you will have a short interruption. If you don’t want interruptions at all, you’d need to go back to the streaming refill approach that you found first. Ofc. that requires you to make sure that you refill the right amount – too little and you might run out of sound, too much and the change of the sound will lag the actual mouse movement.

There’s also BasicSoundScheduleDemo.m which demonstrates use of sound schedules and prefilled buffers, which might allow for a more elegant approach, minimizing audible gaps and such.

Or you explain in much more detail what exactly you intend to achieve, in case the above doesn’t work for you.

Thank you! I had tried an approach like this before but I see now that I made some mistakes when I did it, so I will try to implement your suggestion and see! I think that it could work. I will also consult BasicSoundScheduleDemo.m with maximum attention. :slight_smile:
Thank you very much for your help!
Stefanie

It’s working!! Thanks so much!