PHP で PCM wav ファイル作成 (2)
PHP で PCM wav ファイル作成 - yoyaのメモの続き
小豆を床に落としたような音が欲しくて、音声ファイルを作ってみたのが今日の話。
勿論、PHPで。
前回の記事で作った PHP で wav 音声作る function が結構便利なので、git に置いときました。
この makeWaveData.php を require して音を作って行きます。
注意
PHP で wav ファイルを作りましたがサイズが大きいので、MacOSX に入っている afconvert で変換した m4a の方を公開してます。
afconvert test.wav -f m4pf test.m4a
take0
まず sin 関数で正弦波を作って、それっぽい音が出るのを確認。
<?php require_once('makeWaveData.php'); $sampleRate = 44100; // CD quality $nChannel = 1; // 1:monoral, 2:stereo $toneA = 440; $sampleBits = 16; // 8 or 16 $period = 0.3; // seconds; $data = ''; $theta = 0; $theta_delta = $toneA * 2 * M_PI / $sampleRate; $amp = 0x1000; $totalSamples = $sampleRate * $period; for ($i = 1 ; $i < $sampleRate * $period ; $i++) { // signed 16-bit array (little endian) $v = 0 + 0x4000 * sin($theta); $data .= pack('v', $v); // acrovatic using for 'v' $theta += $theta_delta; } echo makeWaveData($data, $nChannel, $sampleBits, $sampleRate);
take1
mt_rand の乱数を入れてノイズにします。
$v = 0 + $amp * mt_rand() / mt_getrandmax();
take2
音量が徐々に下がる、いわゆる下降のエンベロープを付けます。
$v = 0 + $amp * ($totalSamples - $i) / $totalSamples * mt_rand() / mt_getrandmax();
take3
更に sin を混ぜます。但し周波数を1/100にして音程を感じさせないように。
$v = 0 + $volume * mt_rand()/ mt_getrandmax() * sin($theta/100);
これだとマラカスですね。
ちょっと遠ざかったので、take2 に戻ります。
take2-2
take2 の音の長さを短くします。
< $period = 0.3; // seconds; --- > $period = 0.05; // seconds;
take2-3
アタックを強くします。前半は急に音量を下げて後半はゆっくり下げる。
if ($i < $totalSamples/2) { // Decay $volume = ($totalSamples - $i*2) / $totalSamples + 0.5; } else { // Release $volume = ($totalSamples - $i/2) / $totalSamples - 0.5; }
これでいっかな。