さて今回はサウンドの実習です。
ここでは、Essというライブラリを使ってみます。ここではインストールの仕方は説明しませんので、自力でやってください。
1. サイン波
まずは、サイン波を出してみましょう。サイン波は、音の中で一番単純なものです。
まずは、220ヘルツのサイン波を出すコードを書いてみましょう。
import krister.Ess.*;
AudioChannel myChannel;
SineWave myWave;
void setup() {
size(300,300);
//Essをスタートさせる
Ess.start(this);
//myChannelオブジェクトを作成
myChannel=new AudioChannel();
//myChannelを初期化。この場合2000ミリ秒 = 2秒
myChannel.initChannel(myChannel.frames(2000));
myWave=new SineWave(220,.5); //SineWave(周波数, ボリューム[0-1の間])
myWave.generate(myChannel); //波形を生成し、myChannelに割り当てる
myChannel.volume(300); //ボリュームは300
//スムーズにパンする
myChannel.play(Ess.FOREVER); //ループ再生
//ボリュームを調整する。ボリューム[0-1の間], 調整する時間間隔[単位:ミリ秒]
myChannel.fadeTo(.5,500);
}
void draw() {
}
//終了する前にクリーンアップする
public void stop() {
Ess.stop();
super.stop();
}
簡単ですか?次は少し複雑です。
マウスのX軸の動きによって、左から聞こえたり右から聞こえたりします。更にY軸の動きによって、音量が変化します。
//This code has been arranged by Yasushi Noguchi. Last updated on July 1, 2008.
// Pan and Volume
// by Krister Olsson
// Generates a looping sine wave and pink noise.
// Pan and volume are controlled by mouse position
// Created 1 May 2005
// Updated 3 May 2006
import krister.Ess.*;
AudioChannel myChannel;
SineWave myWave;
void setup() {
size(300,300);
//Essをスタートさせる
Ess.start(this);
//myChannelオブジェクトを作成
myChannel=new AudioChannel();
//myChannelを初期化。この場合2000ミリ秒 = 2秒
myChannel.initChannel(myChannel.frames(2000));
myWave=new SineWave(220,.5); //SineWave(周波数, ボリューム[0-1の間])
myWave.generate(myChannel); //波形を生成し、myChannelに割り当てる
myChannel.volume(0); //ボリュームは0
//スムーズにパンする
myChannel.smoothPan=true;
myChannel.play(Ess.FOREVER); //ループ再生
//ボリュームを調整する。ボリューム[0-1の間], 調整する時間間隔[単位:ミリ秒]
myChannel.fadeTo(.5,500);
frameRate(30);
}
void draw() {
background(0);
stroke(255);
int x = mouseX;
int y = mouseY;
//パンとボリュームがマウスの動きで変化する。パンは-1から1の値を取る。
float newPan = (x/(float)width*2)-1;
float newVolume = y/(float)height;
//もし、パンしていなければ、newPanの値ごとにパンする(単位 ミリ秒)
if (!myChannel.panning) myChannel.panTo(newPan,500);
//newVolumeの値ごとにボリュームが変化する(単位 ミリ秒)
if (!myChannel.fading) myChannel.fadeTo(newVolume,500);
line(x, 0, x, height); //縦の線
line(0,y,width,y); //横の線
}
//終了する前にクリーンアップする
public void stop() {
Ess.stop();
super.stop();
}
ここで、いくつか重要な概念が登場します。
一般的に言われる音の三要素は、大きさ(Loudness)、高さ(Pitch)、音色(Tone)です。
ここでは、ボリューム=音の大きさ、周波数=高さが出てきます。
ですから、ボリュームは言うに及ばず、サンプルでは220に設定されている周波数を操作すると、音の高低が変化します。
クイズ マウスのy軸の値を変化させて周波数110から440の値をマウスの位置によって変化させなさい。
解答
import krister.Ess.*;
AudioChannel myChannel;
SineWave myWave;
float frequency = 0.0;
void setup() {
size(300,300);
//Essをスタートさせる
Ess.start(this);
//myChannelオブジェクトを作成
myChannel=new AudioChannel();
//myChannelを初期化。この場合2000ミリ秒 = 2秒
myChannel.initChannel(myChannel.frames(10000));
myWave=new SineWave(220,.5); //SineWave(周波数, ボリューム[0-1の間])
myWave.generate(myChannel); //波形を生成し、myChannelに割り当てる
myChannel.volume(0); //ボリュームは0
//スムーズにパンする
myChannel.smoothPan=true;
myChannel.play(Ess.FOREVER); //ループ再生
//ボリュームを調整する。ボリューム[0-1の間], 調整する時間間隔[単位:ミリ秒]
myChannel.fadeTo(1.0,500);
frameRate(30);
}
void draw() {
background(0);
stroke(255);
int x = mouseX;
int y = mouseY;
//パンとボリュームがマウスの動きで変化するパンは-1から1の値を取る。
float newPan = (x/float(width)*2)-1;
//もし、パンしていなければ、newPanの値ごとにパンする(単位 ミリ秒)
if (!myChannel.panning) myChannel.panTo(newPan,500);
myWave.frequency=frequency;
myWave.generate(myChannel);
line(x, 0, x, height); //縦の線
line(0,y,width,y); //横の線
}
//終了する前にクリーンアップする
public void stop() {
Ess.stop();
super.stop();
}
void mousePressed(){
//周波数は110から440の間を行き来する
frequency = mouseY/(float)height*(440-110) + 110;
}
2. サウンドファイルの再生
次は、サウンドファイルが外部から読み込んで再生する方法です。これは、かなり短いコードで書けてしまいます。
サンプル用サウンドファイル
bush.wav
//This code has been arranged by Yasushi Noguchi. Last updated on July 1, 2008.
// Scrub
// by Krister Olsson
// Loads a sample that can be played/paused by
// clicking a button in the lower left-hand corner.
// Playback head can be adjusted by clicking and dragging
// Created 1 May 2005
// Updated 2 May 2006
import krister.Ess.*;
AudioChannel myChannel;
void setup() {
size(256,200);
background(0);
Ess.start(this); //Essをスタートさせる
//bush.wavを読み込んで、myChannelオブジェクトを作成
myChannel=new AudioChannel("bush.wav");
myChannel.play(Ess.FOREVER); //ループ再生
frameRate(30);
}
void draw() {
}
void mousePressed() {
//もし、マウスが押されたときに再生していたら、
if (myChannel.state==Ess.PLAYING) myChannel.pause(); //一時停止する
else myChannel.resume(); //それ以外は一時停止解除
}
//終了する前にクリーンアップする
public void stop() {
Ess.stop();
super.stop();
}
3. エフェクト(reverb)
次はエフェクトです。代表的なエフェクトであるreverbをかけてみましょう。サンプルの音素材は先ほどと同じbush.wavを使います。基本的に上記のコードとそんなに変わらないので、reverbの部分だけ付け加えているような感じです。
//This code has been arranged by Yasushi Noguchi. Last updated on July 1, 2008.
// Example by Krister Olsson
// please check the followoing site for more details
//http://www.tree-axis.com/Ess/Reverb/Reverb.html
import krister.Ess.*;
AudioChannel myChannel;
Reverb myReverb;
void setup() {
size(200,200);
//Essをスタートさせる
Ess.start(this);
//buch.wavをインポートし、myChannelオブジェクトを作成
myChannel=new AudioChannel("bush.wav");
myReverb=new Reverb(); //Reverbオブジェクトを生成
//最初の引数(0.0 ~ 1.0)を操作することによって、Reverbのかけ具合が調節できる
//myReverb=new Reverb(1.0, 0, .5); //Reverbオブジェクトを生成
myChannel.play(Ess.FOREVER); //ループ再生
}
void draw() {
}
void mousePressed(){
//マウスクリックごとにReverbをかけていく
myReverb.filter(myChannel);
}
//終了する前にクリーンアップする
public void stop() {
Ess.stop();
super.stop();
}
エフェクトはその他にも色々あるので、下のマニュアルを見ながら試してみてください。
http://www.tree-axis.com/Ess/classes_AudioFilter_subclasses.html
4. Essのマニュアル
上記のサンプルはあくまでも初歩的なものでしかありません。Essや他のサウンド系ライブラリにはかなり多くの機能があります。興味がある人は是非独学で頑張ってみましょう(プログラミングって基本は独学なんです)。
http://www.tree-axis.com/Ess/index.html
このサイトのclassの項目には、使える機能が全部載っている
他のサウンド系ライブラリ
5. サウンド素材サイト
無料のサウンド素材はネットにいくらでもあります。まあ、品質は様々ですが、いいものもあるので根気よく探してみましょう。
http://www.freesound.org/
http://www.soundclick.com/default.cfm
参考
サウンドの周波数解析のサンプル
import krister.Ess.*;
FFT myFFT;
int bands = 128;
AudioStream myStream;
AudioFile myFile;
void setup(){
size(1024, 200);
Ess.start(this);
myFile = new AudioFile("ファイル名.aif", 0, Ess.READ);
myStream = new AudioStream(128*1024);
myStream.sampleRate(myFile.sampleRate);
myStream.start();
myFFT = new FFT(bands*2);
}
void draw(){
background(176);
myFFT.getSpectrum(myStream);
stroke(255);
for(int i = 0; i < bands; i ++){
float x = (float)i/(float)(bands-1)*1024.0;
float freY = max(0, myFFT.spectrum[i]*height*4);
line(x, height, x, height - freY);
}
}
void stop(){
Ess.stop();
super.stop();
}
void audioStreamWrite(AudioStream theStream){
int sampleRead = myFile.read(myStream);
}
