Interactive Music II
SuperCollider入門 4 楽器を定義、変調合成(RM, AM, FM)
2013年10月24日
東京藝術大学芸術情報センター(AMC)
田所 淳
今日の内容
‣ 先週の続き - 楽器を定義する
‣ SynthDef について

!
‣ SuperColliderによる音響合成入門
‣ 変調合成:
‣ RM - リング変調
‣ AM - 振幅変調
‣ FM - 周波数変調
「楽器」を定義する - SynthDef
「楽器」を定義する - SynthDef
‣ これまで使用してきた、{ }.play; という形式
‣ 一時的に、楽器(Synth)を生成し、それをSC Serverに送って出
力していた

!
‣ 例えば、SinOscを使用した際のPost Windowの出力
//! {}.playによる出力
{SinOsc.ar}.play;
!

!

//! Post Windowの表示
Synth("temp__146" : 1000)
!

!
‣ これは、 temp__146 という名前の楽器を生成していた
「楽器」を定義する - SynthDef
‣ SynthDef - 楽器を定義する
‣ SynthDef( 楽器の名前 , { Ugen関数 });

!
‣ 先程の簡単な関数によるプログラムをSynthDef形式へ

!
!
{SinOsc.ar}.play;
!!
// SyntDefに変換
!
SynthDef("sine", {Out.ar(0,
SynthDef("sine", {Out.ar(1,
!
!
// {}.playによる出力

SinOsc.ar)}).play; //left
SinOsc.ar)}).play; //right

‣ SynthDefの最終出力は、必ずOutオブジェクトに渡さなければ
ならない (PdやMax/MSPの「dac 」のようなもの)
‣ Out.ar( バス番号, 出力信号);
「楽器」を定義する - SynthDef
‣ SynthDef、もう少し複雑な例
//関数による記述
{ SinOsc.ar(440, 0, 0.2) }.play;

!

//SynthDefをサーバーに追加
SynthDef.new("test-SinOsc", {
Out.ar(0, SinOsc.ar(440, 0, 0.2))
}).add;

!

//Synthを演奏
Synth("test-SinOsc");
「楽器」を定義する - SynthDef
‣ SynthDef は、引数 (Arguments) を渡せる
//SynthDefの定義(引数あり)
SynthDef.new("test-SinOsc", {
arg freq = 440, amp = 0.2;
Out.ar(0, SinOsc.ar(freq, 0, amp))
}).add;

!

//Synthを演奏
a = Synth("test-SinOsc"); //440Hz
b = Synth("test-SinOsc", [freq:660]); //660Hz
c = Synth("test-SinOsc", [freq:880, amp:0.5]); //880Hz, amp:0.5

!

a.set("freq", 330); //440Hz -> 330Hz
b.set("freq", 220, "amp", 0.3); //660Hz -> 220Hz, amp: 0.3

!

//終了
a.free; b.free; c.free;
SuperColliderによる音響合成
変調合成1- RMとAM
変調合成1- RMとAM
‣ 変調合成 (Modulation synthesis)

!
‣ ある信号のパラメータを、もう1つの信号で変更することで行
う音響合成の手法

!
‣ 変更される信号 → キャリア(Carrier)
‣ 変更する信号 → モジュレーター(Modulator)
変調合成1- RMとAM
‣ キャリアの何を変調するかによって、異なる特性をもった音響
合成が可能

!
‣ 音量を変調: リング変調(RM)、振幅変調(AM)
‣ 周波数を変調: 周波数変調(FM)
変調合成1- RMとAM
‣ RMとAM合成のダイアグラム
freq

amp

freq

Carrier

amp

Modulator

x
変調合成1- RMとAM
‣ AM、RM: モジュレータのオシレータでキャリアの音量を変調
‣ 高速のビブラートとも言えるでしょう。

!
‣ AMとRMの原理はとても良く似ている
‣ その差は、モジュレータの変化の範囲によって決まる

!
‣ AM: モジュレーターの振幅 0.0∼1.0
‣ RM: モジュレーターの振幅 -1.0∼1.0
変調合成1- RMとAM
‣ RMとAMの波形
変調合成1- RMとAM
‣ 参考: PureDataでは
変調合成1- RMとAM
‣ RM合成の例
// RM変調
SynthDef.new("test-rm",{
var car, mod, rm;
mod = SinOsc.ar(880, 0, 1.0);
car = SinOsc.ar([440,442], 0, 0.5);
rm = car * mod;
Out.ar(0, rm);
}).play;

!
!

// RM変調2 - マウスでModulatorの周波数を変更
SynthDef.new("test-rm",{
var car, mod, rm;
mod = SinOsc.ar(MouseX.kr(1, 4000, 1), 0, 1.0);
car = SinOsc.ar([440,442], 0, 0.5);
rm = car * mod;
Out.ar(0, rm);
}).play;
変調合成1- RMとAM
‣ RM合成の例 - 2
// RM変調3 - 2つのModulator
SynthDef.new("test-rm",{
var car, mod1, mod2, rm;
car = SinOsc.ar(440, 0, 0.5);
mod1 = SinOsc.ar(MouseX.kr(1, 4000, 1), 0, 1.0);
mod2 = SinOsc.ar([6.1,7.9].reciprocal);
rm = car * (mod1 * mod2);
Out.ar(0, rm);
}).play;
変調合成1- RMとAM
‣ 次に同じような合成を、AMで実現してみる
‣ 音はどのように変化するか?
変調合成1- RMとAM
‣ AM合成の例
// AM変調
SynthDef.new("test-am",{
var car, mod, rm;
mod = SinOsc.ar(MouseX.kr(1, 4000, 1), 0, 0.5, 0.5);
car = SinOsc.ar([440,442], 0, 0.5);
rm = car * mod;
Out.ar(0, rm);
}).play;

!

SynthDef.new("test-am",{
var car, mod1, mod2, rm;
car = SinOsc.ar(440, 0, 0.5);
mod1 = SinOsc.ar(MouseX.kr(1, 4000, 1), 0, 0.5, 0.5);
mod2 = SinOsc.ar([8,7].reciprocal);
rm = car * (mod1 * mod2);
Out.ar(0, rm);
}).play;
変調合成1- RMとAM
‣ AM合成のパラメータをノイズ(LFNoise1)で変化させる
// AM + LFNoise
(
SynthDef.new("rand-am",{
arg freq = 440, amp = 0.5, modFreq = 400;
var car, mod1, mod2, rm;
car = SinOsc.ar(freq, 0, amp);
mod1 = SinOsc.ar(LFNoise1.kr(5.reciprocal, modFreq), pi.rand, 0.5, 0.5);
mod2 = SinOsc.ar(LFNoise1.kr([8,7].reciprocal).abs);
rm = car * (mod1 * mod2);
Out.ar(0, rm);
}).add;
)

!

(
Synth("rand-am",
Synth("rand-am",
Synth("rand-am",
Synth("rand-am",
Synth("rand-am",
)

["freq",
["freq",
["freq",
["freq",
["freq",

110, "amp", 0.2, "modFreq", 1200]);
220, "amp", 0.2, "modFreq", 200]);
440, "amp", "modFreq", 200]);
880, "amp", 0.2, "modFreq", 100]);
1780, "amp", 0.05, "modFreq", 20]);
変調合成1- RMとAM
‣ RMとAMの周波数分布の違い
SuperColliderによる音響合成
変調合成2 - FM
変調合成2 - FM
‣ FM - 周波数の変調
‣ FMを利用した音響合成
‣ ジョン・チョウニングを中心としてスタンフォード大学の
CCRMA(Center for Computer Research in Music and
Acoustics)で1973年開発
‣ その後ヤマハにライセンス
変調合成2 - FM
‣ YAMAHA DX7 (1983)
変調合成2 - FM
‣ FM合成の特徴
‣ たった3つのパラメータで、驚くほど多様なサウンドを実現

!
‣ C - Carrier:キャリア周波数
‣ M - Modulator : モジュレータ周波数
‣ I - Index:モジュレータの振幅
変調合成2 - FM
‣ FM合成のダイアグラム
Mod Index

Mod
Car

+

amp

Car
変調合成2 - FM
‣ 参考: Pd では
変調合成2 - FM
‣ Index の大きさによる周波数成分の変化
変調合成2 - FM
‣ FM基本
//FM基本
SynthDef.new("test-fm",{
arg cfreq = 440, mfreq = 111, index = 200;
var car, mod;
mod = SinOsc.ar(mfreq, 0, index);
car = SinOsc.ar([cfreq, cfreq*1.005] + mod, 0, 0.5);
Out.ar(0, car);
}).play;
変調合成2 - FM
‣ Mod Freq と Index をマウスで操作
//FMマウスで操作
SynthDef.new("test-fm",{
var car, mod;
mod = SinOsc.ar(MouseX.kr(1, 1000, 1), 0,
MouseY.kr(1, 10000, 1));
car = SinOsc.ar([440,442] + mod, 0, 0.5);
Out.ar(0, car);
}).play;
変調合成2 - FM
‣ FM応用1
(
SynthDef("fm1", { arg freq = 440, detune = 2, carPartial = 1,
modPartial = 1, index = 3, mul = 0.2;
var mod, car;
mod = SinOsc.ar(
[freq, freq+detune] * modPartial, 0,
freq * index * LFNoise1.kr(10.reciprocal).abs
);
car = SinOsc.ar((freq * carPartial) + mod, 0, mul);
Out.ar(0, car);
}).add;
)

!

(
Synth("fm1",
Synth("fm1",
Synth("fm1",
Synth("fm1",
)

["modPartial", 2.4]);
["modPartial", 2.401]);
["freq", 110, "modPartial", 3.1213, "index", 10]);
["freq", 220, "modPartial", 10.99, "index", 20]);
変調合成2 - FM
‣ FM応用2 - FM + エフェクト
(
SynthDef("fm2", { arg bus = 0, freq = 440, detune = 2, carPartial = 1,
modPartial = 1, index = 3, mul = 0.1;
var mod, car;
mod = SinOsc.ar(
[freq, freq+detune] * modPartial,
0,
freq * index * LFNoise1.kr(10.reciprocal).abs
);
car = SinOsc.ar((freq * carPartial) + mod, 0, mul);
Out.ar(bus, car);
}).add;
変調合成2 - FM
‣ FM応用2 - FM + エフェクト
SynthDef("preDelay", { arg inbus = 2;
ReplaceOut.ar(
4,
DelayN.ar(In.ar(inbus, 1), 0.048, 0.048)
)
}).add;

!

SynthDef("combs", {
ReplaceOut.ar(
6,
Mix.arFill(7, { CombL.ar(In.ar(4, 1), 0.1, LFNoise1.kr(Rand(0,
0.1), 0.04, 0.05), 15) })
)
}).add;

!

SynthDef("allpass", { arg gain = 0.2;
var source;
source = In.ar(6, 1);
4.do({source = AllpassN.ar(source, 0.050, [Rand(0, 0.05), Rand(0,
0.05)], 1) });
ReplaceOut.ar(8, source * gain)
}).add;
変調合成2 - FM
‣ FM応用2 - FM + エフェクト
SynthDef("theMixer", { arg gain = 1;
ReplaceOut.ar(
0,
Mix.ar([In.ar(2, 1), In.ar(8, 2)]) * gain
)
}).add;
)

!

(
Synth("fm2", ["bus", 2, "freq", 440, "modPartial", 2.4]);
Synth("fm2", ["bus", 2, "freq", 448, "modPartial", 2.401]);
Synth.tail(s, "preDelay");
Synth.tail(s, "combs");
Synth.tail(s, "allpass");
Synth.tail(s, "theMixer", ["gain", 0.64]);
)

Interactive Music II SuperCollider入門 4 - 楽器を定義、変調合成(RM, AM, FM)

  • 1.
    Interactive Music II SuperCollider入門4 楽器を定義、変調合成(RM, AM, FM) 2013年10月24日 東京藝術大学芸術情報センター(AMC) 田所 淳
  • 2.
    今日の内容 ‣ 先週の続き -楽器を定義する ‣ SynthDef について ! ‣ SuperColliderによる音響合成入門 ‣ 変調合成: ‣ RM - リング変調 ‣ AM - 振幅変調 ‣ FM - 周波数変調
  • 3.
  • 4.
    「楽器」を定義する - SynthDef ‣これまで使用してきた、{ }.play; という形式 ‣ 一時的に、楽器(Synth)を生成し、それをSC Serverに送って出 力していた ! ‣ 例えば、SinOscを使用した際のPost Windowの出力 //! {}.playによる出力 {SinOsc.ar}.play; ! ! //! Post Windowの表示 Synth("temp__146" : 1000) ! ! ‣ これは、 temp__146 という名前の楽器を生成していた
  • 5.
    「楽器」を定義する - SynthDef ‣SynthDef - 楽器を定義する ‣ SynthDef( 楽器の名前 , { Ugen関数 }); ! ‣ 先程の簡単な関数によるプログラムをSynthDef形式へ ! ! {SinOsc.ar}.play; !! // SyntDefに変換 ! SynthDef("sine", {Out.ar(0, SynthDef("sine", {Out.ar(1, ! ! // {}.playによる出力 SinOsc.ar)}).play; //left SinOsc.ar)}).play; //right ‣ SynthDefの最終出力は、必ずOutオブジェクトに渡さなければ ならない (PdやMax/MSPの「dac 」のようなもの) ‣ Out.ar( バス番号, 出力信号);
  • 6.
    「楽器」を定義する - SynthDef ‣SynthDef、もう少し複雑な例 //関数による記述 { SinOsc.ar(440, 0, 0.2) }.play; ! //SynthDefをサーバーに追加 SynthDef.new("test-SinOsc", { Out.ar(0, SinOsc.ar(440, 0, 0.2)) }).add; ! //Synthを演奏 Synth("test-SinOsc");
  • 7.
    「楽器」を定義する - SynthDef ‣SynthDef は、引数 (Arguments) を渡せる //SynthDefの定義(引数あり) SynthDef.new("test-SinOsc", { arg freq = 440, amp = 0.2; Out.ar(0, SinOsc.ar(freq, 0, amp)) }).add; ! //Synthを演奏 a = Synth("test-SinOsc"); //440Hz b = Synth("test-SinOsc", [freq:660]); //660Hz c = Synth("test-SinOsc", [freq:880, amp:0.5]); //880Hz, amp:0.5 ! a.set("freq", 330); //440Hz -> 330Hz b.set("freq", 220, "amp", 0.3); //660Hz -> 220Hz, amp: 0.3 ! //終了 a.free; b.free; c.free;
  • 8.
  • 9.
    変調合成1- RMとAM ‣ 変調合成(Modulation synthesis) ! ‣ ある信号のパラメータを、もう1つの信号で変更することで行 う音響合成の手法 ! ‣ 変更される信号 → キャリア(Carrier) ‣ 変更する信号 → モジュレーター(Modulator)
  • 10.
    変調合成1- RMとAM ‣ キャリアの何を変調するかによって、異なる特性をもった音響 合成が可能 ! ‣音量を変調: リング変調(RM)、振幅変調(AM) ‣ 周波数を変調: 周波数変調(FM)
  • 11.
  • 12.
    変調合成1- RMとAM ‣ AM、RM:モジュレータのオシレータでキャリアの音量を変調 ‣ 高速のビブラートとも言えるでしょう。 ! ‣ AMとRMの原理はとても良く似ている ‣ その差は、モジュレータの変化の範囲によって決まる ! ‣ AM: モジュレーターの振幅 0.0∼1.0 ‣ RM: モジュレーターの振幅 -1.0∼1.0
  • 13.
  • 14.
  • 15.
    変調合成1- RMとAM ‣ RM合成の例 //RM変調 SynthDef.new("test-rm",{ var car, mod, rm; mod = SinOsc.ar(880, 0, 1.0); car = SinOsc.ar([440,442], 0, 0.5); rm = car * mod; Out.ar(0, rm); }).play; ! ! // RM変調2 - マウスでModulatorの周波数を変更 SynthDef.new("test-rm",{ var car, mod, rm; mod = SinOsc.ar(MouseX.kr(1, 4000, 1), 0, 1.0); car = SinOsc.ar([440,442], 0, 0.5); rm = car * mod; Out.ar(0, rm); }).play;
  • 16.
    変調合成1- RMとAM ‣ RM合成の例- 2 // RM変調3 - 2つのModulator SynthDef.new("test-rm",{ var car, mod1, mod2, rm; car = SinOsc.ar(440, 0, 0.5); mod1 = SinOsc.ar(MouseX.kr(1, 4000, 1), 0, 1.0); mod2 = SinOsc.ar([6.1,7.9].reciprocal); rm = car * (mod1 * mod2); Out.ar(0, rm); }).play;
  • 17.
  • 18.
    変調合成1- RMとAM ‣ AM合成の例 //AM変調 SynthDef.new("test-am",{ var car, mod, rm; mod = SinOsc.ar(MouseX.kr(1, 4000, 1), 0, 0.5, 0.5); car = SinOsc.ar([440,442], 0, 0.5); rm = car * mod; Out.ar(0, rm); }).play; ! SynthDef.new("test-am",{ var car, mod1, mod2, rm; car = SinOsc.ar(440, 0, 0.5); mod1 = SinOsc.ar(MouseX.kr(1, 4000, 1), 0, 0.5, 0.5); mod2 = SinOsc.ar([8,7].reciprocal); rm = car * (mod1 * mod2); Out.ar(0, rm); }).play;
  • 19.
    変調合成1- RMとAM ‣ AM合成のパラメータをノイズ(LFNoise1)で変化させる //AM + LFNoise ( SynthDef.new("rand-am",{ arg freq = 440, amp = 0.5, modFreq = 400; var car, mod1, mod2, rm; car = SinOsc.ar(freq, 0, amp); mod1 = SinOsc.ar(LFNoise1.kr(5.reciprocal, modFreq), pi.rand, 0.5, 0.5); mod2 = SinOsc.ar(LFNoise1.kr([8,7].reciprocal).abs); rm = car * (mod1 * mod2); Out.ar(0, rm); }).add; ) ! ( Synth("rand-am", Synth("rand-am", Synth("rand-am", Synth("rand-am", Synth("rand-am", ) ["freq", ["freq", ["freq", ["freq", ["freq", 110, "amp", 0.2, "modFreq", 1200]); 220, "amp", 0.2, "modFreq", 200]); 440, "amp", "modFreq", 200]); 880, "amp", 0.2, "modFreq", 100]); 1780, "amp", 0.05, "modFreq", 20]);
  • 20.
  • 21.
  • 22.
    変調合成2 - FM ‣FM - 周波数の変調 ‣ FMを利用した音響合成 ‣ ジョン・チョウニングを中心としてスタンフォード大学の CCRMA(Center for Computer Research in Music and Acoustics)で1973年開発 ‣ その後ヤマハにライセンス
  • 23.
    変調合成2 - FM ‣YAMAHA DX7 (1983)
  • 24.
    変調合成2 - FM ‣FM合成の特徴 ‣ たった3つのパラメータで、驚くほど多様なサウンドを実現 ! ‣ C - Carrier:キャリア周波数 ‣ M - Modulator : モジュレータ周波数 ‣ I - Index:モジュレータの振幅
  • 25.
    変調合成2 - FM ‣FM合成のダイアグラム Mod Index Mod Car + amp Car
  • 26.
    変調合成2 - FM ‣参考: Pd では
  • 27.
    変調合成2 - FM ‣Index の大きさによる周波数成分の変化
  • 28.
    変調合成2 - FM ‣FM基本 //FM基本 SynthDef.new("test-fm",{ arg cfreq = 440, mfreq = 111, index = 200; var car, mod; mod = SinOsc.ar(mfreq, 0, index); car = SinOsc.ar([cfreq, cfreq*1.005] + mod, 0, 0.5); Out.ar(0, car); }).play;
  • 29.
    変調合成2 - FM ‣Mod Freq と Index をマウスで操作 //FMマウスで操作 SynthDef.new("test-fm",{ var car, mod; mod = SinOsc.ar(MouseX.kr(1, 1000, 1), 0, MouseY.kr(1, 10000, 1)); car = SinOsc.ar([440,442] + mod, 0, 0.5); Out.ar(0, car); }).play;
  • 30.
    変調合成2 - FM ‣FM応用1 ( SynthDef("fm1", { arg freq = 440, detune = 2, carPartial = 1, modPartial = 1, index = 3, mul = 0.2; var mod, car; mod = SinOsc.ar( [freq, freq+detune] * modPartial, 0, freq * index * LFNoise1.kr(10.reciprocal).abs ); car = SinOsc.ar((freq * carPartial) + mod, 0, mul); Out.ar(0, car); }).add; ) ! ( Synth("fm1", Synth("fm1", Synth("fm1", Synth("fm1", ) ["modPartial", 2.4]); ["modPartial", 2.401]); ["freq", 110, "modPartial", 3.1213, "index", 10]); ["freq", 220, "modPartial", 10.99, "index", 20]);
  • 31.
    変調合成2 - FM ‣FM応用2 - FM + エフェクト ( SynthDef("fm2", { arg bus = 0, freq = 440, detune = 2, carPartial = 1, modPartial = 1, index = 3, mul = 0.1; var mod, car; mod = SinOsc.ar( [freq, freq+detune] * modPartial, 0, freq * index * LFNoise1.kr(10.reciprocal).abs ); car = SinOsc.ar((freq * carPartial) + mod, 0, mul); Out.ar(bus, car); }).add;
  • 32.
    変調合成2 - FM ‣FM応用2 - FM + エフェクト SynthDef("preDelay", { arg inbus = 2; ReplaceOut.ar( 4, DelayN.ar(In.ar(inbus, 1), 0.048, 0.048) ) }).add; ! SynthDef("combs", { ReplaceOut.ar( 6, Mix.arFill(7, { CombL.ar(In.ar(4, 1), 0.1, LFNoise1.kr(Rand(0, 0.1), 0.04, 0.05), 15) }) ) }).add; ! SynthDef("allpass", { arg gain = 0.2; var source; source = In.ar(6, 1); 4.do({source = AllpassN.ar(source, 0.050, [Rand(0, 0.05), Rand(0, 0.05)], 1) }); ReplaceOut.ar(8, source * gain) }).add;
  • 33.
    変調合成2 - FM ‣FM応用2 - FM + エフェクト SynthDef("theMixer", { arg gain = 1; ReplaceOut.ar( 0, Mix.ar([In.ar(2, 1), In.ar(8, 2)]) * gain ) }).add; ) ! ( Synth("fm2", ["bus", 2, "freq", 440, "modPartial", 2.4]); Synth("fm2", ["bus", 2, "freq", 448, "modPartial", 2.401]); Synth.tail(s, "preDelay"); Synth.tail(s, "combs"); Synth.tail(s, "allpass"); Synth.tail(s, "theMixer", ["gain", 0.64]); )