數字信號處理Day1自制電子音樂

第一天的課程感覺比較簡單,主要介紹Karplus-Strong Algorithm

給出方程 y[n]=αy[nM]+x[n],                         

x[n]是輸入,M是延遲,α是衰弱係數

我們要衰減D次,總的採樣數就是D*M


下面是最直接的實現

關於x = x(:).';的語法是這樣的,這是一個轉置,但是是非共軛轉置,如果是x',那麼1+i就成了1-i

function y = ks_loop(x, alpha, D)

% Length of the output signal must be larger than the length of the input signal,
% that is, D must be larger than 1 
if D < 1   
    error('Duration D must be greater than 1');
end    
    
% Make sure the input is a row-vector
x = x(:).';

% Number of input samples
M = length(x);

% Number of output samples
size_y = D * M;

% Initialize with random input x
y = zeros(1, size_y);
y(1:M) = x;

for index = (M+1):size_y
    y(index) = alpha * y(index - M);
end

y = y(:);

return


下面來測試一下

x = randn(100, 1);

stem(x);


y = ks_loop(x, 0.9, 10);

stem(y);


其實,你已經完成了KS算法

要知道,在matlab和octave這樣的軟件中,矩陣運算比單個運算速度要快很多,於是就有了優化的版本


function y = ks(x, alpha, D)
    
% Length of the output signal must be larger than the length of the input signal,
% that is, D must be larger than 1 
if D < 1   
    error('Duration D must be greater than 1.');
end  
    
% Make sure the input is a row-vector 
x = x(:).';

% Number of input samples
M = length(x);

% number of output samples
size_y = D * M;

% Create a vector of the powers of alpha, [alpha^0 alpha^1 ....]
size_alphaVector = D;
alphaVector = (alpha*ones(size_alphaVector,1)).^((0:(size_alphaVector-1))');

% Create a matrix with M columns, each being the vector of the powers of alpha
alphaMatrix = repmat(alphaVector, 1, M);

% Create a matrix with D rows filled by the input signal x   
xMatrix = repmat(x, D, 1);

% Multipliy the two, and take the transpose so we can read it out
% column-by-column
yMatrix = (alphaMatrix .* xMatrix).';

% Read out the output column by columnn
y = yMatrix(:);

return

在matlab中,你可以用soundsc(y, FS)來播放音樂

y是我們的採樣數據,FS是頻率

下面這個例子可以播放opening chord of Hard day's night 開頭的音樂,太神奇了

因爲牽扯到音樂的相關知識,一些參數就不大懂,只畫出了最後的採樣圖看看


clear all
close all
clc

% Parameters:
%
% - Fs       : sampling frequency
% - F0       : frequency of the notes forming chord
% - gain     : gains of individual notes in the chord
% - duration : duration of the chord in second
% - alpha    : attenuation in KS algorithm

Fs = 48000;

% D2, D3, F3, G3, F4, A4, C5, G5
F0 = 440*[2^-(31/12); 2^-(19/12); 2^-(16/12); 2^(-14/12); 2^-(4/12); 1; 2^(3/12); 2^(10/12)];
gain = [1.2 3.0 1.0 2.2 1.0 1.0 1.0 3.5];
duration = 4;
alpha = 0.9785;

% Number of samples in the chord
nbsample_chord = Fs*duration;

% This is used to correct alpha later, so that all the notes decay together
% (with the same decay rate)
first_duration = ceil(nbsample_chord / round(Fs/F0(1)));

% Initialization
chord = zeros(nbsample_chord, 1);

for i = 1:length(F0)
    
    % Get M and duration parameter
    current_M = round(Fs/F0(i));
    current_duration = ceil(nbsample_chord/current_M);

    % Correct current alpha so that all the notes decay together (with the
    % same decay rate)
    current_alpha = alpha^(first_duration/current_duration);

    % Let Paul's high D on the bass ring a bit longer
    if i == 2
        current_alpha = current_alpha^.8;
    end

    % Generate input and output of KS algorithm
    x = rand(current_M, 1);
    y = ks(x, current_alpha, current_duration);
    y = y(1:nbsample_chord);
        
    % Construct the chord by adding the generated note (with the
    % appropriate gain)
    chord = chord + gain(i) * y;
end

% Play output
soundsc(chord, Fs);


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章