利用matlabgui制作乐谱

利用matlabgui制作乐谱,matlab,user-interface,Matlab,User Interface,我正在做一个自动转录钢琴音乐(单音)的项目。我想创建一个MatlabGUI,它可以显示转录音乐的乐谱。然而,我不太确定如何在MatlabGUI上设计GrandStaff。这是我第一次使用GUI,我真的很想得到一些帮助。 我遇到了这个链接,并希望类似的东西,唯一的事情是我将加载一个.wav文件,而不是手动给出一个旋律。 我使用的是MatlabR2011A软件。 Thanx提前:) 我现在只专注于用谱号显示高音谱号(前5行)。我的第一次蠕动 我为音乐GUI制作了一个存根,如下所示 迄今为止的结果

我正在做一个自动转录钢琴音乐(单音)的项目。我想创建一个MatlabGUI,它可以显示转录音乐的乐谱。然而,我不太确定如何在MatlabGUI上设计GrandStaff。这是我第一次使用GUI,我真的很想得到一些帮助。 我遇到了这个链接,并希望类似的东西,唯一的事情是我将加载一个.wav文件,而不是手动给出一个旋律。

我使用的是MatlabR2011A软件。 Thanx提前:)

我现在只专注于用谱号显示高音谱号(前5行)。

我的第一次蠕动 我为音乐GUI制作了一个存根,如下所示

迄今为止的结果:

我采取的方法如下:

  • 在网上查找(免版税)高音谱号、低音谱号和大括号的SVG图像
  • 不幸的是,MATLAB不支持矢量图形。因此,将这些SVG转换为合理的高分辨率PNG
  • 在MATLAB图形中重新缩放和定位这些图像
  • 下面是我的存根,它显示了我将采取的总体策略。基本上,我会对所有固定的音符、休止符、锐器等符号使用相同的方法。查找/创建符号的图像,将其加载到MATLAB中,并在需要时缩放/显示

    当然,你得有点创意。例如,您不需要第128个rest的图像;只需将第8个剩余部分复制3次,并将每个副本偏移一点。另一个例子:将一个第八音符的图像在其头部和尾部向上分割。它的头与四分之一音符相等,只有在同一和弦上的最后一个音符被画出来之后,它的尾才会被画出来

    用于绘制非固定符号(请考虑连接多组符号的线、线)≤ 第8条注释等),您必须做出决定:

  • 手动绘制它们。您必须创造性地使用
    补丁
    等所有内置绘图功能。可能相当耗时
  • 使用图像,通过
    imtransform
    和朋友获得创意。有利的一面是,结果可能会看起来更好,而且可能会花费更少的时间。缺点是这些是图像处理工具箱的一部分,并非所有用户都可以访问
  • 真正最好的:检测用户是否有图像处理工具箱(使用
    ver('images')
    )。如果是,请使用选项2。如果否,请使用选项1
  • 另一种选择 另一个选择是使用专门的音乐字体。音乐字体将字符映射到音乐符号。好的字体是矢量化的,也就是说,它们可以任意放大或缩小,而不会降低质量。这就减少了对这些图像的需求。您所要担心的就是将正确的字符映射到所需的符号,以及字符的位置

    但是,对于和弦和非固定符号,您仍然必须使用图像

    存根 但现在,我使用的存根是:

    classdef SheetMusicGui < handle
    
        properties (Access = private)
            f  % Figure handle
            h  % Axes handle
    
            % Coordinates of the box
            topLineY    = 0.8;
            bottomLineY = 0.2;
    
            leftLineX   = 0.1;
            maxX        = 3;
        end
    
        methods
    
            function obj = SheetMusicGui(varargin)
    
                % Initialize figure and axis
                obj.f = figure; clf, hold on
                set(obj.f,...
                    'position', [400 400 900 300]);
    
                obj.h = gca;
                set(obj.h, ...
                    'box', 'on',...
                    'xtick',[], 'xticklabel',[],...
                    'ytick',[], 'yticklabel',[]);
    
                % Draw the grande staff
                obj.drawGrandeStaff(obj.h);
    
                % Make sure all measurements work out
                axis([0 3 0 1]);
            end
    
        end
    
        methods (Access = private)
    
            %% The Basics
    
            function [h] = drawGrandeStaff(obj, h)
    
                % First bar line
                line([obj.leftLineX obj.leftLineX], [obj.bottomLineY obj.topLineY], 'color', 'k');
    
                % Brace
                img = imread('brace.png');
    
                X = size(img,2);    xExtent = 0.068;
                Y = size(img,1);    yExtent = xExtent/X*Y;
    
                C = imagesc([0.01 0.01+xExtent],[0.8 0.8-yExtent],img, 'parent',obj.h);
                uistack(C, 'bottom'); % At the bottom prevents transparency issues
    
    
                % Treble staff
                line(...
                    repmat([obj.leftLineX; obj.maxX],1,5), ...
                    repmat(linspace(obj.topLineY, obj.topLineY-0.15, 5), 2,1), 'color','k')
                % Treble clef
                obj.drawTrebleClef(obj.leftLineX+0.04, obj.topLineY+0.05);
    
    
                % Bass staff
                line(...
                    repmat([obj.leftLineX; obj.maxX],1,5),...
                    repmat(linspace(obj.bottomLineY, obj.bottomLineY+0.15, 5), 2,1), 'color','k')
    
                % Bass clef
                obj.drawBassClef(obj.leftLineX+0.04, obj.bottomLineY+0.155);
    
            end
    
            % Draw a G clef at location X,Y
            function C = drawTrebleClef(obj, x, y)
                persistent img
                if isempty(img)
                    img = imread('GClef.png'); end
    
                % Scale image
                X = size(img,2);    xExtent = 0.1;
                Y = size(img,1);    yExtent = xExtent/X*Y;
    
                % Plage image
                C = imagesc([x x+xExtent],[y y-yExtent],img, 'parent',obj.h);
                uistack(C, 'bottom'); % At the bottom prevents transparency issues
    
            end
    
            % Draw an F clef at location X,Y
            function C = drawBassClef(obj, x, y)
                persistent img
                if isempty(img)
                    img = imread('FClef.png'); end
    
                % Scale image
                X = size(img,2);    xExtent = 0.12;
                Y = size(img,1);    yExtent = xExtent/X*Y;
    
                % Plage image
                C = imagesc([x x+xExtent],[y y-yExtent],img, 'parent',obj.h);
                uistack(C, 'bottom'); % At the bottom prevents transparency issues
    
            end
    
            function T = drawTime(obj, varargin)
    
                % TODO
    
                % NOTE: you had best use some pre-defined times, like common time,
                % 2/2, 3/4, 6/8, etc. It looks much nicer. Only use text() when a
                % non-common time is encountered.
            end
    
            function K = drawKey(obj, varargin)
                % TODO
                % NOTE: use sharp/flat below
            end
    
            %% Sharps, flats
    
            function T = drawSharp(obj, varargin)
                % TODO
            end
    
            function T = drawDoubleSharp(obj, varargin)
                % TODO
            end
    
            function T = drawFlat(obj, varargin)
                % TODO
            end
    
            function T = drawDoubleFlat(obj, varargin)
                % TODO
            end
    
            function T = drawNatural(obj, varargin)
                % TODO
            end
    
            %% Bars
    
            function B = drawBar(obj, varargin)
                % TODO
            end
    
            function R = drawBeginRepeat(obj, varargin)
                % TODO
            end
    
            function R = drawEndRepeat(obj, varargin)
                % TODO
            end
    
            %% Pedalling
    
            function P = drawBeginPedal(obj, varargin)
                % TODO
            end
    
            function P = drawEndPedal(obj, varargin)
                % TODO
            end
    
            %% Slurs & lines
    
            function S = drawSlur(obj, varargin)
                % TODO
                % NOTE: You'll have to do this one by hand
            end
    
            function P = drawGlissando(obj, varargin)
                % TODO
            end
    
            %% Multi-measure rest
    
            function R = drawMultiMeasureRest(obj, varargin)
                % TODO
            end
    
    
            %% Whole note/rest
    
            function N = drawWholeNote(obj, pitch, varargin)
    
                % TODO
    
                % Possibly transform note
                N = obj.transformNote(N, varargin{:});
            end
    
            function R = drawWholeRest(obj, varargin)
    
                % TODO
    
                % Possibly transform rest
                N = obj.transformNote(N, varargin{:});
            end
    
    
            %% Half note/rest
    
            function N = drawHalfNote(obj, varargin)
    
                % TODO
    
                % Possibly transform note
                N = obj.transformNote(N, varargin{:});
            end
    
            function R = drawHalfRest(obj, varargin)
    
                % TODO
    
                % Possibly transform rest
                N = obj.transformNote(N, varargin{:});
            end
    
    
            %% Quarter note/rest
    
            function N = drawQuarterNote(obj, varargin)
    
                % TODO
    
                % Possibly transform note
                N = obj.transformNote(N, varargin{:});
            end
    
            function R = drawQuarterRest(obj, varargin)
    
                % TODO
    
                % Possibly transform rest
                N = obj.transformNote(N, varargin{:});
            end
    
            %% 8th, 16th, 32nd, 64th, ...
    
            function N = drawSingleShortNote(obj, type, varargin)
    
                % TODO
    
                % NOTE: all short notes have a different number of tails. Just store
                % the tail as a separate figure, and copy however many times needed.
                % Use the quarter note for the head.
    
                % Possibly transform rest
                N = obj.transformNote(N, varargin{:});
            end
    
            function R = drawShortRest(obj, type, varargin)
    
                % TODO
    
                % NOTE: all short rests are just copies of the eighth rest, so you can
                % juse load one image and copy the desired number of times.
    
                % Possibly transform rest
                N = obj.transformNote(N, varargin{:});
            end
    
    
            function N = drawShortNoteGroup(obj, types, varargin)
    
                % TODO
    
                % NOTE: Use the quarter note for all the heads. Draw however many
                % lines (with "line" command) where needed. Top line should be
                % "fatter"; you can do this by adjusting the "linewidth" property
    
                % Possibly transform one or more members of the group
                N = obj.transformNote(N, varargin{:});
            end
    
    
            %% Note/Rest transformations
            % (dots, accents, inversion, decoration, etc.)
    
            function N = transformNote(obj, N, varargin)
    
                parameters = varargin(1:2:end);
                values     = varargin(2:2:end);
    
                if mod(nargin,2)~=0 || ...
                        ~all(cellfun('isclass', parameters), 'char') || ...
                        ~all(cellfun('isclass', values), 'char')
                    error('transformNotes:no_pv_pairs',...
                        'Transforming notes is done by all-text parameter/value pairs.'); 
                end
    
                if numel(parameters)==0
                    return; end
    
                for ii = 1:numel(parameters)
    
                    parameter = lower(parameters{ii});
                    value     = lower(values{ii});
    
                    switch parameter
    
                        % Note may be flipped
                        case 'orientation'
                            switch value
                                case {'upright' 'normal'}
                                    % No action 
                                case {'flip', 'flipped', 'upside down'} 
                                    N = flipdim(N,1);
                                otherwise
                                    % error
                            end
    
                        % Duration of note may be extended 
                        case {'extend' 'extension'}
                            switch value
                                case {'single' 'dot'}
                                case {'double' 'dotdot' 'dot dot' 'ddot'}
                                case {'triple' 'dotdotdot' 'dot dot dot' 'dddot'}
                                otherwise
                                    % error
                            end
    
    
                        % Note may be accented
                        case {'accent' 'accented'}
                            switch value
                                case 'portato'
                                case 'staccato'
                                case 'staccatissimo'
                                case 'legato'
                                case 'marcato'
                                case 'marcatissimo'
                                case 'tenuto'
                                otherwise
                                    % error
                            end
    
    
                        % Note may be decorated
                        case {'decoration' 'decorated'}
                            switch value
                                case {'thril' 'thriller'}
                                case {'pralthril' 'pralthriller' 'praller'}
                                case 'mordent'
                                case 'arpeggio'
                                case 'gruppetto'
                                case 'glissando'
                                case 'portamento'
                                case 'schleifer'
                                case {'grace note' 'appoggiatura'}
                                case {'striped grace note' 'acciaccatura'}
                                otherwise
                                    % error
                            end
    
                        otherwise
                            warning('transformNotes:unsupported_parameter',...
                                'Unknown parameter: ''%s''. Ignoring...', parameter);
                    end
                end
    
            end % transformNote
    
        end % Private methods
    
    end % Class definition
    
    classdef SheetMusicGui