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
Related
If entered at the command line in Matlab 2016, the following lines will create an audiorecorder object, start it recording, stop it recording, write the recorded samples to a wav, and play the samples from the recorder object (i.e., not from the newly written wav file):
rec = audiorecorder(44100, 16, 1);
record(rec); % User speaks now
stop(rec);
audiowrite('foo.wav', getaudiodata(rec), 44100);
play(rec);
I am trying to partition this into a three button GUI (created with GUIDE) with the following functionality:
Start button, which starts a created recorder
Stop button, which stops the recorder AND saves the wav file
Playback button, which plays back the samples from the recorder
(The idea is to be able to record small samples of text, quickly listen for a first pass of quality, and decide whether or not to record over or to advance to the next sample.
Create the recorder object (among other things) in the initial setup for the GUI:
function ReadingScript_OpeningFcn(hObject, eventdata, handles, varargin)
recorder = audiorecorder(Fs, nbits, nChannels);
Start the recorder object:
function startRecord_Callback(hObject, eventdata, handles)
global recorder
set(handles.status,'String', 'Recording');
record(recorder);
Stop the recorder object AND save samples to a file:
function stopRecord_Callback(hObject, eventdata, handles)
global recorder
global wavname
stop(recorder);
audiowrite(wavname, getaudiodata(recorder), 44100)
Play the samples back:
function PlayBack_Callback(hObject, eventdata, handles)
global recorder
play(recorder)
Everything here works except playing the samples back. Samples are recorded into the recorder, which starts and stops with the correct button presses, and a wav file is saved. But the samples will not play. I even know the playback button is firing because of the intentional missing semicolon, which causes the details of the recorder object to be printed to screen, which also verifies that samples are still in it.
What exactly am I missing, that will make the audio play?
There seems to be a quirk of the audiorecorder that means it won't play within a GUI.
In order to get it working I needed to use playblocking with an audioplayer object as shown below
global recorder
disp('playing');
player = audioplayer(getaudiodata(recorder),44100,16);
playblocking(player);
I am trying to play audio file along with moving line on a graph....
[signal,Fs]=wavread('sig_c.wav');
time=(0:length(signal)-1)/Fs;
figure(1);
plot(time,signal)
grid on;
end_time=length(signal)/Fs;
h=line([0,0],[-0.30 0.30],'Color','r','Marker','o','LineWidth',3);
sound(signal,fs);
tic
t=toc;
while t<end_time
set(h,'xdata',t*[1 1]);
drawnow;
t=toc;
end
it play the audio file first and then move the line on the graph.but the result of above is not required one.we need to play the audio file in synchronization with moving line on the graph..
how to do
your help will be appreciated greatly......
you could use the audioplayer for playback instead of sound. So
player = audioplayer(signal, Fs);
Player is the the audioplayer object (check MATLAB help on audioplayer) which you can play using
play(player);
While the sound is playing you can do whatever you want. For example there is a CurrentSample property which shows you the sample played at the moment. You can get it
c_sample = get(player,'CurrentSample');
and use it for your plotting purposes.
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!
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.
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.