我正在写一首播放歌曲的MATLAB函数(权力的游戏主题)。
我有正确的按键和持续时间。我试图让两个(高音和低音)一次播放,每次击键都是正确的持续时间。出于某种原因,我无法获得使用击键的持续时间(它们都在持续时间= 1)或两组一起进行。有任何想法吗?
function xx = key2note(X, keynum, dur)
% KEY2NOTE Produce a sinusoidal waveform corresponding to a given piano key number
% usage: xx = key2note (X, keynum, dur)
% xx = the output sinusoidal waveform
% X = complex amplitude for the sinusoid, X = A*exp(j*phi).
% keynum = the piano keyboard number of the desired note
% dur = the duration (in seconds) of the output note
fs = 8000;
tt = (1/fs):(1/fs):dur;
freq = 440*(2^((keynum-49)/12)); %<=============== fill in this line
xx = real(X*exp(j*2*pi*freq*tt)); %<=============== fill in this line
end
t = 0.17;
%treble - 40 is middle C
throne.keys = [47 40 43 45, 47 40 43 45, 47 40 43 45, 47 40 43 45, 47 40 44 45, 47 40 44 45, 47 40 44 45, 47 40 44 45, 47, 40, 40 45 47, 40 43 45, 42 47 36 40];
throne.dur = [ 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 4, 4, 1 1 2 1, 2 1 1, 1 1 1 1];
%bass
throne.keys2 = [ 21, 21 25 28 31 28 25, 21 25 28 31 28 25];
throne.dur2 = [ 32, 1/3 1/3 1/3 1/3 1/3 1/3, 1/3 1/3 1/3 1/3 1/3 1/3];
throne.durations = 0.2 * ones(1,length(throne.dur));
fs = 8000; % 11025 Hz also works
f = 329.62;
xx = zeros(1, sum(throne.dur)*fs + length(throne.keys));
n1 = 1;
for kk = 1:length(throne.keys)
keynum = throne.keys(kk);
tone = key2note(1,keynum,0.25); %amplitude 1, keynum, 0.38s % <------- Fill in this line
n2 = n1 + length(tone) - 1;
xx(n1:n2) = tone; %<------- Insert the note
n1 = n2 + 1;
end
fs = 8000;
%xt = zeros(1, sum(tdur)*fs + length(keyst));
%xb = zeros(1, sum(bdur)*fs + 1);
%xa = zeros(1, sum(adur)*fs+1);
%xd = zeros(1, sum(ddur)*fs+1);
%xx = xt + xb + xa + xd
xx = xt + xb;
soundsc(xx,fs)
答案 0 :(得分:0)
我评论了一些从未使用过的行 - 你可能想要取消注释它们,如果它们以后用于别的东西。我也感到很自由,以使t
成为全球速度控制。
t = 0.17; % this variable was never used.
%I assumed you wanted to control the overall speed with it and felt so free to adjust the durations with it.
%treble - 40 is middle C
throne.keys = [47 40 43 45, 47 40 43 45, 47 40 43 45, 47 40 43 45, 47 40 44 45, 47 40 44 45, 47 40 44 45, 47 40 44 45, 47, 40, 40 45 47, 40 43 45, 42 47 36 40];
throne.dur = t*[ 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 1 1 0.5 0.5, 4, 4, 1 1 2 1, 2 1 1, 1 1 1 1];
%bass
throne.keys2 = [ 21, 21 25 28 31 28 25, 21 25 28 31 28 25];
throne.dur2 = t*[ 32, 1/3 1/3 1/3 1/3 1/3 1/3, 1/3 1/3 1/3 1/3 1/3 1/3];
%throne.durations = 0.2 * ones(1,length(throne.dur)); % this was never used - no clue what you intended to do with it
fs = 8000; % 11025 Hz also works
%f = 329.62; % is also never used
%treble loop
xt = zeros(1, ceil(sum(throne.dur)*fs + length(throne.keys)));
n1 = 1;
for kk = 1:length(throne.keys)
tone = key2note(1,throne.keys(kk),throne.dur(kk)); % You used here the constant length of 0.25 instead of taking the duration value from throne.dur
n2 = n1 + length(tone) - 1;
xt(n1:n2) = tone; %<------- Insert the note
n1 = n2 + 1;
end
%Bass loop
xb = zeros(1, ceil(sum(throne.dur2)*fs + length(throne.keys2)));
n1 = 1;
for kk = 1:length(throne.keys2)
tone2 = key2note(1,throne.keys2(kk),throne.dur2(kk));
n2 = n1 + length(tone2) - 1;
xb(n1:n2) = tone2; %<------- Insert the note
n1 = n2 + 1;
end
xb(length(xb)+1:length(xt)) = 0; %bass voice has a much shorter duration currently - padding to same size as xt with 0's at the end.
%If you add more voices, you have to pad them all to the length of the longest one.
%xt = zeros(1, sum(tdur)*fs + length(keyst));
%xb = zeros(1, sum(bdur)*fs + 1);
%xa = zeros(1, sum(adur)*fs+1);
%xd = zeros(1, sum(ddur)*fs+1);
%xx = xt + xb + xa + xd
xx = xt + xb;
soundsc(xx,fs)
当然你可以在某处下载主题曲并使用[y,Fs] = audioread(filename)
进行转换。但这远远不如你正在做的那么酷。