WAV: Guía Completa del Formato de Audio Waveform
WAV (Waveform Audio File Format) es un contenedor de audio de Microsoft/IBM estandarizado en 1991 como parte de la especificación RIFF (Resource Interchange File Format). Los archivos WAV almacenan audio PCM (Modulación por Impulsos Codificados) sin comprimir — la representación digital bruta de una forma de onda sonora sin compresión con pérdida. WAV es el formato de intercambio universal entre herramientas de audio profesional, DAWs, grabadores hardware y sistemas de radiodifusión.
Estructura del Contenedor RIFF
WAV está construido sobre el contenedor basado en bloques RIFF. Cada archivo RIFF consiste en una cabecera RIFF de 12 bytes seguida de bloques anidados:
Cabecera RIFF (12 bytes):
ChunkID: "RIFF" (4 bytes, ASCII)
ChunkSize: tamaño total − 8 (4 bytes, uint32 little-endian)
Format: "WAVE" (4 bytes, ASCII)
Bloques obligatorios:
Bloque "fmt " — parámetros del formato de audio
Bloque "data" — datos de muestra brutos
Bloques opcionales:
"bext" — metadatos Broadcast Wave Format (BWF)
"smpl" — puntos de bucle de sampler
"LIST" — sub-bloques INFO (artista, título, etc.)
"cue " — marcadores de punto de señal
El Bloque fmt (16–40 bytes)
AudioFormat: 2 bytes — 1=PCM, 3=IEEE float, 65534=Extensible
NumChannels: 2 bytes — 1=mono, 2=estéreo, hasta 65535
SampleRate: 4 bytes — ej. 44100, 48000, 96000, 192000
ByteRate: 4 bytes — SampleRate × NumChannels × BitsPerSample/8
BlockAlign: 2 bytes — NumChannels × BitsPerSample/8
BitsPerSample: 2 bytes — 8, 16, 24, 32 (PCM); 32, 64 (IEEE float)
WAVE_FORMAT_EXTENSIBLE (AudioFormat=65534) extiende el bloque fmt básico para soportar más de 2 canales con mapeo de posición de altavoz, profundidades de bits donde ValidBitsPerSample < BitsPerSample (p. ej., 24 bits en un contenedor de 32 bits) y subformatos de códec arbitrarios mediante GUID.
Codificación de Muestras PCM
Para PCM entero estándar:
- 8 bits: enteros sin signo, 0–255, silencio en 128
- 16 bits: enteros con signo, −32768 a +32767, little-endian, silencio en 0
- 24 bits: enteros con signo, 3 bytes por muestra, little-endian — más común en grabación de estudio
- 32 bits float (IEEE 754): valores en rango −1.0 a +1.0; AudioFormat=3
Las muestras están intercaladas por canal: L₁ R₁ L₂ R₂ L₃ R₃ … (para estéreo).
Tasas de Muestreo Comunes y Sus Usos
| Tasa de muestreo | Límite de Nyquist | Caso de uso |
|---|---|---|
| 8.000 Hz | 4.000 Hz | Telefonía, voz (G.711) |
| 16.000 Hz | 8.000 Hz | Voz de banda ancha (WebRTC) |
| 44.100 Hz | 22.050 Hz | Audio CD, música de consumo |
| 48.000 Hz | 24.000 Hz | Producción de vídeo profesional |
| 96.000 Hz | 48.000 Hz | Audio de alta resolución |
| 192.000 Hz | 96.000 Hz | Estudio de alta gama / masterización |
Procesamiento WAV con Python
Módulo wave de la Biblioteca Estándar
import wave, struct
with wave.open('entrada.wav', 'rb') as wf:
n_canales = wf.getnchannels()
ancho_muest = wf.getsampwidth() # bytes por muestra
tasa_frames = wf.getframerate()
n_frames = wf.getnframes()
duracion = n_frames / tasa_frames
print(f"Canales : {n_canales}")
print(f"Profundidad : {ancho_muest*8} bits")
print(f"Tasa : {tasa_frames} Hz")
print(f"Duración : {duracion:.3f} s")
datos_brutos = wf.readframes(n_frames)
# Desempaquetar muestras estéreo de 16 bits
n_muestras = n_frames * n_canales
muestras = struct.unpack(f'<{n_muestras}h', datos_brutos)
NumPy y SciPy para Procesamiento de Señal
import numpy as np
import scipy.io.wavfile as wav
import scipy.signal as signal
# Leer WAV
tasa, datos = wav.read('entrada.wav')
print(f"Forma: {datos.shape}, dtype: {datos.dtype}, tasa: {tasa} Hz")
# Normalizar a float −1.0 a +1.0
if datos.dtype == np.int16:
datos_float = datos.astype(np.float32) / 32768.0
# Aplicar un filtro pasa-bajo a 8 kHz
sos = signal.butter(10, 8000, fs=tasa, btype='low', output='sos')
filtrado = signal.sosfilt(sos, datos_float, axis=0)
# Escribir resultado filtrado
wav.write('filtrado.wav', tasa, (filtrado * 32767).astype(np.int16))
soundfile para Soporte de Formatos Avanzados
import soundfile as sf
# Leer WAV de 24 bits o 32 bits float
datos, tasa_muestreo = sf.read('estudio_24bit.wav')
print(f"Forma: {datos.shape}, tasa: {tasa_muestreo}, dtype: {datos.dtype}")
# Escribir WAV de 24 bits
sf.write('salida_24bit.wav', datos, tasa_muestreo, subtype='PCM_24')
# Escribir WAV de 32 bits float
sf.write('salida_32f.wav', datos, tasa_muestreo, subtype='FLOAT')
# Subtipos disponibles: PCM_8, PCM_16, PCM_24, PCM_32, FLOAT, DOUBLE
WAV vs Otros Formatos de Audio
| Formato | Sin pérdida | Comprimido | Máx. profundidad bits | Uso profesional |
|---|---|---|---|---|
| WAV | Sí | No | 32 bits float | Universal |
| AIFF | Sí | No | 32 bits float | Apple/Pro |
| FLAC | Sí | Sí (~55% WAV) | 32 bits int | Archivo/entrega |
| BWF | Sí | No | 32 bits float | Radiodifusión |
| RF64 | Sí | No | 32 bits float | Archivos >4 GB |
| MP3 | No | Sí | 16 bits | Consumo |
El límite de 4 GB de WAV: El campo de tamaño del bloque RIFF estándar es un entero sin signo de 32 bits, limitando los archivos WAV a ~4 GB (aproximadamente 6,4 horas a 44,1 kHz 16 bits estéreo). Para grabaciones más largas, usa RF64 (EBU R94) que extiende los campos de tamaño a 64 bits — FFmpeg escribe RF64 automáticamente cuando el contenido superaría los 4 GB.
Errores Comunes
- El desajuste de tasa de muestreo provoca reproducción a velocidad de ardilla o en cámara lenta. Si una DAW lee un archivo de 96 kHz como 48 kHz, lo reproduce a mitad de velocidad con la mitad del tono. Preserva siempre la tasa de muestreo.
- El WAV de 8 bits es sin signo; el de 16 bits+ es con signo. Esta asimetría complica los parsers personalizados — el silencio de 8 bits es 0x80 (128); el de 16 bits es 0x0000 (0).
- 24 bits en un contenedor de 32 bits. Algunos grabadores escriben WAV de 32 bits donde solo 24 bits llevan audio (el byte más bajo siempre es cero).
soundfilelee la profundidad real correctamente;scipy.io.wavfiledevuelve muestras int32 que necesitarías desplazar 8 bits a la derecha. - Metadatos BWF (bloque bext) para flujos de trabajo profesionales. El cine y la radiodifusión requieren BWF con origen de código de tiempo SMPTE, descripción y campos UID en el bloque
bext.
Conversiones relacionadas
Pares de formatos de audio más frecuentes: