この記事は Qiita p5.js アドベントカレンダー23日目の記事です。
これはなに
いろんなものを描画できるp5.jsですがたくさんライブラリが用意されておりまして、
その中のp5.soundを利用して遊んでみようというものです。
p5.sound
p5.jsのコアライブラリとして提供されている拡張機能です。
こちらを利用することで音に関する動作、情報の取得が容易にできるようになるみたい。
ということでリファレンスをみてみるとめちゃくちゃ関数があります!
もうなんでもできそうですね。ドキドキしてきました。
試してみる
ライブラリを読み込む
リファレンスにある通り、index.htmlのheadタグ内でライブラリを読み込みます。
<head>
<!-- 追加 -->
<script src="p5.sound.js"></script>
</head>
音を読み込んで鳴らす
リファレンスを参考に音を鳴らしてみます。
今回使う音源は私が以前作っていた音源を使用します。
よかったら聴いてください!↓
https://soundcloud.com/tenten1105/20201005a
// setup前に音源を読み込む
function preload() {
sound = loadSound('./20201005.mp3')
}
function setup() {
canvas = createCanvas(600, 600);
// canvasをクリックすると音が鳴る
canvas.mousePressed(onClickPlay)
}
function draw() {
background(0);
}
// 音源を鳴らす
function onClickPlay () {
sound = sound.play()
}
preload
でロードされた音源はsoundのインスタンスとして利用できるようです。
canvas内をクリックするとsound.play
により音源が鳴り始めました!
もちろんstop
メソッドも持っているので、これを利用すればミニプレーヤーができてしまいます。
音量を取得する
流れている音量を数値として取得してみましょう。
ついでにonClickPlay
に「再生してたら音とめる」な処理も追加しました。
function preload() {
sound = loadSound('./20201005.mp3')
}
function setup() {
canvas = createCanvas(600, 600);
canvas.mousePressed(onClickPlay)
// Amplitudeのインスタンスを生成
amplitude = new p5.Amplitude();
}
function draw() {
background(0);
textSize(32);
fill('white')
// getLevel()で音量を取得
const level = amplitude.getLevel()
text(level, 100, 100)
}
function onClickPlay () {
if(sound.isPlaying()) {
sound.stop()
return
}
sound.play()
}
しっかりと音量を取得することができました!
音量のピークを取得する
今度は音量の最大値を取得し、最大かそうじゃないかで文字列を出しわけてみます。
function draw() {
background(0);
const level = amplitude.getLevel()
// getPeak()で読み込んだ音源の最大値を取得
const peak = sound.getPeaks(1)
text(level, 100, 100)
textSize(32);
fill('white')
// テキストを出し分ける
if(level > peak - 0.2) {
text('音量がpeak - 0.2を超えた', 50, 50)
} else {
text('音量がpeak - 0.2未満', 50, 150)
}
}
音量によって文字の出し分けをすることができました👏
このようにp5.soundを利用すれば簡単に音による制御を加えることができます。
簡単なビジュアライザを作ってみる
ellipseで円の半径と色が変わるビジュアライザを作成してみました。
下記リンクに遷移し、canvasをクリックすると音源の再生と描画が始まります。
https://editor.p5js.org/shibuya01055/sketches/2qa0oHKEg
function preload() {
sound = loadSound('./20201005.mp3')
}
function setup() {
canvas = createCanvas(600, 600);
canvas.mousePressed(onClickPlay)
amplitude = new p5.Amplitude();
colorMode(HSB)
rowVolumeColor = color(100, 255, 255)
highVolumeColor = color(0, 100, 100)
}
function draw() {
background(0, 80);
const level = amplitude.getLevel()
const peak = sound.getPeaks(1)
text(level, 100, 100)
textSize(32)
noStroke()
fill(isSpecifiedMax(level, peak))
ellipse(width / 2, height / 2, level * width)
push()
fill(100, 100, level*100)
ellipse(width / 2, height / 2, level * width / 3)
pop()
}
function onClickPlay () {
if(sound.isPlaying()) {
sound.stop()
return
}
sound.play()
}
function isSpecifiedMax (level, peak) {
if(level > peak - 0.2) {
return highVolumeColor
} else {
return rowVolumeColor
}
}