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-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
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.