當前位置: 首頁> 最新文章列表> 如何使用pack() 函數生成標準的WAV 音頻文件頭部?

如何使用pack() 函數生成標準的WAV 音頻文件頭部?

M66 2025-06-12

在音頻編程中,生成標準的WAV 文件頭部是一個基礎但關鍵的步驟。 WAV 文件是基於RIFF(Resource Interchange File Format)格式的音頻文件,結構清晰、易於讀取。本文將通過PHP 的pack()函數手動構造一個合法的WAV 文件頭部,便於開發者更深入地理解WAV 格式的結構。

WAV 文件的基本結構

一個標準的WAV 文件頭部大致可以分為以下幾個部分:

  1. RIFF 塊:標記文件是一個RIFF 文件。

  2. WAVE 標誌:說明文件類型是WAVE。

  3. fmt 子塊:包含音頻格式信息(採樣率、聲道數、比特率等)。

  4. data 子塊:包含實際的音頻數據。

結構如下:

 | ChunkID | ChunkSize | Format |
|--------|-----------|--------|
| 'RIFF' | 36 + SubChunk2Size | 'WAVE' |

| Subchunk1ID | Subchunk1Size | AudioFormat | NumChannels | SampleRate | ByteRate | BlockAlign | BitsPerSample |
|-------------|----------------|-------------|-------------|------------|----------|-------------|----------------|

| Subchunk2ID | Subchunk2Size | Data |

使用pack()構造WAV 頭部

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 文件頭部非常適合用於以下場景:

  • 服務器端動態生成音頻流。

  • 自定義音頻錄製格式的導出。

  • 數據壓縮與音頻封裝分析工具的開發。

總結