ほぼあらゆる音をつくる方法(How to Make Almost Any Sound)

1.ライブラリ

1.1 ADSR関数
function e=ADSR(A,D,S,R,gate,duration)
e=zeros(1,duration);
if A~=0
    for n=1:A,
        e(n)=1-exp(-5*(n-1)/A);
    end
end
if D~=0
    for n=A+1:gate,
        e(n)=S+(1-S)*exp(-5*(n-1-A)/D);
    end
else
    for n=A+1:gate,
        e(n)=S;
    end  
end
if R~=0
    for n=gate+1:duration,
        e(n)=e(gate)*exp(-5*(n-gate+2)/R);
    end
end
1.2 IIR_LPF関数
function [b,a]=IIR_LPF(fc,Q)
fc=tan(pi*fc)/(2*pi);
a(1)=1+2*pi*fc/Q+4*pi*pi*fc*fc;
a(2)=(8*pi*pi*fc*fc-2)/a(1);
a(3)=(1-2*pi*fc/Q+4*pi*pi*fc*fc)/a(1);
b(1)=4*pi*pi*fc*fc/a(1);
b(2)=8*pi*pi*fc*fc/a(1);
b(3)=4*pi*pi*fc*fc/a(1);
a(1)=1;
1.3 IIR_HPF関数
function [b,a]=IIR_HPF(fc,Q)
fc=tan(pi*fc)/(2*pi);
a(1)=1+2*pi*fc/Q+4*pi*pi*fc*fc;
a(2)=(8*pi*pi*fc*fc-2)/a(1);
a(3)=(1-2*pi*fc/Q+4*pi*pi*fc*fc)/a(1);
b(1)=1/a(1);
b(2)=-2/a(1);
b(3)=1/a(1);
a(1)=1;
1.4 IIR_resonator関数
function [b,a]=IIR_resonator(fc,Q)
fc=tan(pi*fc)/(2*pi);
a(1)=1+2*pi*fc/Q+4*pi*pi*fc*fc;
a(2)=(8*pi*pi*fc*fc-2)/a(1);
a(3)=(1-2*pi*fc/Q+4*pi*pi*fc*fc)/a(1);
b(1)=2*pi*fc/Q/a(1);
b(2)=0;
b(3)=-2*pi*fc/Q/a(1);
a(1)=1;
1.5 Hanning_window関数
% Hanning_window.m
function w=Hanning_window(N)
w=zeros(1,N);
if mod(N,2)==0
    for n=1:N,
        w(n)=0.5-0.5*cos(2*pi*(n-1)/N);
    end 
else
    for n=1:N,
        w(n)=0.5-0.5*cos(2*pi*(n-0.5)/N);
    end 
end
1.6 sinc関数
function y=sinc(x)
if x==0.0
    y=1.0;
else
    y=sin(x)/x;
end

2.楽器音

2.1 グロッケンシュピール
2.2 トライアングル
(面内振動)
(面外振動)
2.3 チューブラーベル
2.4 マリンバ
2.5 シロフォン
2.6 ティンパニ
2.7 シンバル
2.8 銅鑼
2.9 ハイハットシンバル
2.10 バスドラム
2.11 タムドラム
2.12 スネアドラム
2.13 ピッコロ
2.14 フルート
2.15 クラリネット
2.16 サキソフォン
2.17 オーボエ
2.18 バスーン
2.19 トランペット
2.20 ホルン
2.21 トロンボーン
2.22 チューバ
2.23 バイオリン
2.24 ビオラ
2.25 チェロ
2.26 コントラバス
2.27 ハープ
2.28 アコースティックギター
2.29 エレクトリックギター
2.30 エレクトリックベース
2.31 パイプオルガン
2.32 リードオルガン
2.33 ハープシコード
2.34 アコースティックピアノ
2.35 エレクトリックピアノ

3.サウンドエフェクト

3.1 ディレイ
使用前(delay0.wav)

使用後(delay1.wav)

% delay1.m
clear;
fs=44100;
bits=16;

s0=wavread('delay0.wav');
length_of_s=length(s0);

s1=zeros(1,length_of_s);
a=0.8;
d=fs*0.375;
repeat=1;
for n=1:length_of_s,
    s1(n)=s0(n);
    for i=1:repeat,
        m=floor(n-i*d);
        if m>=1
            s1(n)=s1(n)+power(a,i)*s0(m);
        end
    end
end

sound(s1,fs);
wavwrite(s1,fs,bits,'delay1.wav');
3.2 リバーブ
使用前(reverb0.wav)

インパルス応答(impulse_response.wav)

使用後(reverb1.wav)

% reverb1.m
clear;
fs=44100;
bits=16;

s0=wavread('reverb0.wav');

b=wavread('impulse_response.wav',44100);
a(1)=1;
s1=filter(b,a,s0);

sound(s1,fs);
wavwrite(s1,fs,bits,'reverb1.wav');
3.3 トレモロ
使用前(tremolo0.wav)

使用後(tremolo1.wav)

% tremolo1.m
clear;
fs=44100;
bits=16;

s0=wavread('tremolo0.wav');
length_of_s=length(s0);

s1=zeros(1,length_of_s);
depth=0.8;
rate=8;
for n=1:length_of_s,
    a=1.0+depth*sin(2.0*pi*rate*(n - 1)/fs);
    s1(n)=a*s0(n);
end

sound(s1,fs);
wavwrite(s1,fs,bits,'tremolo1.wav');
3.4 ビブラート
使用前(vibrato0.wav)

使用後(vibrato1.wav)

% vibrato1.m
clear;
fs=44100;
bits=16;

s0=wavread('vibrato0.wav');
length_of_s=length(s0);

s1=zeros(1,length_of_s);
d=fs*0.025;
depth=fs*0.01;
rate=0.5;
for n=1:length_of_s,
    tau=d+depth*sin(2.0*pi*rate*(n-1)/fs);
    t=n-tau;
    m=floor(t);
    delta=t-m;
    if m>0 & m+1<=length_of_s
        s1(n)=s1(n)+delta*s0(m+1)+(1.0-delta)*s0(m);
    end
end

sound(s1,fs);
wavwrite(s1,fs,bits,'vibrato1.wav');
3.5 コーラス
使用前(chorus0.wav)

使用後(chorus1.wav)

% chorus1.m
clear;
fs=44100;
bits=16;

s0=wavread('chorus0.wav');
length_of_s=length(s0);

s1=zeros(1,length_of_s);
d=fs*0.025;
depth=fs*0.01;
rate=0.1;
for n=1:length_of_s,
    s1(n)=s0(n);
    tau=d+depth*sin(2.0*pi*rate*(n-1)/fs);
    t=n-tau;
    m=floor(t);
    delta=t-m;
    if m>0 & m+1<=length_of_s
        s1(n)=s1(n)+delta*s0(m+1)+(1.0-delta)*s0(m);
    end
end

sound(s1,fs);
wavwrite(s1,fs,bits,'chorus1.wav');
3.6 フランジャ(フィードバックなし)
使用前(flanger0.wav)

使用後(flanger1.wav)

% flanger1.m
clear;
fs=44100;
bits=16;

s0=wavread('flanger0.wav');
length_of_s=length(s0);

s1=zeros(1,length_of_s);
d=fs*0.003;
depth=fs*0.002;
rate=0.25;
for n=1:length_of_s,
    s1(n)=s0(n);
    tau=d+depth*sin(2.0*pi*rate*(n-1)/fs);
    t=n-tau;
    m=floor(t);
    delta=t-m;
    if m>0 & m+1<=length_of_s
        % no feedback
        s1(n)=s1(n)+delta*s0(m+1)+(1.0-delta)*s0(m);
    end
end

s1=s1/max(s1)*0.5;

sound(s1,fs);
wavwrite(s1,fs,bits,'flanger1.wav');
3.7 フランジャ(フィードバックあり)
使用前(flanger0.wav)

使用後(flanger2.wav)

% flanger2.m
clear;
fs=44100;
bits=16;

s0=wavread('flanger0.wav');
length_of_s=length(s0);

s1=zeros(1,length_of_s);
d=fs*0.003;
depth=fs*0.002;
rate=0.25;
for n=1:length_of_s,
    s1(n)=s0(n);
    tau=d+depth*sin(2.0*pi*rate*(n-1)/fs);
    t=n-tau;
    m=floor(t);
    delta=t-m;
    if m>0 & m+1<=length_of_s
        % feedback
        s1(n)=s1(n)+0.7*(delta*s1(m+1)+(1.0-delta)*s1(m));
    end
end

s1=s1/max(s1)*0.5;

sound(s1,fs);
wavwrite(s1,fs,bits,'flanger2.wav');
3.8 ラジオボイス
使用前(radiovoice0.wav)

使用後(radiovoice1.wav)

% radiovoice1.m
clear;
fs=44100;
bits=16;

s0=wavread('radiovoice0.wav');
length_of_s=length(s0);

s1=zeros(1,length_of_s);
I=2;
J=2;
fc=1000;
Q=10;
[b,a]=IIR_resonator(fc/fs,Q);
for n=1:length_of_s,
    for m=1:J+1,
        if n-m+1>0
            s1(n)=s1(n)+b(m)*s0(n-m+1);
        end
    end
    for m=2:I+1,
        if n-m+1>0
            s1(n)=s1(n)-a(m)*s1(n-m+1);
        end
    end
end

s1=s1/max(s1)*0.5;

sound(s1,fs);
wavwrite(s1,fs,bits,'radiovoice1.wav');
3.9 ワウ
使用前(wah0.wav)

使用後(wah1.wav)

% wah1.m
clear;
fs=44100;
bits=16;

s0=wavread('wah0.wav');
length_of_s=length(s0);

s1=zeros(1,length_of_s);
I=2;
J=2;
depth=800;
rate=2;
for n=1:length_of_s,
    fc=1000+depth*sin(2*pi*rate*(n-1)/fs);
    Q=2;
    [b,a]=IIR_resonator(fc/fs,Q);
    for m=1:J+1,
        if n-m+1>0
            s1(n)=s1(n)+b(m)*s0(n-m+1);
        end
    end
    for m=2:I+1,
        if n-m+1>0
            s1(n)=s1(n)-a(m)*s1(n-m+1);
        end
    end
end

s1=s1/max(s1)*0.5;

sound(s1,fs);
wavwrite(s1,fs,bits,'wah1.wav');
3.10 ボコーダ
音声(vocal.wav)

楽器音(synth.wav)

ロボットボイス(vocoder1.wav)

% vocoder1.m
clear;
fs=44100;
bits=16;

s0=wavread('synth.wav');
s1=wavread('vocal.wav');
length_of_s=length(s0);

s2=zeros(1,length_of_s);

d=zeros(1,length_of_s);
d(1)=0;
for n=2:length_of_s,
    d(n)=s1(n)-0.98*s1(n-1);
end
for n=1:length_of_s,
    s1(n)=d(n);
end

N=1024;

x=zeros(1,N);
b=zeros(1,N);
w=Hanning_window(N);
Y=zeros(1,N);

number_of_frame=floor((length_of_s-N/2)/(N/2));

band_width=8;
number_of_band=N/2/band_width;

for frame=1:number_of_frame,
    offset=N/2*(frame-1);
    for n=1:N,
        x(n)=s0(offset+n)*w(n);
    end
    X=fft(x,N);
    for n=1:N,
        b(n)=s1(offset+n)*w(n);
    end
    B=fft(b,N);
    
    for k=1:N,
        B(k)=abs(B(k));
    end
    for band=1:number_of_band,
        offset=band_width*(band-1);
        a=0;
        for k=1:band_width,
            a=a+B(offset+k);
        end
        a=a/band_width;
        for k=1:band_width,
            B(offset+k)=a;
        end
    end
    B(1)=0;
    B(N/2+1)=0;
    for k=2:N/2,
        B(N-k+2)=B(k);
    end
    
    for k=1:N,
        Y(k)=X(k)*B(k);
    end
    y=real(ifft(Y,N));
    
    offset=N/2*(frame-1);
    for n=1:N,
        s2(offset+n)=s2(offset+n)+y(n);
    end
end

s2=s2/max(s2)*0.5;

sound(s2,fs);
wavwrite(s2,fs,bits,'vocoder1.wav');
3.11 ディストーション(対称クリッピング)
使用前(distortion0.wav)

使用後(distortion1.wav)

% distortion1.m
clear;
fs=8000;
bits=16;

s0=wavread('distortion0.wav');
length_of_s=length(s0);

s1=zeros(1, length_of_s);
gain=100;
level=0.1;
for n=1:length_of_s,
    s1(n)=s0(n)*gain;
    if s1(n)>=1
        s1(n)=1;
    elseif s1(n)<=-1
        s1(n)=-1;
    end
    s1(n)=s1(n)*level;
end

sound(s1,fs);
wavwrite(s1,fs,bits,'distortion1.wav');
3.12 ディストーション(半波整流)
使用前(distortion0.wav)

使用後(distortion2.wav)

% distortion2.m
clear;
fs=8000;
bits=16;

s0=wavread('distortion0.wav');
length_of_s=length(s0);

s1=zeros(1, length_of_s);
gain=10;
level=0.2;
for n=1:length_of_s,
    s1(n)=s0(n)*gain;
    if s1(n)>=1
        s1(n)=1;
    elseif s1(n)<0
        s1(n)=0;
    end
    s1(n)=s1(n)*level;
end

sound(s1,fs);
wavwrite(s1,fs,bits,'distortion2.wav');
3.13 ディストーション(全波整流)
使用前(distortion0.wav)

使用後(distortion3.wav)

% distortion3.m
clear;
fs=8000;
bits=16;

s0=wavread('distortion0.wav');
length_of_s=length(s0);

s1=zeros(1, length_of_s);
gain=10;
level=0.2;
for n=1:length_of_s,
    s1(n)=abs(s0(n))*gain;
    if s1(n)>=1
        s1(n)=1;
    end
    s1(n)=s1(n)*level;
end

sound(s1,fs);
wavwrite(s1,fs,bits,'distortion3.wav');
3.14 ピッチシフタ
使用前(pitchshifter0.wav)

使用後(pitchshifter1.wav)

% pitchshifter1.m
clear;
fs=44100;
bits=16;

s0=wavread('pitchshifter0.wav');
length_of_s0=length(s0);

rate=0.5; % 0.5 <= rate < 1.0

length_of_s1=ceil(length_of_s0/rate);
s1=zeros(1,length_of_s1);

template_size=floor(fs * 0.01); % 10 ms
pmin=floor(fs * 0.005); % 5 ms
pmax=floor(fs * 0.02); % 20 ms

x = zeros(1,template_size);
y = zeros(1,template_size);
r=zeros(1,pmax+1);

offset0=0;
offset1=0;

while offset0+pmax*2<=length_of_s0,
    for n=1:template_size,
        x(n)=s0(offset0+n);
    end
    rmax=0;
    p=pmin;
    for m=pmin:pmax,
        for n=1:template_size,
            y(n)=s0(offset0+m+n);
        end
        r(m)=0;
        for n=1:template_size,
            r(m)=r(m)+x(n)*y(n);
        end
        if r(m)>rmax
            rmax=r(m);
            p=m;
        end
    end
    for n=1:p,
        s1(offset1+n)=s0(offset0+n);
    end
    for n=1:p,
        s1(offset1+p+n)=s0(offset0+p+n)*(p-n)/p;
        s1(offset1+p+n)=s1(offset1+p+n)+s0(offset0+n)*n/p;
    end
    q=round(p*rate/(1-rate));
    for n=p+1:q,
        if offset0+n>length_of_s0
            break;
        end
        s1(offset1+p+n)=s0(offset0+n);
    end
    offset0=offset0+q;
    offset1=offset1+p+q;
end

pitch=1/rate;

length_of_s2=length_of_s0;
s2=zeros(1,length_of_s0);

N=16;

for n=1:length_of_s2,
    t=pitch*n;
    ta=floor(t);
    if t==ta
        tb=ta;
    else
        tb=ta+1;
    end
    for m=tb-N/2:ta+N/2,
        if m>0 & m<=length_of_s1
            s2(n)=s2(n)+s1(m)*sinc(pi*(t-m))*(0.5+0.5*cos(2*pi*(t-m)/(N*2+1)));
        end
    end
end

sound(s2,fs);
wavwrite(s2,fs,bits,'pitchshifter1.wav');

メディアネットワーク実験

サウンドプログラミング1
サウンドプログラミング2

Facebookページ

https://www.facebook.com/almostanysound

参考文献

青木 直史, ``ゼロからはじめる音響学,'' 講談社, 2014.
青木 直史, ``サウンドプログラミング入門 - 音響合成の基本とC言語による実装 - ,'' 技術評論社, 2013.
青木 直史, ``C言語ではじめる音のプログラミング - サウンドエフェクトの信号処理 - ,'' オーム社, 2008.
青木 直史, ``ディジタル・サウンド処理入門 - 音のプログラミングとMATLAB(Octave・Scilab)における実際 - ,'' CQ出版社, 2006.

Last Modified: July 5 12:00 JST 2015 by Naofumi Aoki
E-mail: aoki@ime.ist.hokudai.ac.jp