Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 10

classdef musicPlayer < matlab.apps.

AppBase

% Properties that correspond to app components


properties (Access = public)
UIFigure matlab.ui.Figure
addMenu matlab.ui.container.Menu
add_file matlab.ui.container.Menu
add_folder matlab.ui.container.Menu
play_and_pause matlab.ui.control.Button
process matlab.ui.control.Slider
UIAxes matlab.ui.control.UIAxes
Tree matlab.ui.container.Tree
speedLabel matlab.ui.control.Label
PLAYSPEED matlab.ui.control.DropDown
end

properties (Access = private)


extendsions = {'.ogg';'.mp3';'.wav';'.flac';'.au';'.aif';'.aiff';'.mp4';'.m4a'}
total_frame % audio length
fs % sampling rate
player
play_speed = 1
audio_data
my_timer
fragment_size = 0.1 % per second
bar_handler
end

methods (Access = private)

function load_node(app, node)


file = node.Text;
path = node.NodeData;
full_path = fullfile(path, file);
if ~exist(full_path, 'file')
errordlg("文件不存在");
return;
end
[app.audio_data, app.fs] = audioread(fullfile(path, file));
pause(app.player);
app.total_frame = size(app.audio_data,1);
app.player = audioplayer(app.audio_data, app.play_speed*app.fs);
play(app.player);
end

function node = addNode(app, file, path)


node = uitreenode(app.Tree);
node.Text = file;
node.NodeData = path;
end

function draw_bar(app)
half_space = floor(app.fs*app.play_speed*app.fragment_size/2);
left = app.player.CurrentSample - half_space;
if left<1
left = 1;
end
right = app.player.CurrentSample + half_space;
if right>app.total_frame
right = app.total_frame;
end
X = app.audio_data(left:right,:);
% merge the left and right channels
X = sum(X, 2);
L = length(X);
Y = fft(X);
tmp = abs(Y/L);
P1 = 2*tmp(1:floor(L/2)+1);
freq = app.fs*app.play_speed*(0:(L/2))/L;
P2 = P1(freq<2500&freq>20);
freq2 = freq(freq<2500&freq>20);
window = floor(length(freq2)/32);
XData = smooth(freq2, window);
YData = smooth(P2, window);
XData = XData(1:window:end);
YData = YData(1:window:end);

set(app.bar_handler, 'XData', XData, 'YData', YData);


end

function update_process(app, hObject, eventdata)


if ~isempty(app.player)&&strcmpi(get(app.player,'running'),'on')
app.process.Value = app.player.CurrentSample/app.total_frame;
app.draw_bar();
end
end
end

% Callbacks that handle component events


methods (Access = private)

% Code that executes after component creation


function startupFcn(app)
% initialize
app.bar_handler = bar(app.UIAxes, 0, 0);
% limit y-axix
ylim(app.UIAxes, [0, 0.2]);
app.my_timer = timer("ExecutionMode", "fixedSpacing", 'Period', 0.1,
"TimerFcn", @app.update_process);
start(app.my_timer);
end

% Button pushed function: play_and_pause


function play_and_pauseButtonPushed(app, event)
if isempty(app.player)
return
end
if strcmpi(get(app.player,'running'),'on')
% pause playing
pause(app.player);
else
%keep playing
resume(app.player);
end
end

% Value changed function: process


function processValueChanged(app, event)
value = app.process.Value;
if isempty(app.player)
return
end
status = strcmpi(get(app.player,'running'),'on');
if status
pause(app.player);
end
% start playing at the exact frame
play(app.player, round(value*app.total_frame));
end

% Selection changed function: Tree


function TreeSelectionChanged(app, event)
selectedNodes = app.Tree.SelectedNodes;
% upload music
app.load_node(selectedNodes);
end

% Menu selected function: add_file


function add_fileMenuSelected(app, event)
s = '';
for index = 1:length(app.extendsions)
s = strcat(s, '*', app.extendsions{index}, ';');
end
[files,path] = uigetfile({s, "音频文件"}, 'MultiSelect', 'on');
% if choose no file, go back
if ~ischar(path)
return
end
% if one file
if ~iscell(files)
app.addNode(files, path);
return
end
% if up to one file
for i = 1:length(files)
app.addNode(files{i}, path);
end
end

% Menu selected function: add_folder


function add_folderMenuSelected(app, event)
path = uigetdir;
if ~ischar(path)
return
end
files = batch_load(path, app.extendsions{:});
f = waitbar(0,'is adding file...', 'WindowStyle', 'modal');
% cancel loading
try
for i = 1:length(files)
app.addNode(files{i}, path);
% refresh per 50
if mod(i, 50) == 0
waitbar(i/length(files),f);
end
end
waitbar(1,f);
close(f);
catch
end
end

% Value changed function: PLAYSPEED


function PLAYSPEEDValueChanged(app, event)
if isempty(app.player)
return
end
status = strcmpi(get(app.player,'running'),'on');
if status
pause(app.player);
end
current_frame = app.player.CurrentSample;
% change speed
app.play_speed = str2double(app.PLAYSPEED.Value);
app.player.SampleRate = app.play_speed*app.fs;
if status
play(app.player, current_frame);
end
end

% Close request function: UIFigure


function UIFigureCloseRequest(app, event)
pause(app.player);
delete(app.player);
stop(app.my_timer);
delete(app.my_timer);
delete(app)
end
end

% Component initialization
methods (Access = private)

% Create UIFigure and components


function createComponents(app)

% Create UIFigure and hide until all components are created


app.UIFigure = uifigure('Visible', 'off');
app.UIFigure.Color = [1 1 1];
app.UIFigure.Colormap = [0.2431 0.149 0.6588;0.2431 0.1529 0.6745;0.2471
0.1569 0.6863;0.2471 0.1608 0.698;0.251 0.1647 0.7059;0.251 0.1686 0.7176;0.2549 0.1725
0.7294;0.2549 0.1765 0.7412;0.2588 0.1804 0.749;0.0745 0.6235 1;0.2627 0.1882
0.7725;0.2627 0.1961 0.7922;0.2667 0.2 0.8039;0.2667 0.2039 0.8157;0.2706 0.2078
0.8235;0.2706 0.2157 0.8353;0.2706 0.2196 0.8431;0.2745 0.2235 0.851;0.2745 0.2275
0.8627;0.2745 0.2314 0.8706;0.2745 0.2392 0.8784;0.2784 0.2431 0.8824;0.2784 0.2471
0.8902;0.2784 0.2549 0.898;0.2784 0.2588 0.902;0.2784 0.2667 0.9098;0.2784 0.2706
0.9137;0.2784 0.2745 0.9216;0.2824 0.2824 0.9255;0.2824 0.2863 0.9294;0.2824 0.2941
0.9333;0.2824 0.298 0.9412;0.2824 0.3059 0.9451;0.2824 0.3098 0.949;0.2824 0.3137
0.9529;0.2824 0.3216 0.9569;0.2824 0.3255 0.9608;0.2824 0.3294 0.9647;0.2784 0.3373
0.9686;0.2784 0.3412 0.9686;0.2784 0.349 0.9725;0.2784 0.3529 0.9765;0.2784 0.3569
0.9804;0.2784 0.3647 0.9804;0.2745 0.3686 0.9843;0.2745 0.3765 0.9843;0.2745 0.3804
0.9882;0.2706 0.3843 0.9882;0.2706 0.3922 0.9922;0.2667 0.3961 0.9922;0.2627 0.4039
0.9922;0.2627 0.4078 0.9961;0.2588 0.4157 0.9961;0.2549 0.4196 0.9961;0.251 0.4275
0.9961;0.2471 0.4314 1;0.2431 0.4392 1;0.2353 0.4431 1;0.2314 0.451 1;0.2235 0.4549
1;0.2196 0.4627 0.9961;0.2118 0.4667 0.9961;0.2078 0.4745 0.9922;0.2 0.4784
0.9922;0.1961 0.4863 0.9882;0.1922 0.4902 0.9882;0.1882 0.498 0.9843;0.1843 0.502
0.9804;0.1843 0.5098 0.9804;0.1804 0.5137 0.9765;0.1804 0.5176 0.9725;0.1804 0.5255
0.9725;0.1804 0.5294 0.9686;0.1765 0.5333 0.9647;0.1765 0.5412 0.9608;0.1765 0.5451
0.9569;0.1765 0.549 0.9529;0.1765 0.5569 0.949;0.1725 0.5608 0.9451;0.1725 0.5647
0.9412;0.1686 0.5686 0.9373;0.1647 0.5765 0.9333;0.1608 0.5804 0.9294;0.1569 0.5843
0.9255;0.1529 0.5922 0.9216;0.1529 0.5961 0.9176;0.149 0.6 0.9137;0.149 0.6039
0.9098;0.1451 0.6078 0.9098;0.1451 0.6118 0.9059;0.1412 0.6196 0.902;0.1412 0.6235
0.898;0.1373 0.6275 0.898;0.1373 0.6314 0.8941;0.1333 0.6353 0.8941;0.1294 0.6392
0.8902;0.1255 0.6471 0.8902;0.1216 0.651 0.8863;0.1176 0.6549 0.8824;0.1137 0.6588
0.8824;0.1137 0.6627 0.8784;0.1098 0.6667 0.8745;0.1059 0.6706 0.8706;0.102 0.6745
0.8667;0.098 0.6784 0.8627;0.0902 0.6824 0.8549;0.0863 0.6863 0.851;0.0784 0.6902
0.8471;0.0706 0.6941 0.8392;0.0627 0.698 0.8353;0.0549 0.702 0.8314;0.0431 0.702
0.8235;0.0314 0.7059 0.8196;0.0235 0.7098 0.8118;0.0157 0.7137 0.8078;0.0078 0.7176
0.8;0.0039 0.7176 0.7922;0 0.7216 0.7882;0 0.7255 0.7804;0 0.7294 0.7765;0.0039 0.7294
0.7686;0.0078 0.7333 0.7608;0.0157 0.7333 0.7569;0.0235 0.7373 0.749;0.0353 0.7412
0.7412;0.051 0.7412 0.7373;0.0627 0.7451 0.7294;0.0784 0.7451 0.7216;0.0902 0.749
0.7137;0.102 0.7529 0.7098;0.1137 0.7529 0.702;0.1255 0.7569 0.6941;0.1373 0.7569
0.6863;0.1451 0.7608 0.6824;0.1529 0.7608 0.6745;0.1608 0.7647 0.6667;0.1686 0.7647
0.6588;0.1725 0.7686 0.651;0.1804 0.7686 0.6471;0.1843 0.7725 0.6392;0.1922 0.7725
0.6314;0.1961 0.7765 0.6235;0.2 0.7804 0.6157;0.2078 0.7804 0.6078;0.2118 0.7843
0.6;0.2196 0.7843 0.5882;0.2235 0.7882 0.5804;0.2314 0.7882 0.5725;0.2392 0.7922
0.5647;0.251 0.7922 0.5529;0.2588 0.7922 0.5451;0.2706 0.7961 0.5373;0.2824 0.7961
0.5255;0.2941 0.7961 0.5176;0.3059 0.8 0.5059;0.3176 0.8 0.498;0.3294 0.8 0.4863;0.3412
0.8 0.4784;0.3529 0.8 0.4667;0.3686 0.8039 0.4549;0.3804 0.8039 0.4471;0.3922 0.8039
0.4353;0.4039 0.8039 0.4235;0.4196 0.8039 0.4118;0.4314 0.8039 0.4;0.4471 0.8039
0.3922;0.4627 0.8 0.3804;0.4745 0.8 0.3686;0.4902 0.8 0.3569;0.5059 0.8 0.349;0.5176
0.8 0.3373;0.5333 0.7961 0.3255;0.5451 0.7961 0.3176;0.5608 0.7961 0.3059;0.5765 0.7922
0.2941;0.5882 0.7922 0.2824;0.6039 0.7882 0.2745;0.6157 0.7882 0.2627;0.6314 0.7843
0.251;0.6431 0.7843 0.2431;0.6549 0.7804 0.2314;0.6706 0.7804 0.2235;0.6824 0.7765
0.2157;0.698 0.7765 0.2078;0.7098 0.7725 0.2;0.7216 0.7686 0.1922;0.7333 0.7686
0.1843;0.7451 0.7647 0.1765;0.7608 0.7647 0.1725;0.7725 0.7608 0.1647;0.7843 0.7569
0.1608;0.7961 0.7569 0.1569;0.8078 0.7529 0.1529;0.8157 0.749 0.1529;0.8275 0.749
0.1529;0.8392 0.7451 0.1529;0.851 0.7451 0.1569;0.8588 0.7412 0.1569;0.8706 0.7373
0.1608;0.8824 0.7373 0.1647;0.8902 0.7373 0.1686;0.902 0.7333 0.1765;0.9098 0.7333
0.1804;0.9176 0.7294 0.1882;0.9255 0.7294 0.1961;0.9373 0.7294 0.2078;0.9451 0.7294
0.2157;0.9529 0.7294 0.2235;0.9608 0.7294 0.2314;0.9686 0.7294 0.2392;0.9765 0.7294
0.2431;0.9843 0.7333 0.2431;0.9882 0.7373 0.2431;0.9961 0.7412 0.2392;0.9961 0.7451
0.2353;0.9961 0.7529 0.2314;0.9961 0.7569 0.2275;0.9961 0.7608 0.2235;0.9961 0.7686
0.2196;0.9961 0.7725 0.2157;0.9961 0.7804 0.2078;0.9961 0.7843 0.2039;0.9961 0.7922
0.2;0.9922 0.7961 0.1961;0.9922 0.8039 0.1922;0.9922 0.8078 0.1922;0.9882 0.8157
0.1882;0.9843 0.8235 0.1843;0.9843 0.8275 0.1804;0.9804 0.8353 0.1804;0.9765 0.8392
0.1765;0.9765 0.8471 0.1725;0.9725 0.851 0.1686;0.9686 0.8588 0.1647;0.9686 0.8667
0.1647;0.9647 0.8706 0.1608;0.9647 0.8784 0.1569;0.9608 0.8824 0.1569;0.9608 0.8902
0.1529;0.9608 0.898 0.149;0.9608 0.902 0.149;0.9608 0.9098 0.1451;0.9608 0.9137
0.1412;0.9608 0.9216 0.1373;0.9608 0.9255 0.1333;0.9608 0.9333 0.1294;0.9647 0.9373
0.1255;0.9647 0.9451 0.1216;0.9647 0.949 0.1176;0.9686 0.9569 0.1098;0.9686 0.9608
0.1059;0.9725 0.9686 0.102;0.9725 0.9725 0.0941;0.9765 0.9765 0.0863;0.9765 0.9843
0.0824;0.2157 0.6706 0.5176;1 1 1;1 1 1];
app.UIFigure.Position = [100 100 737 360];
app.UIFigure.Name = 'UI Figure';
app.UIFigure.CloseRequestFcn = createCallbackFcn(app,
@UIFigureCloseRequest, true);

% Create addMenu
app.addMenu = uimenu(app.UIFigure);
app.addMenu.Text = 'add';

% Create add_file
app.add_file = uimenu(app.addMenu);
app.add_file.MenuSelectedFcn = createCallbackFcn(app,
@add_fileMenuSelected, true);
app.add_file.Text = 'document';

% Create add_folder
app.add_folder = uimenu(app.addMenu);
app.add_folder.MenuSelectedFcn = createCallbackFcn(app,
@add_folderMenuSelected, true);
app.add_folder.Text = 'folder';

% Create play_and_pause
app.play_and_pause = uibutton(app.UIFigure, 'push');
app.play_and_pause.ButtonPushedFcn = createCallbackFcn(app,
@play_and_pauseButtonPushed, true);
app.play_and_pause.Position = [47 63 100 24];
app.play_and_pause.Text = 'play/pause';

% Create process
app.process = uislider(app.UIFigure);
app.process.Limits = [0 1];
app.process.MajorTicks = [];
app.process.MajorTickLabels = {''};
app.process.ValueChangedFcn = createCallbackFcn(app, @processValueChanged,
true);
app.process.MinorTicks = [];
app.process.Position = [33 135 378 3];
% Create UIAxes
app.UIAxes = uiaxes(app.UIFigure);
title(app.UIAxes, '')
xlabel(app.UIAxes, '')
ylabel(app.UIAxes, '')
app.UIAxes.Box = 'on';
app.UIAxes.XTick = [];
app.UIAxes.XTickLabel = {};
app.UIAxes.YTick = [];
app.UIAxes.YTickLabel = {};
app.UIAxes.Position = [7 152 429 185];

% Create Tree
app.Tree = uitree(app.UIFigure);
app.Tree.SelectionChangedFcn = createCallbackFcn(app,
@TreeSelectionChanged, true);
app.Tree.Position = [463 25 235 312];

% Create speedLabel
app.speedLabel = uilabel(app.UIFigure);
app.speedLabel.HorizontalAlignment = 'right';
app.speedLabel.Position = [259 64 38 22];
app.speedLabel.Text = 'speed';

% Create PLAYSPEED
app.PLAYSPEED = uidropdown(app.UIFigure);
app.PLAYSPEED.Items = {'0.5', '0.75', '1', '1.25', '1.5', '2'};
app.PLAYSPEED.ValueChangedFcn = createCallbackFcn(app,
@PLAYSPEEDValueChanged, true);
app.PLAYSPEED.Position = [312 64 100 22];
app.PLAYSPEED.Value = '1';

% Show the figure after all components are created


app.UIFigure.Visible = 'on';
end
end

% App creation and deletion


methods (Access = public)

% Construct app
function app = musicPlayer

% Create UIFigure and components


createComponents(app)

% Register the app with App Designer


registerApp(app, app.UIFigure)

% Execute the startup function


runStartupFcn(app, @startupFcn)

if nargout == 0
clear app
end
end

% Code that executes before app deletion


function delete(app)

% Delete UIFigure when app is deleted


delete(app.UIFigure)
end
end
end

You might also like