Wait for sound to finish - matlab

I am playing a sound using sound command in Matlab and I want for the program to wait until it finishes playing the sound before executing the next command. How can I do it?
>>tic
>>sound(signal,Fs)
>>wait??
>>b=toc

You can use the audioplayer function:
%Create player object
player = audioplayer(signal, Fs);
%play sound
play(player)
while( strcmp(player.running,'on') )
{
% Waiting for sound to finish
}

I had a similar issue and tried to use the Estaban's suggested answer, but I couldn't get my while loop right (I am a novice programmer) and the script kept hanging. Eventually I stumbled upon the playblocking function, which seems to do exactly what the OP wanted - to pause the code until the player is done playing the sound. So, to modify Esteban's previous answer, use the "playblocking" function in place of the "play" function. Then the While loop is not needed!

Related

Real time audio matlab. Loop while answering to gui calls

I'm doing a simple GUI in matlab using guide, where I have some sliders to select a frequency or many which then get plotted and played through the speakers. I'm learning real-time sound right now so I thought it'd be neat to incorporate it into the application. I right now have a button that plays the sinusoidal waves for 10 seconds when I press it, but I want a checkbox that disables the button when checked and immediately starts playing the sound continuously until the checkbutton is unchecked again.
I can't really get my head around how to do this in Matlab since I heard Matlab is inherently single threaded. And how to do it right with the GUI and everything since I suspect GUI creation is something you think you do right, but you miss some kind of detail and it only works in some situations.
What I think would be the easy way would be to have the check of the checkbox set the 'Enable' property of the Play button to false, and start an infinite loop that plays it from the real time system object I create. When I however uncheck the checkbox, it should set a flag or something to false and enable the Play button again. Could someone point me to if this is the right approach? How do I make the application listen to clicks on the check box while simultanously being in an infinite loop that processes and plays sound? The simultanous loop should be sensitive to changes in the sliders determining the frequencies and those frequencies are also stored in the handles variable.
Mockup code:
function playbutton_Callback(hObject, eventdata, handles)
freqs = [handles.freq1, handles.freq2, handles.freq3]
hightensecy = sinewave(handles.hightensecx, freqs); %creates a sinewave consisting of the three frequencies. hightensecx is a time vector of ten seconds with a high sample rate.
sound(hightensecy, handles.highsr);
figure;
plot(handles.hightensecx,hightensecy);
function y = sinewave(x, freqs)
% x in sec
y(:,1:size(freqs,2)) = sin(2*pi*x*freqs);
y=sum(y,2)/size(freqs,2);
end
% --- Other code to make the sliders store their values in handles.freq1, handles.freq2... ---
function continuousbox_Callback(hObject, eventdata, handles)
selected = get(hObject,'Value');
if(selected)
set(handles.playbutton, 'Enable', 'off');
startsound(handles);
else
set(handles.playbutton, 'Enable', 'on');
stopsound();
end
% Plays sound continuously
function startsound(handles)
%%Initialization
SamplesPerFrame = 1024;
Fs = handles.highsr;
Player = dsp.AudioPlayer('SampleRate', Fs);
%%Stream
tic
while(1)
%TODO Read in a new 1024 bytes chunk and make sure it has the same
%characteristics as sinewave(x, freqs)
step(Player, outsound)
end
%Stops the continuously played sound
function stopsound()
%TODO Somehow stop the loop inside startsound(handles)
If it is possible, it would be good if the resulting startsound function plays a sound that sounds exactly like the playbutton callback, only indefinitely. I'm also not sure how to handle phase issues that might occur in the real time loop. Should I use a time counter that tics away and calculates the current 1024 chunk's y-value and in that case, should I just use the time distance from tic, or increase it with 1024/sample rate seconds per time? Thanks in advance.

Changing the Value of a Variable While the Code is Running

I'm writing a code that will take the location of the cursor and output a sound signal. But here's the catch: There is already a sin function playing in the background, the mouse click will merely change the x and y values of this sound. Here is what I came up with so far:
clear all
clc
k = 1:1200;
k = k/5000;
x=1;
y=1;
while i<10;
[x,y]=ginput(1)
vib= 0.5*sin(2*pi*y*k);
note=sin(pi*x*k*440);
ses = note+vib;
sound (ses);
end
As you can see my code just plays a sin function but it is discrete. Can someone please help me? I researched handles and callbacks but I just can't get it in my head. The explanations that I find in the net are too complicated for me to understand.
sound (ses); just takes the variable "ses" and plays. While it plays you can not interfere in the data in the way you think. You can observe the change in the next sound() function call.
If you want to continously play a waveform you can look at here:
Matlab: How to get the current mouse position on a click by using callbacks

How Do I set multiple File Player Audio Units to start at the same time?

Right now I have a loop that loops through an array of file player audio units and tells them what position in the audio file to start playing. (this works) In this same loop I have the following code to tell the units when to start playing (-1 makes them play in the next render cycle). The problem is that they are not starting at the same time because the first track starts playing before i have had a chance to tell the third track to play. What I want to say is "track one, you play in exactly 5 cycles, Track 2 you play in exactly 4 cycles, Track 3 you play in exactly 3 cycles... etc. that way they play at the same time. Is this the right approach? If so, what value do you set for startTime.mSampleTime ? I have not found any documentation that tells me how to do this. Thanks
// tell the file player AU when to start playing (-1 sample time means next render cycle)
AudioTimeStamp startTime;
memset (&startTime, 0, sizeof(startTime));
startTime.mFlags = kAudioTimeStampSampleTimeValid;
startTime.mSampleTime = -1;
AudioUnitSetProperty(fileUnitArray[mycount], kAudioUnitProperty_ScheduleStartTimeStamp, kAudioUnitScope_Global, 0, &startTime, sizeof(startTime));
I was not able to track down any information on setting mSampleTime to any other value then -1 (i.e start on the next cycle) but I was able to work around the problem. Instead of keeping the AUGraph running, using AudioUnitReset to reset the file player audio unit and then using the code above to restart the file players, I store the current file player play-head position, stop the AUGraph completely, reinitialize the AUGraph with the current play-head position instead of telling it to start at position zero, and then restart the AUGRAPH.
What you need to do is schedule the playback of the audio files from the render thread.
You load the files on a different thread but you tell the files to play in the next render cycle from the render thread. This way all of your files wil start at the same time.

Callback at certain times during audio playback

Is it possible to play an audio file from the user's ipod library and have a callback occur whenever the player reaches a certain time point ? I need it to be very accurate, so simply using methods like currentPlaybackTime might not be enough because float equality is inaccurate. I could use the A - B < Epsilon float check, but is there a better, more accurate way of achieving this?
If you can target iOS 4.0 or hight, try using AVPlayer. Then you will be able to use
- (id)addBoundaryTimeObserverForTimes:(NSArray *)times queue:(dispatch_queue_t)queue usingBlock:(void (^)(void))block
which takes an array of NSValues for CMTimes and will run the contents of the block each time one of the boundary times is hit. (Beware of some behavior like, if you pause the audio file inside of the block, the callback will fire again when you unpause it).
Since CMTime is not a float, I think this will be more accurate than checking for the currentTime repeatedly.

How to stop sound in MATLAB?

When playing a sound using e.g:
sound(x,fs);
I sometimes by accident play the wrong one. If x is of substantial length, I currently try to wait until the sound has completed. Any suggestions on how to "abort" the playback? I've already tried
sound(mute,fs); % Mute is a short vector containing all zeroes
But that didn't work. I'm using Windows by the way.
UPDATE:
The following solution proposed by kigurai seems to do the trick:
sound(x,fs); % Start the audio
Now kill audio by
clear playsnd
Try this command Definitely works !!
clear sound
Mathworks says (and this applies to sound as well),
There is no function in MATLAB that
can pause or stop audio playback once
initiated by WAVPLAY. Instead of using
WAVPLAY, an alternative is to create
an AUDIOPLAYER object. This type of
object has methods which allow
pausing, resuming and stopping the
audio playback. For example:
player = audioplayer(Y, Fs)
% start the playback
play(player);
% pause the playback
pause(player);
% resume the playback
resume(player)
% stop the playback
stop(player)
Never used "sound()" but when I have played audio using wavplay(..., ..., 'async') I can stop the sound by issuing
clear playsnd
Maybe that works with sound() as well?
Note: This is when playing asynchronously. For synchronous playback I assume that CTRL-C should break it, but I had issues with wavplay() last time I tried that.
Use the audioplayer object instead - it gives you the full control on what you do with the sound. I.e:
player = audioplayer(x, fs);
play(player) % start the player
stop(player) % stop whenever you like...
Audioplayer has a lot of other useful stuff:
http://www.mathworks.com/help/techdoc/ref/audioplayer.html