On the way to fun things

聲音合成 Sound Synthesizers

Snapshot from Will Hurt's work AP1

開始之前 Before we start...

Snapshot from Will Hurt's work AP1

  • 目標是大家回家可以做一台自己的琴
  • 入門款使用方式,沒有太硬的知識
  • 使用工具:P5JS + ToneJS

P5.js Intro

  • 可以做 2D、3D 以及聲音的 Library
    (還有 machine learning 好朋友 ML5)
  • 前身 processing
  • 使用 canvas

P5.js Core

Setup

設定東西的地方

Draw

不斷重複執行的功能(60 times per sec)

其他還有 mousePressed、keyDown 等 function

在這兩個 function 中可以 call p5 methods

P5.js Simple Example

function setup() {
  createCanvas(400, 400);
  background(0, 0, 0);
}

function draw() {
  rect(width / 2, height / 2, 24, 24);
}

P5.js Quick Start

P5.js Namespacing

function sketch(p) {
  p.setup = function() {
    p.createCanvas(p.width, p.height);
  }
  
  p.draw = function() {
    p.background(155, 100, 40);
    p.rect(p.mouseX, p.mouseY, 40, 40);
  }
}

new p5(
  sketch, 
  document.getElemendById('myCanvas')
);

讓它可以跟 webpack、React 等一起使用,會需要 namespacing 的做法

聲音合成

減法合成 Subtractive Synthesis

減法合成概念

產生聲波

去掉不要的頻段

控制聲音的生命週期

+

減法合成術語

Oscillator

Filter

Envelope

產生聲波

去掉不要的頻段

控制聲音的生命週期

Oscillator

有四種波形分類:

  • Sine
  • Square
  • Triangle
  • Sawtooth

Oscillator

設定音高用 frequency

Oscillator

設定音量用 amp(amplitude)

Oscillator

example

const osc = new Tone.Oscillator(440, 'triangle');

function setup() {
  createCanvas(windowWidth, windowHeight);
  background(223, 180, 76);

  osc.toDestination();
}

function keyPressed() {
  Tone.start();
  osc.start();
  background(155, 41, 21);
}

function keyReleased() {
  osc.stop();
  background(223, 180, 76);
}

Filter

常見的 3 種 filter:

  • 低通 Low Pass
  • 高通 High Pass
  • 帶通 Band Pass

Filter

resonance(res) 控制下降幅度

  • res 值越小,越寬

Filter

frequency(cut-off) 控制高峰點

  • freq 有可能改變聽到的音高

Filter

example

const osc = new Tone.Oscillator(440, 'triangle');
const filter = new Tone.Filter(20, 'bandpass');

osc.connect(filter);
filter.toDestination();

function setup() {
  createCanvas(windowWidth, windowHeight);
  background(223, 180, 76);
}

function draw() {
  const freq = map(mouseX, 0, width, 10, 22050);

  filter.set({ frequency: freq });
  // filter.frequency.rampTo(freq);
}

function keyPressed() {
  Tone.start();
  osc.start();
  background(155, 41, 21);
}

function keyReleased() {
  osc.stop();
  background(223, 180, 76);
}

Filter

example

let isPlaying = false;

// 生出一個振盪器
const osc = new p5.Oscillator('triangle');
osc.freq(440);
osc.amp(0.5);

// 生出一個濾波器
const filter = new p5.Filter('lowpass');
filter.freq(261);
filter.res(80);

// 讓濾波器跟振盪器連在一起
osc.connect(filter);

function setup() {
  createCanvas(windowWidth, windowHeight);
}

function mouseClicked() {
  if (isPlaying) {
    isPlaying = false;
    osc.stop();	
  } else {
    isPlaying = true;
    osc.start();	
  }
}

Envelope

ADSR

  • Attack - 到達峰值的時間
  • Decay - 從峰值到平均的時間
  • Sustain - 持續的時間
  • Release - 平均到沒聲音的時間

通常另外會設定 Attack Level & Sustain Level

Envelope

example

const osc = new Tone.Oscillator(440, 'triangle');
const filter = new Tone.Filter(261, 'lowpass');
const env = new Tone.Envelope({
  attack: 0.2,
  decay: 0.1,
  sustain: 0.5,
  release: 0.4,
});

osc.start();
osc.connect(env);
env.connect(filter);
filter.toDestination();

function setup() {
  createCanvas(windowWidth, windowHeight);
  background(223, 180, 76);
}

function keyPressed() {
  Tone.start();
  env.triggerAttack();
  background(155, 41, 21);
}

function keyReleased() {
  env.triggerRelease();
  background(223, 180, 76);
}

如果以上還是覺得不好玩...

Modulation Technique

  • 用另一個 oscillator 來改變另一個的頻率 or 振幅
  • Frequency Modulation (FM)
  • Amplitude Modulation (AM)

Sound Effects

  • Reverb 殘響
  • Distortion 破音
  • Delay 延遲

...等

Fin.

Sound Synth

By Kai Ting Liu

Sound Synth

  • 308