Ekstensi ini dapat dengan cepat mengkonversi file gelombang suara format PCM menjadi file audio format WAV. Saat ini, ekstensi ini hanya memberikan solusi untuk proyek perusahaan.
Referensi tambahannya ada di helviojunior/WaveGenerator, terima kasih khusus kepada Anda!
composer require jade/pcm-to-wavuse 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.phpPCM dan WAV ? PCM : PCM (Modulasi Kode Pulsa ---- perekaman modulasi kode pulsa). Yang disebut perekaman PCM adalah mengubah sinyal analog seperti suara menjadi rangkaian pulsa simbolis dan kemudian merekamnya. Sinyal PCM adalah sinyal digital yang terdiri dari 1 , 0 , dan simbol lainnya tanpa proses pengkodean atau kompresi apa pun. Dibandingkan dengan sinyal analog, sinyal ini kurang rentan terhadap noise dan distorsi pada sistem transmisi. Rentang dinamisnya lebar dan kualitas suaranya cukup bagus.
WAV : WAV adalah format file audio lossless. WAV mematuhi spesifikasi PIFF (Resource Interchange File Format). Semua WAV memiliki header file, yang berisi parameter pengkodean aliran audio. WAV tidak memiliki aturan tegas dan cepat untuk menyandikan aliran audio Selain PCM , hampir semua penyandian yang mendukung spesifikasi ACM dapat menyandikan aliran audio WAV.
PCM dan WAV Sederhananya, PCM adalah data asli audio, dan WAV adalah wadah yang merangkum data audio, dan formatnya sangat sederhana, hanya menambahkan beberapa informasi header terkait data audio di awal data.
Pertama, mari kita lihat aturan format WAV, seperti gambar di bawah ini
Setelah memahami aturan-aturan ini, kita bisa mulai coding
1. ChunkID menempati 4 byte, nilai tetap "RIFF"
$ChunkID = array(0x52, 0x49, 0x46, 0x46); // RIFF 16进制的0x52等于10进制中的82,82对应的ASCII码为R
2. ChunkSize menempati 4 byte, dan nilainya adalah 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size).
$ChunkSize = array(0x0, 0x0, 0x0, 0x0);
$ChunkSize = self::getLittleEndianByteArray(36 + $dataSize);
3. Format menempati 4byte, nilai tetap "WAVE"
$FileFormat = array(0x57, 0x41, 0x56, 0x45); // WAVE
4. Subchunk1ID menempati 4 byte, nilai tetap "ftm" (perhatikan penyelesaian spasi 4 digit)
$Subchunk1ID = array(0x66, 0x6D, 0x74, 0x20); // fmt
5. Subchunk1Size menempati 4byte, dan jika datanya PCM, nilainya 16
$Subchunk1Size = array(0x10, 0x0, 0x0, 0x0); // 16 little endian
6. AudioFormat menempati 2 byte. Jika datanya adalah PCM, nilainya adalah 1. Nilai lain menunjukkan bahwa data telah dikompresi dengan cara tertentu.
$AudioFormat = array(0x1, 0x0); // PCM = 1 little endian
7. NumChannels menempati 2 byte, sesuai dengan channelConfig di AudioRecord, Mono = 1, Stereo = 2
if ($numchannels == 2) {
$fmt->NumChannels = array(0x2, 0x0); // 立体声为2
} else {
$fmt->NumChannels = array(0x1, 0x0); // 单声道为1
}
8. SampleRate menempati 4 byte, sesuai dengan sampleRateInHz di AudioRecord, yang merupakan frekuensi pengambilan sampel, seperti 8000, 16000, 44100
$SampleRate = self::getLittleEndianByteArray($samplerate);
9. ByteRate menempati 4byte, dan nilainya adalah SampleRate * BlockAlign
self::getLittleEndianByteArray($samplerate * $numchannels * ($bitspersample / 8));
10. BlockAlign menempati 2 byte, dan nilainya adalah NumChannels * BitsPerSample / 8
self::getLittleEndianByteArray($numchannels * ($bitspersample / 8), true);
11. BitsPerSample menempati 2byte, sesuai dengan audioFormat di AudioRecord, 8bits = 8, 16bits = 16
self::getLittleEndianByteArray($bitspersample, true);
12. Subchunk2ID menempati 4byte, nilai tetap "data", yaitu
$Subchunk2ID = array(0x64, 0x61, 0x74, 0x61); // data
13. Subchunk2Size menempati 4byte, yang menggambarkan panjang data audio, yaitu ukuran file pcm.
self::getLittleEndianByteArray(filesize($filename));
14. Data menyumbang byte ukuran file pcm, mewakili data audio PCM asli.
deskripsi metode getLittleEndianByteArray
getLittleEndianByteArray terutama memproses angka yang diteruskan dan mengubahnya menjadi data yang perlu digunakan. Panjang array akan dikembalikan berdasarkan jumlah byte.
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;
}
Informasi 44 byte pertama di seluruh file pada dasarnya telah dijelaskan. Mari kita bicara tentang implementasi pemrosesan file kelas. Logika pemrosesan di sini pertama-tama membuat file dengan hanya 44 byte untuk sementara, dan kemudian menambahkan data file PCM ke dalam file tersebut. Terakhir, menurut aturan format WAV, informasi header 44-byte sebenarnya dihitung dan penunjuk modifikasi file menunjuk ke awal file, dan kemudian dimodifikasi ke data yang baru dihasilkan.