2015-01-20 50 views
6

我想在php中生成正弦波音。但是構建我的wav我需要以字節爲單位給出值。我不知道該怎麼做:在PHP中生成波形音

這裏是我的代碼:

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

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

//$dataArray = new 


$text = "RIFF" 
."80036" 
."WAVE" 
."fmt " 
."16" 
."1" 
."1" 
."44100" 
."44100" 
."1" 
."8" 
."data" 
."80000"; 

for ($n = 0; $n < $samplesCount; $n++) 
{ 
    $text .= (int)($amplitude * sin($n * $w)); 
} 


$myfile = fopen("sine.wav", "w") or die("Unable to open file!"); 

fwrite($myfile, $text); 

fclose($myfile); 
+2

您將數據寫入「文本」中。波形文件是「二進制」的。 – 2015-01-20 19:09:31

+2

@CommuSoft試圖說的是,您必須編寫字節值,而不是文本內容。例如,不必寫'44100',而必須寫'0xAC44'字節。 – 2015-01-20 19:31:21

+0

@ Ismael Miguel - 那爲什麼他不使用80036的字節值? – lopata 2015-01-20 19:35:07

回答

5

的問題是,你的算法作爲文字寫的數字。而.wav文件編碼數據二進制文件。您可以使用例如pack分組數據。

$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); 

這產生了這個file

請注意,您不能只是重用上述標題。某些方面的硬編碼不同(如文件大小,通道數量,比特率等)。但是如果有人讀取documentation,則可以相應地輕鬆修改標題。

+3

不要忘記將'fopen(「sine.wav」,「w」)'改成'fopen(「sine.wav」,「w + b」)'(注意最後一個參數)。這可以避免Windows將'\ r \ n'(CRLF)轉換爲'\ r'(CR)。 – 2015-01-20 19:19:14

+0

@IsmaelMiguel:它實際上可以是'fopen(「sine.wav」,「wb」)',不需要'+'。 – 2015-01-20 19:24:27

+0

@RocketHazmat它不是必需的,但它總是安全的。只是爲了保證文件將被截斷。 – 2015-01-20 19:26:29