この拡張機能は、PCM 形式のサウンド ウェーブ ファイルを WAV 形式のオーディオ ファイルにすばやく変換できます。現在、企業プロジェクト向けのソリューションのみを提供しています。
拡張リファレンスは helviojunior/WaveGenerator にあります。ありがとうございます。
composer require jade/pcm-to-wav
use PcmToWav e P cmToWave ;
$input_file = ' ./file/test.pcm ' ; // 准备输入的文件
$output_file = ' ./file/test.wav ' ; // 预计输出的文件
$data = PcmToWav e::init( $pcm_file , $wav_file ) ; // 调用转换
进入扩展包目录
cd vendor/jade/pcm-to-wav
composer install
cd test
php Test.php
PCM
とWAV
とは何ですか? PCM
: PCM (Pulse Code Modulation ----パルス符号変調録音)。いわゆるPCM
録音とは、音声などのアナログ信号を記号的なパルス列に変換して録音することです。 PCM
信号は0
符号化や圧縮処理が施されていない、 1
などのシンボルから構成されるデジタル信号です。アナログ信号に比べて、伝送系のノイズや歪みの影響を受けにくいです。ダイナミックレンジも広く、音質もかなり良いです。
WAV
: WAV
WAV
、PIFF (Resource Interchange File Format) 仕様に準拠したロスレス オーディオ ファイル形式です。すべてのWAV
にはファイル ヘッダーがあり、オーディオ ストリームのエンコード パラメーターが含まれています。 WAV には、 PCM
に加えて、オーディオ ストリームをエンコードするための厳密なルールはありません。ACM ACM
をサポートするほぼすべてのエンコードで、WAV オーディオ ストリームをエンコードできます。
PCM
とWAV
の関係簡単に言うと、 PCM
音声の元データであり、 WAV
音声データをカプセル化したコンテナであり、その形式はデータの先頭に音声データに関するヘッダー情報を追加するだけです。
まず、以下に示すように、WAV のフォーマット規則を見てみましょう。
これらのルールを理解したら、コーディングを開始できます
1. ChunkID
は 4 バイトを占有し、固定値「RIFF」
$ChunkID = array(0x52, 0x49, 0x46, 0x46); // RIFF 16进制的0x52等于10进制中的82,82对应的ASCII码为R
2. ChunkSize
4 バイトを占め、その値は 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size) です。元のデータが PCM の場合、36 + SubChunk2Size に簡略化されます。
$ChunkSize = array(0x0, 0x0, 0x0, 0x0);
$ChunkSize = self::getLittleEndianByteArray(36 + $dataSize);
3. Format
4byte、固定値「WAVE」を占有します。
$FileFormat = array(0x57, 0x41, 0x56, 0x45); // WAVE
4. Subchunk1ID
4 バイトを占め、固定値「ftm」(4 桁のスペース補完に注意してください)
$Subchunk1ID = array(0x66, 0x6D, 0x74, 0x20); // fmt
5. Subchunk1Size
は 4byte を占め、データが PCM の場合、値は 16 になります。
$Subchunk1Size = array(0x10, 0x0, 0x0, 0x0); // 16 little endian
6. AudioFormat
2 バイトを占めます。データが PCM の場合、値は 1 です。その他の値は、データが何らかの方法で圧縮されていることを示します。
$AudioFormat = array(0x1, 0x0); // PCM = 1 little endian
7. NumChannels
2 バイトを占め、AudioRecord の channelConfig に対応し、モノラル = 1、ステレオ = 2
if ($numchannels == 2) {
$fmt->NumChannels = array(0x2, 0x0); // 立体声为2
} else {
$fmt->NumChannels = array(0x1, 0x0); // 单声道为1
}
8. SampleRate
4 バイトを占め、AudioRecord のサンプルRateInHz に対応します。これは、8000、16000、44100 などのサンプリング周波数です。
$SampleRate = self::getLittleEndianByteArray($samplerate);
9. ByteRate
4 バイトを占め、値は SampleRate * BlockAlign です。
self::getLittleEndianByteArray($samplerate * $numchannels * ($bitspersample / 8));
10. BlockAlign
2 バイトを占有し、値は NumChannels * BitsPerSample / 8 です。
self::getLittleEndianByteArray($numchannels * ($bitspersample / 8), true);
11. BitsPerSample
2 バイトを占め、AudioRecord の audioFormat に対応し、8 ビット = 8、16 ビット = 16
self::getLittleEndianByteArray($bitspersample, true);
12. Subchunk2ID
4 バイトの固定値「データ」を占めます。
$Subchunk2ID = array(0x64, 0x61, 0x74, 0x61); // data
13. Subchunk2Size
4 バイトを占め、オーディオ データの長さを表します。これは、pcm ファイルのサイズです。
self::getLittleEndianByteArray(filesize($filename));
14. Data
、元の PCM オーディオ データを表す pcm ファイル サイズのバイトを占めます。
getLittleEndianByteArray
メソッドの説明
getLittleEndianByteArray
主に、渡された数値を処理し、使用する必要があるデータに変換します。配列の長さはバイト数に基づいて返されます。
private static function getLittleEndianByteArray($lValue, $short = false)
{
$b = array(0, 0, 0, 0);
$running = $lValue / pow(16, 6);
$b[3] = floor($running);
$running -= $b[3];
$running *= 256;
$b[2] = floor($running);
$running -= $b[2];
$running *= 256;
$b[1] = floor($running);
$running -= $b[1];
$running *= 256;
$b[0] = round($running);
if ($short) { // 为 `true` 时返回长度为2的数组
$tmp = array_slice($b, 0, 2);
$b = $tmp;
}
return $b;
}
ファイル全体の最初の 44 バイトの情報については、基本的に説明しました。ここでの処理ロジックは、最初に 44 バイトだけのファイルを作成し、そのファイルにPCM
ファイルのデータを追加します。最後に、WAV 形式の規則に従って、実際のヘッダー 44 バイトの情報が実際に計算され、ファイル変更ポインターがファイルの先頭を指し、新しく生成されたデータに変更されます。