from PlayTune by Alan Tan
This function plays musical tunes. Write your own musical tune and call the function to play it.

playtune(str,cf,cb)
function x = playtune(str,cf,cb)
% Play musical tune.
% [x] = playtune(str,[cf],[cb])
%
% Notation:
% [CDEFGAB] keys, 5 full octaves
% [12345678] key/rest duration,
% with the default [1] semiquaver, [2] quaver, [4] crochet and [8] minim
% [#] sharp / [b] flat / [.] rest / [^] raise octave / [_] lower octave
%
% Examples:
% C major            -- playtune('^2CDEFGAB^C_BAGFEDC');
% F major            -- playtune('^2FGABb^CDEFEDC_BbAGF');
% B minor (harmonic) -- playtune('^2B^C#DEF#GA#BA#GF#EDC#_B');
% F# minor (melodic) -- playtune('^2F#G#AB^C#D#E#F#EDC#_BAG#F#');
% Doe-a-deer         -- playtune('^^6C2D6E2C4EC8E6D2EFFED8F.');
%
% Advanced features:
% CF is a (N,2) matrix where the first column contains the frequency and
%   the second column the corresponding scaling coefficient. The simplest
%   choice of CF would be cf = [1 1] which generates a pure sine wave. The
%   default CF is cf = [1 1; 1.001 0.33; 1.002 0.2; 0.999 0.33; 0.998 0.2]
%   which generates a tone resembling the flute.
% CB is a (1,9) vector containing the duration of that particular symbol (1-9).
%
% v2.0, Alan Tan (weechiat@gmail.com) 

if nargin < 2 | isempty(cf), cf = [1 1; 1.001 0.33; 1.002 0.2; 0.999 0.33; 0.998 0.2]; end
if nargin < 3 | isempty(cb), cb = [1:9]; end

% Set constants.
Fc = 65.4064;
Fs = 2^13;
Ts = 1/Fs;
Td = 0.1;
c1 = 2*pi*Fc;
c2 = 2.^([0:60]/12);

% Convert string to score.
d                   = -ones(1,length(str));
d(find(str == 'C')) = 0;
d(find(str == 'D')) = 2;
d(find(str == 'E')) = 4;
d(find(str == 'F')) = 5;
d(find(str == 'G')) = 7;
d(find(str == 'A')) = 9;
d(find(str == 'B')) = 11;
d(find(str == '^')) = 0;
d(find(str == '_')) = 0;
d(find(str == '.')) = 0;
u1                  = find(str == 'b');
d(u1-1)             = d(u1-1)-1;
u2                  = find(str == '#');
d(u2-1)             = d(u2-1)+1;
str([u1,u2])        = [];
d([u1,u2])          = [];

% Construct vector.
x  = [];
oc = 1;
Tu = Td;
t  = [Ts:Ts:Tu];
L  = length(t);
th = zeros(size(cf,1),1);
for k = 1:length(str)
   if d(k) == -1
      Tu = cb(str(k)-48)*Td;
      t  = [Ts:Ts:Tu];
      L  = length(t);
   else
      switch str(k),
      case '^',  oc       = oc+12;
      case '_',  oc       = oc-12;
      case '.',  x(end+L) = 0;
      otherwise
         wt           = c1*c2(oc+d(k))*t;
         x(end+(1:L)) = transpose(cf(:,2))*sin(cf(:,1)*wt+th(:,ones(1,L)));
         th           = rem(cf(:,1)*wt(end)+th,2*pi);
      end
   end
end

% Set output.
if ~nargout
   soundsc(x,Fs);
   clear x;
end

Contact us at files@mathworks.com