Matlab: How to call play(recorder) from GUI - matlab

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);

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.

Audio player - sharing data between callbacks

I already asked this question to no avail. I couldn't solve the problem. I am trying again maybe someone can help!
I have 2 buttons, Play and Stop. I would have the path of an audio track at hand and want the audio to play when the user clicks on play and stop when the user clicks on stop. The only problem is that once the callback function of play exits, the variable holding the info about the player is emptied, and hence the track does not play. I needed some method to share data between callback functions..
I tried using global variables to no avail..
then I looked at this and I tried more or less each and every mentioned method: http://www.mathworks.com/help/matlab/creating_guis/share-data-among-callbacks.html#bt9p4qp
Let's take for instance this method:
In the play callback button:
[Y, Fs] = audioread(path);
player = audioplayer(Y,Fs);
hObject.UserData = player;
play(player);
In the stop callback button:
h = findobj('Tag','Play');
player = h.UserData;
stop(player);
On hObject.UserData = player; I am getting this warning when clicking on the play button:
Warning: Struct field assignment overwrites a value with class "double". See MATLAB R14SP2 Release Notes,
Assigning Nonstructure Variables As Structures Displays Warning, for details.
The solution I need would let me keep using the rest of the program while the music is playing, stop the audio whenever I want, and the program must obviously keep working well after that.
Any ideas guys? any help would be truly appreciated!
Thanks in advance!
I'm not shure whether the following works:
hObject.UserData = player;
I would (as you have already found out) use a global variable. I didn't test this solution, but it should work and shows how to use global variables in combination with a GUI correct. Please correct me if you found a mistake.
% --- Executes just before GUI is made visible.
function GUI_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject handle to figure
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% varargi
% Create a global player variable
global player;
player = audioplayer(Y,Fs);; % initialize player
% --- Outputs from this function are returned to the command line.
function pushbutton_off(hObject, eventdata, handles)
global player; % tell matlab player is global
play(player)
% --- Outputs from this function are returned to the command line.
function pushbutton_on(hObject, eventdata, handles)
global player;
stop(player);

play audio file synchronously with moving line on graph,MATLAB

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.

stop playing a wav file in MATLAB GUI

I created a GUI in MATLAB to analyze piano songs. My GUI basically has a load, play and stop button.
I load the file using the code
[FileName,PathName] = uigetfile({'*.wav'},'Load Wav File');
[x,Fs] = wavread([PathName '/' FileName]);
handles.fileLoaded = 1;
guidata(hObject, handles);
This is the code I used to play the song
if (handles.fileLoaded==1)
sound(handles.x, handles.Fs);
end
After this, I'm not sure how I can stop the song, so that every time i test the GUI I wouldn't have to keep listening to the whole song... Any suggestions??
Thanx in advance :)
You should use audioplayer
[FileName,PathName] = uigetfile({'*.wav'},'Load Wav File');
[x,Fs] = wavread([PathName '/' FileName]);
player=audioplayer(x,Fs);
% start the playback
play(player);
% pause the playback
pause(player);
% resume the playback
resume(player)
% stop the playback
stop(player)
You can use audioplayer class methods in your buttons code.
You can look this link too How to stop sound in MATLAB?

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