Cette extension peut convertir rapidement des fichiers d'ondes sonores au format PCM en fichiers audio au format WAV. Actuellement, elle ne fournit des solutions que pour les projets d'entreprise.
La référence étendue est dans helviojunior/WaveGenerator, un merci spécial à vous !
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
et WAV
? PCM
: PCM (Pulse Code Modulation ---- enregistrement de modulation de code d'impulsion). L'enregistrement dit PCM
consiste à convertir des signaux analogiques tels que le son en trains d'impulsions symboliques, puis à les enregistrer. PCM
est un signal numérique composé de 1
, 0
et d'autres symboles sans aucun codage ni traitement de compression. Comparé aux signaux analogiques, il est moins sensible au bruit et à la distorsion dans le système de transmission. La plage dynamique est large et la qualité sonore peut être assez bonne.
WAV
: WAV
est un format de fichier audio sans perte WAV
conforme à la spécification PIFF (Resource Interchange File Format). Tous WAV
ont un en-tête de fichier qui contient les paramètres d'encodage du flux audio. WAV n'a pas de règles strictes pour l'encodage des flux audio. En plus du PCM
, presque tous les encodages prenant en charge ACM
peuvent encoder les flux audio WAV.
PCM
et WAV
En termes simples, PCM
est les données audio originales et WAV
est un conteneur qui encapsule les données audio, et son format est très simple. Il ajoute simplement des informations d'en-tête liées aux données audio au début des données.
Tout d’abord, jetons un coup d’œil aux règles de format de WAV, comme indiqué ci-dessous.
Après avoir compris ces règles, nous pouvons commencer à coder
1. ChunkID
occupe 4 octets, valeur fixe "RIFF"
$ChunkID = array(0x52, 0x49, 0x46, 0x46); // RIFF 16进制的0x52等于10进制中的82,82对应的ASCII码为R
2. ChunkSize
occupe 4 octets et la valeur est 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size). Si les données d'origine sont PCM, elles sont simplifiées à 36 + SubChunk2Size.
$ChunkSize = array(0x0, 0x0, 0x0, 0x0);
$ChunkSize = self::getLittleEndianByteArray(36 + $dataSize);
3. Format
occupe 4 octets, valeur fixe "WAVE"
$FileFormat = array(0x57, 0x41, 0x56, 0x45); // WAVE
4. Subchunk1ID
occupe 4 octets, valeur fixe "ftm" (notez la complétion de l'espace de 4 chiffres)
$Subchunk1ID = array(0x66, 0x6D, 0x74, 0x20); // fmt
5. Subchunk1Size
occupe 4 octets et lorsque les données sont PCM, la valeur est 16
$Subchunk1Size = array(0x10, 0x0, 0x0, 0x0); // 16 little endian
6. AudioFormat
occupe 2 octets Lorsque les données sont PCM, la valeur est 1. D'autres valeurs indiquent que les données ont été compressées d'une manière ou d'une autre.
$AudioFormat = array(0x1, 0x0); // PCM = 1 little endian
7. NumChannels
occupe 2 octets, correspondant à ChannelConfig dans AudioRecord, Mono = 1, Stereo = 2
if ($numchannels == 2) {
$fmt->NumChannels = array(0x2, 0x0); // 立体声为2
} else {
$fmt->NumChannels = array(0x1, 0x0); // 单声道为1
}
8. SampleRate
occupe 4 octets, correspondant à sampleRateInHz dans AudioRecord, qui est la fréquence d'échantillonnage, telle que 8000, 16000, 44100.
$SampleRate = self::getLittleEndianByteArray($samplerate);
9. ByteRate
occupe 4 octets et la valeur est SampleRate * BlockAlign
self::getLittleEndianByteArray($samplerate * $numchannels * ($bitspersample / 8));
10. BlockAlign
occupe 2 octets et la valeur est NumChannels * BitsPerSample / 8
self::getLittleEndianByteArray($numchannels * ($bitspersample / 8), true);
11. BitsPerSample
occupe 2 octets, correspondant à audioFormat dans AudioRecord, 8 bits = 8, 16 bits = 16
self::getLittleEndianByteArray($bitspersample, true);
12. Subchunk2ID
occupe 4 octets de "données" à valeur fixe, c'est-à-dire
$Subchunk2ID = array(0x64, 0x61, 0x74, 0x61); // data
13. Subchunk2Size
occupe 4 octets, qui décrit la longueur des données audio, qui correspond à la taille du fichier pcm.
self::getLittleEndianByteArray(filesize($filename));
14. Data
représentent les octets de la taille du fichier pcm, représentant les données audio PCM d'origine.
Description de la méthode getLittleEndianByteArray
getLittleEndianByteArray
traite principalement les nombres transmis et les convertit en données qui doivent être utilisées. La longueur du tableau sera renvoyée en fonction du nombre d'octets.
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;
}
Les 44 premiers octets d'informations de l'ensemble du fichier ont été essentiellement expliqués. Parlons de l'implémentation des fichiers de classe de traitement. La logique de traitement crée ici d'abord temporairement un fichier de seulement 44 octets, puis ajoute les données PCM
au fichier. Enfin, selon les règles du format WAV, les informations réelles de l'en-tête de 44 octets sont réellement calculées et le pointeur de modification du fichier pointe vers le début du fichier, puis modifié avec les données nouvellement générées.