Esta extensión puede convertir rápidamente archivos de ondas de sonido en formato PCM en archivos de audio en formato WAV. Actualmente, solo proporciona soluciones para proyectos de la empresa.
La referencia ampliada está en helviojunior/WaveGenerator, ¡un agradecimiento especial para ti!
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 y WAV ? PCM : PCM (Modulación de código de pulso----grabación de modulación de código de pulso). La llamada grabación PCM consiste en convertir señales analógicas, como el sonido, en trenes de impulsos simbólicos y luego grabarlos. PCM es una señal digital compuesta por 1 , 0 y otros símbolos sin ningún procesamiento de codificación o compresión. En comparación con las señales analógicas, es menos susceptible al ruido y la distorsión en el sistema de transmisión. El rango dinámico es amplio y la calidad del sonido puede ser bastante buena.
WAV : WAV es un formato de archivo de audio sin pérdidas WAV cumple con la especificación PIFF (Formato de archivo de intercambio de recursos). Todos WAV tienen un encabezado de archivo que contiene los parámetros de codificación de la transmisión de audio. WAV no tiene reglas estrictas y rápidas para codificar transmisiones de audio. Además de PCM , casi todas las codificaciones que admiten ACM pueden codificar transmisiones de audio WAV.
PCM y WAV En pocas palabras, PCM son los datos de audio originales y WAV es un contenedor que encapsula datos de audio y su formato es muy simple: simplemente agrega información de encabezado relacionada con los datos de audio al comienzo de los datos.
Primero, echemos un vistazo a las reglas de formato de WAV, como se muestra a continuación.
Después de comprender estas reglas, podemos comenzar a codificar.
1. ChunkID ocupa 4 bytes, valor fijo "RIFF"
$ChunkID = array(0x52, 0x49, 0x46, 0x46); // RIFF 16进制的0x52等于10进制中的82,82对应的ASCII码为R
2. ChunkSize ocupa 4 bytes y el valor es 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size). Si los datos originales son PCM, se simplifica a 36 + SubChunk2Size.
$ChunkSize = array(0x0, 0x0, 0x0, 0x0);
$ChunkSize = self::getLittleEndianByteArray(36 + $dataSize);
3. Format ocupa 4 bytes, valor fijo "WAVE"
$FileFormat = array(0x57, 0x41, 0x56, 0x45); // WAVE
4. Subchunk1ID ocupa 4 bytes, valor fijo "ftm" (tenga en cuenta que el espacio se completa con 4 dígitos)
$Subchunk1ID = array(0x66, 0x6D, 0x74, 0x20); // fmt
5. Subchunk1Size ocupa 4 bytes y cuando los datos son PCM, el valor es 16
$Subchunk1Size = array(0x10, 0x0, 0x0, 0x0); // 16 little endian
6. AudioFormat ocupa 2 bytes. Cuando los datos son PCM, el valor es 1. Otros valores indican que los datos se han comprimido de alguna manera.
$AudioFormat = array(0x1, 0x0); // PCM = 1 little endian
7. NumChannels ocupa 2 bytes, correspondientes a channelConfig en AudioRecord, Mono = 1, Stereo = 2
if ($numchannels == 2) {
$fmt->NumChannels = array(0x2, 0x0); // 立体声为2
} else {
$fmt->NumChannels = array(0x1, 0x0); // 单声道为1
}
8. SampleRate ocupa 4 bytes, correspondientes a sampleRateInHz en AudioRecord, que es la frecuencia de muestreo, como 8000, 16000, 44100
$SampleRate = self::getLittleEndianByteArray($samplerate);
9. ByteRate ocupa 4 bytes y el valor es SampleRate * BlockAlign
self::getLittleEndianByteArray($samplerate * $numchannels * ($bitspersample / 8));
10. BlockAlign ocupa 2 bytes y el valor es NumChannels * BitsPerSample / 8
self::getLittleEndianByteArray($numchannels * ($bitspersample / 8), true);
11. BitsPerSample ocupa 2 bytes, correspondientes a audioFormat en AudioRecord, 8 bits = 8, 16 bits = 16
self::getLittleEndianByteArray($bitspersample, true);
12. Subchunk2ID ocupa 4 bytes, "datos" de valor fijo, es decir
$Subchunk2ID = array(0x64, 0x61, 0x74, 0x61); // data
13. Subchunk2Size ocupa 4 bytes, que describe la longitud de los datos de audio, que es el tamaño del archivo pcm.
self::getLittleEndianByteArray(filesize($filename));
14. Data representan bytes del tamaño del archivo pcm y representan los datos de audio PCM originales.
descripción del método getLittleEndianByteArray
getLittleEndianByteArray procesa principalmente los números pasados y los convierte en los datos que deben usarse. La longitud de la matriz se devolverá según la cantidad de bytes.
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;
}
Los primeros 44 bytes de información en todo el archivo se han explicado básicamente. Hablemos de la implementación del procesamiento de archivos de clase. La lógica de procesamiento aquí primero crea temporalmente un archivo con solo 44 bytes y luego agrega los datos del archivo PCM . Finalmente, de acuerdo con las reglas del formato WAV, la información de 44 bytes del encabezado real se calcula y el puntero de modificación del archivo apunta al comienzo del archivo y luego se modifica a los datos recién generados.