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