Generate wav tone in PHP

一个人想着一个人 提交于 2019-12-03 15:04:07
Willem Van Onsem

The problem is that you algorithm writes the numbers as text. Whereas a .wav file encodes the data binary.

You can use for instance pack to group data.

$freqOfTone = 440;
$sampleRate = 44100;
$samplesCount = 80000;

$amplitude = 0.25 * 32768;
$w = 2 * pi() * $freqOfTone / $sampleRate;

$samples = array();
for ($n = 0; $n < $samplesCount; $n++) {
    $samples[] = (int)($amplitude *  sin($n * $w));
}

$srate = 44100; //sample rate
$bps = 16; //bits per sample
$Bps = $bps/8; //bytes per sample /// I EDITED

$str = call_user_func_array("pack",
    array_merge(array("VVVVVvvVVvvVVv*"),
        array(//header
            0x46464952, //RIFF
            160038,      //File size
            0x45564157, //WAVE
            0x20746d66, //"fmt " (chunk)
            16, //chunk size
            1, //compression
            1, //nchannels
            $srate, //sample rate
            $Bps*$srate, //bytes/second
            $Bps, //block align
            $bps, //bits/sample
            0x61746164, //"data"
            160000 //chunk size
        ),
        $samples //data
    )
);
$myfile = fopen("sine.wav", "wb") or die("Unable to open file!");
fwrite($myfile, $str);
fclose($myfile);

This produces this file.

Note that you can't just reuse the above header. Some aspects were hardcoded that differ (like the size of the file, number of channels, bitrate, etc.). But if one reads the documentation, one can easily modify the header accordingly.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!