Number of push button change

I have an audio that I've split into 2 segments. I'd like to plot the audio file and add 2 push buttons in the figure, in order to play each segment. This part is quite standard to do. What if I decide to split the signal in 3 or 4, or more? How can I do that without creating all the possible push button? Is there any cleaver way of do it? Using a for loop uicontrol() would be a solutions.

 Accepted Answer

Image Analyst
Image Analyst on 18 Jan 2019
Edited: Image Analyst on 18 Jan 2019
Have an edit field or scrollbar/slider that allows the user to specify the number of segments to split it up into. Then have a single pushbutton that reads the number from the edit field and does its thing
numSegments = handles.sldNumSegments.Value; % For a scrollbar/slider in GUIDE
numSegments = str2double(handles.edtNumSegments.String); % For an edit text box in GUIDE
You could do the same thing to have the user say what segment to play, so they could specify to split it up into 9 segments and play segment #4 for example.
Attach your fig file and m file if you need any more help.

5 Comments

I have a function that returns the segments (seg) as a cell array, so seg{1,1} would be the first (k = 1) segment.
I have 2 problems here, 1) only the last (k=3) push button appears in the figure (see figure blow);
2) How to pass seg{1,k} to play it?
Thank you!Screenshot 2019-01-19 at 01.11.53.png
k = 3;
close all
hfig = figure();
[audio, fs] = audioread('audio_file.wav');
%% I have a function that returns the segments (seg) as a cell array,
% so seg{1,1} would be the first (k = 1) segment
plot(x)
for i = 1 : k
playB = uicontrol(hfig, 'Style', 'pushbutton', 'String', 'Play', ...
'Position', [k * 100,200,83,20], ...
'UserData', k, ...
'CallBack', @ColorMapB_Callback);
set(playB, 'UserData', k);
ColorMapB_Callback(playB);
end
function ColorMapB_Callback(hObject, eventdata, handles)
if (get(hObject, 'Value') == 1)
seg_number = get(hObject, 'UserData');
sound(seg{1,seg_number},fs);
end
end
João
João on 19 Jan 2019
Edited: João on 19 Jan 2019
@Image Analyst each segment has different dimensions.
You should use GUIDE. I see no advantage to creating a variable number of buttons on the fly. Not only that, but you're overwriting the control's handle, playB, on each iteration. That probably causes the problem. If you did want to tediously and manually create controls in code, then you should just use an edit field, a listbox, or a scrollbar to let the user select the segment, and then have one button to play the selected segment.
How do I get the value "val" from popupmenu into the callback of the push button?
selectSeg = uicontrol(gcf, 'Style' , 'popupmenu', ...
'String' , typeColorMap, ...
'Position', [10,200,83,20],...
'CallBack', @seg_index_Callback);
button = uicontrol('Parent', gcf,'Style','pushbutton',...
'Units','normalized',...
'Position',[0.4 0.3 0.2 0.1],...
'String','Display Difference',...
'Callback', @button_callback);
function seg_index_Callback(hObject, eventdata, handles)
str = get(hObject, 'String');
val = get(hObject,'Value');
end
function button_callback(hObject, eventdata, handles)
popup_sel_index = get(hObject, 'Value')
end
I've tried this but it did not work...
popup_sel_index = get(handles.popupmenu, 'Value');
Of course it didn't work. Because you're not using GUIDE. You created the popup on your own for some reason with uicontrol. So it's handle is not handles.popupmenu, but the name you gave it, which is selectSeg. So to get the value you need to refer to selectSeg.Value. If you want it in a separate variable for some reason, you could do
popup_sel_index = selectSeg.Value;

Sign in to comment.

More Answers (1)

Kevin Phung
Kevin Phung on 18 Jan 2019
Instead of having a pushbutton per segment, perhaps you can create a listbox that will be populated with the number of segments in your audio file.
Pushing the pushbutton will then play the selected segment.

2 Comments

How can I pass the popup_sel_index to the callback play?
selectSeg = uicontrol(gcf, 'Style' , 'popupmenu', ...
'String' , typeColorMap, ...
'Position', [10,200,83,20],...
'CallBack', @seg_index_Callback);
playB = uicontrol(gcf, 'Style' , 'push', ...
'String' , 'Play', ...
'Position', [10,225,83,20], ...
'CallBack', @play_Callback);
seg_index_Callback(selectSeg)
play_Callback(playB)
function seg_index_Callback(hObject, eventdata, handles)
popup_sel_index = get(hObject, 'Value');
end
function play_Callback(hObject, eventdata, handles)
soundsc(seg{1,popup_sel_index})
end
Would have been no problem with GUIDE where every callback function has access to ALL the controls and their values. But since you've accepted this answer, I guess you want to keep attempting to do it this way. I'm sure Kevin will answer shortly.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!