在音頻編程中,生成標準的WAV 文件頭部是一個基礎但關鍵的步驟。 WAV 文件是基於RIFF(Resource Interchange File Format)格式的音頻文件,結構清晰、易於讀取。本文將通過PHP 的pack()函數手動構造一個合法的WAV 文件頭部,便於開發者更深入地理解WAV 格式的結構。
一個標準的WAV 文件頭部大致可以分為以下幾個部分:
RIFF 塊:標記文件是一個RIFF 文件。
WAVE 標誌:說明文件類型是WAVE。
fmt 子塊:包含音頻格式信息(採樣率、聲道數、比特率等)。
data 子塊:包含實際的音頻數據。
結構如下:
| ChunkID | ChunkSize | Format |
|--------|-----------|--------|
| 'RIFF' | 36 + SubChunk2Size | 'WAVE' |
| Subchunk1ID | Subchunk1Size | AudioFormat | NumChannels | SampleRate | ByteRate | BlockAlign | BitsPerSample |
|-------------|----------------|-------------|-------------|------------|----------|-------------|----------------|
| Subchunk2ID | Subchunk2Size | Data |
PHP 的pack()函數可將數據打包成二進製字符串,適用於構造WAV 文件頭部。以下是一個簡單的例子,生成一個16-bit、單聲道、44.1kHz 的WAV 文件頭部,假設音頻數據大小為$dataSize字節:
<?php
function createWavHeader($dataSize, $sampleRate = 44100, $bitsPerSample = 16, $channels = 1)
{
$byteRate = $sampleRate * $channels * $bitsPerSample / 8;
$blockAlign = $channels * $bitsPerSample / 8;
$header = '';
// RIFF Header
$header .= pack('A4', 'RIFF'); // ChunkID
$header .= pack('V', 36 + $dataSize); // ChunkSize
$header .= pack('A4', 'WAVE'); // Format
// fmt Subchunk
$header .= pack('A4', 'fmt '); // Subchunk1ID
$header .= pack('V', 16); // Subchunk1Size
$header .= pack('v', 1); // AudioFormat (1 = PCM)
$header .= pack('v', $channels); // NumChannels
$header .= pack('V', $sampleRate); // SampleRate
$header .= pack('V', $byteRate); // ByteRate
$header .= pack('v', $blockAlign); // BlockAlign
$header .= pack('v', $bitsPerSample); // BitsPerSample
// data Subchunk
$header .= pack('A4', 'data'); // Subchunk2ID
$header .= pack('V', $dataSize); // Subchunk2Size
return $header;
}
// 示例:寫入一個空的 WAV 文件
$dataSize = 44100 * 2 * 1; // 1秒鐘的單聲道16位音頻數據
$header = createWavHeader($dataSize);
file_put_contents('output.wav', $header . str_repeat("\x00", $dataSize));
echo "WAV 文件已創建。可在 m66.net 下載測試文件。";
$sampleRate :採樣率,常見值有44100、48000 等。
$bitsPerSample :每個樣本的位深度,通常為8 或16。
$channels :通道數量,1 為單聲道,2 為立體聲。
$dataSize :音頻數據的實際字節數,計算方式為:秒數* 採樣率* 通道數* 位深/ 8 。
使用pack()構造WAV 文件頭部非常適合用於以下場景:
服務器端動態生成音頻流。
自定義音頻錄製格式的導出。
數據壓縮與音頻封裝分析工具的開發。