使用Karplus-Strong算法生成吉他和弦
这个例子展示了如何使用Karplus-Strong算法和离散时间滤波器生成真实的吉他和弦。
设置
首先定义我们稍后将使用的变量,例如采样频率,A弦的第一次谐波频率,每个弦相对于A弦的偏移量。
Fs = 44100;A = 110;吉他的A弦通常调到110赫兹Eoffset = -5;偏移量= 5;Goffset = 10;Boffset = 14;E2offset = 19;
生成用于分析的频率向量。
F = linspace(1/Fs, 1000,2 ^12);
生成4秒的零,用于生成吉他音符。
x = 0 (Fs* 4,1);
在开弦上演奏一个音符
当吉他弦被拨动或拨动时,它会产生一种在频域内具有等距峰值的声波。这些被称为谐波,它们使每个音符发出完整的声音。我们可以用离散时间滤波器对象用这些谐波产生声波。
根据第一次谐波频率确定反馈延迟。
延迟=轮(Fs/A);
生成一个IIR滤波器,其极点近似于A弦的谐波。零被添加到细微的频域整形。
B = firls(42,[0 1/延迟2/延迟1],[0 0 1 1]);A =[1 0(1,延迟)-0.5 -0.5];
显示滤波器的幅值响应。
[H,W] = freqz(b, a, F, Fs);情节(W, 20 * log10 (abs (H)));标题(开放A弦的谐波);包含(的频率(赫兹));ylabel (“(dB)级”);
为了生成一个4秒的合成音符,我们首先用随机数创建一个状态向量。然后我们用这些初始状态来过滤零。这迫使随机状态退出形成谐波的滤波器。
Zi = rand(max(length(b),length(a))-1,1);注= filter(b, a, x, zi);
规范化音频播放器的声音。
Note = Note -mean(Note);Note = Note /max(abs(Note));%听,输入:hplayer = audioplayer(注,Fs);玩(hplayer)
在动弦上演奏一个音符
吉他琴颈上的每一个琴纹都可以让演奏者奏出更高的半音,或者是一个第一个和声的音符 更高。
Fret = 4;delay = round(Fs/(A*2^(fret/12)));B = firls(42,[0 1/延迟2/延迟1],[0 0 1 1]);A =[1 0(1,延迟)-0.5 -0.5];[H,W] = freqz(b, a, F, Fs);持有在情节(W, 20 * log10 (abs (H)));标题(A弦的谐波);传奇(打开一个字符串,“四烦躁的弦”);
用随机数填充状态。
Zi = rand(max(length(b),length(a))-1,1);
做一个4秒的笔记。
注= filter(b, a, x, zi);
规范化音频播放器的声音。
Note = Note -mean(Note);Note = Note /max(Note);%听,输入:hplayer = audioplayer(注,Fs);玩(hplayer)
弹奏和弦
和弦是一起演奏的一组音符,它们的谐波相互加强。这种情况发生在两个音符之间有一个很小的整数比率时,例如,2/3的比率意味着第一个音符的三次谐波将与第二个音符的二次谐波对齐。
定义G大调和弦的微动。
烦躁= [3 2 0 0 0 3];
根据微扰和字符串偏移量获取每个音符的延迟。
延迟= [round(Fs/(A*2^((fret(1)+Eoffset)/12))),...轮(Fs / (A * 2 ^(担心(2)/ 12))),...轮(Fs / (A * 2 ^((担心(3)+ Doffset) / 12))),...轮(Fs / (A * 2 ^((担心(4)+ Goffset) / 12))),...轮(Fs / (A * 2 ^((担心(5)+ Boffset) / 12))),...轮(Fs / (A * 2 ^((担心(6)+ E2offset) / 12))));B = cell(length(delay),1);A = cell(length(delay),1);H = 0(长度(延迟),4096);注= 0(长度(x),长度(延迟));为Indx = 1:长度(延迟)建立分子和分母系数的单元格数组。B {indx} = firls(42, [0 1/delay(indx) 2/delay(indx) 1], [0 0 1 1]).';A {indx} = [1 0 (1, delay(indx)) -0.5 -0.5].';用随机数填充状态并过滤输入零。子=兰德(max(长度(b {indx}), ({indx})) 1, 1);注(:,indx) = filter(b{indx}, a{indx}, x, zi);确保每个音符都以零为中心。。备注(:,indx) =注意(:,indx)意味着(注意(:,indx));[H(indx,:),W] = freqz(b{indx}, a{indx}, F, Fs);结束
显示和弦中所有音符的大小。
hline = plot(W,20*log10(abs(H.')));标题(“G大调和弦的和声”);包含(的频率(赫兹));ylabel (“(dB)级”);传奇(线,‘G’,“B”,' D ',‘G’,“B”,“G2”);
把这些笔记结合起来,使之规范化。
combinedNote = sum(note,2);combinedNote = combinedNote/max(abs(combinedNote));%听,输入:hplayer = audioplayer(combinedNote, Fs);玩(hplayer)
添加一个拨弦效果
要添加拨动效果,我们只需抵消之前创建的每个音符。
将字符串之间的偏移量定义为50毫秒。
偏移量= 50;offset = ceil(offset*Fs/1000);
在每个音符之间加上50毫秒的零前置。
为Indx = 1:size(note, 2) note(:, Indx) =[零(offset*(index -1),1);...注意((1:结束偏移量* (indx-1)), indx)];结束combinedNote = sum(note,2);combinedNote = combinedNote/max(abs(combinedNote));%听,输入:hplayer = audioplayer(combinedNote, Fs);玩(hplayer)