GhostAcademy logo GhostAcademy
HackConRD 2026 · Informática Forense

Audio Forense:
El Trío de Poder

Investigación Digital Avanzada con Audacity, Python y FFmpeg

👁️
Audacity
El Ojo
⚙️
FFmpeg
El Motor
🧠
Python
El Cerebro
4
Fases forenses
Open
Source 100%
USD 3.98B
Mercado 2033
Cadena de custodia digital Detección de deepfakes Análisis espectral Diarización de hablantes Esteganografía
🎯

Introducción y Contexto

La evidencia digital en formato audio tiene un papel cada vez más relevante en investigaciones criminales, juicios civiles y análisis de inteligencia. El aumento del cibercrimen y la sofisticación de los Deepfakes impulsan una demanda sin precedentes de profesionales capaces de autenticar, manipular y analizar grabaciones de audio.

USD 3.98B
Proyección del mercado global de audio forense para 2033 (DataIntelo)
13.3% CAGR
Tasa de crecimiento anual compuesto (2024–2029) en tecnologías forenses (Technavio)

En este laboratorio trabajaremos con el "Trío de Poder": tres herramientas de código abierto que, combinadas, ofrecen capacidades comparables al software propietario de alto coste. Aprenderás a aplicar el pipeline forense completo sobre evidencia de audio real.

💻

Entorno recomendado: Kali Linux, Ubuntu 22.04/24.04 o macOS. Todo el software es multiplataforma y gratuito. Necesitarás una carpeta de trabajo llamada ~/lab-forense/ que crearemos en el paso 2.

🧰

El Trío de Herramientas

Audacity
👁️ El Ojo
Edición manual precisa, análisis visual de espectrogramas y validación humana. Es la interfaz de confirmación final. Referenciado en guías internacionales como estándar para la exploración y pre-análisis visual.
FFmpeg
⚙️ El Motor
Procesamiento de metadatos, conversión masiva y manejo de la estructura del contenedor. Permite automatizar la ingesta de cientos de archivos y garantizar la trazabilidad forense mediante hashes criptográficos.
Python
🧠 El Cerebro
Automatización, Inteligencia Artificial (IA) y análisis de grandes volúmenes de datos. Bibliotecas como Librosa, Mutagen, pyAudioAnalysis o pyannote-audio permiten análisis que serían imposibles manualmente.
⚖️

Referencia SWGDE: El uso de herramientas de línea de comandos permite generar reportes auditables y reproducibles, condición indispensable para que la evidencia sea admisible en un proceso judicial.

🔧

Preparar el Entorno

1

Crear la estructura de directorios del laboratorio:

mkdir -p ~/lab-forense/{evidencia,procesado,reportes,hashes}
cd ~/lab-forense
echo "Directorio de trabajo: $(pwd)"
2

Instalar FFmpeg y ffprobe:

# En Ubuntu/Kali
sudo apt update && sudo apt install -y ffmpeg

# Verificar instalación
ffmpeg -version | head -1
ffprobe -version | head -1
3

Instalar las bibliotecas Python necesarias:

# Instalar todas las dependencias del laboratorio
pip3 install librosa mutagen numpy scipy matplotlib \
             pyAudioAnalysis torch torchaudio \
             pyannote.audio soundfile

# Verificar librosa (la más importante)
python3 -c "import librosa; print('librosa', librosa.__version__)"
4

Instalar Audacity:

# En Ubuntu/Kali
sudo apt install -y audacity

# O desde Flatpak (versión más actualizada)
flatpak install flathub org.audacityteam.Audacity
5

Descargar un archivo de audio de práctica (usaremos este archivo WAV libre de derechos a lo largo de todo el laboratorio):

# Descargar fichero de audio de práctica (voz real, 44.1kHz, stereo)
wget -O ~/lab-forense/evidencia/evidencia_01.wav \
  "https://www2.cs.uic.edu/~i101/SoundFiles/BabyElephantWalk60.wav"

# Verificar que se descargó correctamente
ls -lh ~/lab-forense/evidencia/evidencia_01.wav
💡

Si no tienes conexión, puedes usar cualquier archivo .mp3, .wav o .flac de tu equipo. Renómbralo a evidencia_01.wav y cópialo a ~/lab-forense/evidencia/.

🔄

Pipeline Forense Integrado

Todo análisis forense de audio debe seguir un flujo de trabajo estructurado y documentado. El pipeline de este laboratorio sigue el estándar de minimizar la intervención manual y maximizar la reproducibilidad.

⚙️
FFmpeg
Ingesta
Extracción + Hash
→
🧠
Python
Análisis
ML · Diarización · Deepfakes
→
👁️
Audacity
Validación
Confirmación Visual
→
📄
Informe
Peritaje
Cadena de custodia
🏛️

Principio fundamental: En informática forense, ninguna operación se realiza sobre la evidencia original. Siempre se trabaja sobre una copia forense verificada cuyo hash SHA256 coincide con el original.

📥

Fase 1: Ingesta y Metadatos

FFmpeg
01

Detección de incoherencias técnicas antes del análisis auditivo

Antes de escuchar un solo segundo de audio, debemos extraer todos los metadatos técnicos del archivo. Un micrófono real, una grabadora o un teléfono producen un perfil técnico muy específico que un archivo manipulado o sintético suele alterar.

  • Identificación de Códecs
  • Tasa de Muestreo (Sample Rate)
  • Timestamps modificados

Análisis básico con ffprobe

1

Extraer metadatos completos en formato JSON (alineado con el comando de la presentación):

ffprobe -v quiet \
        -print_format json \
        -show_format \
        -show_streams \
        ~/lab-forense/evidencia/evidencia_01.wav
// Salida esperada (extracto)
{
  "format": {
    "filename": "evidencia_01.wav",
    "nb_streams": 1,
    "format_name": "wav",
    "duration": "124.500000",
    "bit_rate": "1411200",
    "tags": {
      "encoder": "Lavf58.76.100"
    }
  },
  "streams": [{
    "codec_name": "pcm_s16le",
    "sample_rate": "44100",
    "channels": 2,
    "channel_layout": "stereo"
  }]
}
2

Extraer solo los campos relevantes para el informe forense:

# Formato resumido para el informe
ffprobe -v quiet \
  -print_format json \
  -show_entries format=filename,duration,bit_rate,format_name \
  -show_entries stream=codec_name,sample_rate,channels,bits_per_sample \
  ~/lab-forense/evidencia/evidencia_01.wav
3

Detectar inconsistencias de bitrate — una señal de alerta de manipulación:

# Un archivo MP3 de 320kbps que en realidad tiene 128kbps indica
# que fue re-codificado (posible manipulación)
ffprobe -v quiet \
  -print_format json \
  -show_entries stream=bit_rate,codec_name \
  ~/lab-forense/evidencia/evidencia_01.wav | \
  python3 -c "import json,sys; d=json.load(sys.stdin); \
  [print(f'Codec: {s[\"codec_name\"]} | Bitrate: {s.get(\"bit_rate\",\"N/A\")} bps') \
  for s in d.get('streams',[])]"
⚠️

Señales de alerta en los metadatos:

  • Sample rate inusual para el dispositivo declarado (ej. teléfono a 96kHz)
  • Codec de codificación diferente al formato del contenedor
  • Encoder tag de software de edición (Audacity, Adobe Audition, etc.)
  • Fecha de modificación posterior a la fecha de grabación declarada
  • Duration que no coincide con la duración real del audio útil

Análisis masivo con Python + Mutagen

Cuando el caso involucra cientos o miles de archivos de audio (datos de un servidor, grabaciones de call center, etc.), necesitamos automatizar la detección de anomalías.

1

Script de análisis masivo — detecta archivos con bitrate inconsistente:

#!/usr/bin/env python3
# archivo: ~/lab-forense/analisis_masivo.py
# Detecta anomalías de bitrate en un directorio de evidencias

import mutagen
import os, json
from pathlib import Path

# Bitrate esperado para todos los archivos (en bps)
BITRATE_ESPERADO = 320000
DIRECTORIO = "/root/lab-forense/evidencia"

anomalias = []
procesados = 0

def flag_evidence(filepath, bitrate_real):
    """Registra el archivo como sospechoso."""
    anomalias.append({
        "archivo": filepath,
        "bitrate_real": bitrate_real,
        "bitrate_esperado": BITRATE_ESPERADO,
        "diferencia": abs(bitrate_real - BITRATE_ESPERADO)
    })

dataset = list(Path(DIRECTORIO).rglob("*.mp3")) + \
          list(Path(DIRECTORIO).rglob("*.wav")) + \
          list(Path(DIRECTORIO).rglob("*.flac"))

for file in dataset:
    try:
        audio = mutagen.File(file)
        if audio is None:
            continue
        bitrate = getattr(audio.info, 'bitrate', 0) * 1000
        if bitrate != BITRATE_ESPERADO:
            flag_evidence(str(file), bitrate)
        procesados += 1
    except Exception as e:
        print(f"[ERROR] {file}: {e}")

# Mostrar resultados
print(f"\n{'='*50}")
print(f"Archivos procesados: {procesados}")
print(f"Anomalías detectadas: {len(anomalias)}")
print(f"\n[ANOMALÍAS]")
for a in anomalias:
    print(f"  ⚑ {a['archivo']}")
    print(f"    Esperado: {a['bitrate_esperado']}bps | Real: {a['bitrate_real']}bps")

# Guardar reporte JSON
with open("/root/lab-forense/reportes/anomalias.json", "w") as f:
    json.dump(anomalias, f, indent=2)

Ejecutar con: python3 ~/lab-forense/analisis_masivo.py

🔒

Integridad de la Evidencia Digital

Cadena de Custodia

La cadena de custodia digital garantiza que la evidencia no ha sido alterada desde su incautación hasta la corte. El mecanismo técnico es el hash criptográfico: si un solo bit del archivo cambia, el hash cambia completamente.

1

Calcular el hash SHA256 del bitstream de audio usando FFmpeg (método forense preferido sobre sha256sum del archivo contenedor):

# Método forense: hash del CONTENIDO AUDIO, no del contenedor
ffmpeg -i ~/lab-forense/evidencia/evidencia_01.wav \
       -map 0:a \
       -f hash \
       -hash SHA256 \
       - 2>/dev/null
◈ Ejemplo de salida — guardar en cadena de custodia
SHA256: 5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
2

Calcular y guardar el hash del archivo completo con sha256sum:

# Hash del fichero completo + nombre → guardar en registro de custodia
sha256sum ~/lab-forense/evidencia/evidencia_01.wav \
  | tee ~/lab-forense/hashes/evidencia_01.sha256

# Verificar integridad (ejecutar antes y después del análisis)
sha256sum --check ~/lab-forense/hashes/evidencia_01.sha256
# Salida esperada: evidencia_01.wav: OK
3

Script Python para registrar múltiples evidencias con timestamp de incautación:

#!/usr/bin/env python3
# registro_custodia.py — crea el acta de cadena de custodia

import hashlib, json, datetime
from pathlib import Path

def hash_archivo(filepath):
    sha256 = hashlib.sha256()
    with open(filepath, 'rb') as f:
        while chunk := f.read(8192):
            sha256.update(chunk)
    return sha256.hexdigest()

directorio = Path("/root/lab-forense/evidencia")
registro = {
    "caso": "CASO-2026-001",
    "perito": "[Tu nombre]",
    "fecha_incautacion": datetime.datetime.now().isoformat(),
    "evidencias": []
}

for archivo in directorio.glob("*.*"):
    entry = {
        "nombre": archivo.name,
        "tamaño_bytes": archivo.stat().st_size,
        "sha256": hash_archivo(archivo),
        "timestamp": datetime.datetime.now().isoformat()
    }
    registro["evidencias"].append(entry)
    print(f"✓ {archivo.name}: {entry['sha256'][:16]}...")

with open("/root/lab-forense/reportes/cadena_custodia.json", "w") as f:
    json.dump(registro, f, indent=2, ensure_ascii=False)
print("\n✅ Registro de cadena de custodia guardado.")
🎛️

Fase 2: Mejora y Limpieza Manual

Audacity
02

Preparar el audio para el análisis pericial

Antes del análisis automatizado, el perito debe limpiar el audio para mejorar la inteligibilidad de voces y revelar anomalías ocultas en la señal. Herramienta: Audacity.

  • Reducción de ruido
  • Filtros de paso alto/bajo
  • Inversión de fases

Proceso de reducción de ruido en Audacity

1

Abrir el archivo de evidencia y crear una copia de trabajo:

  • Abre Audacity y arrastra evidencia_01.wav a la pista de audio.
  • Antes de cualquier edición, ve a File → Save Project As y guarda como trabajo_01.aup3. Así preservas el original intacto.
2

Obtener el perfil de ruido (paso obligatorio):

  1. Localiza una sección de silencio o ruido de fondo sin voz (2-3 segundos).
  2. Selecciona esa sección con el ratón.
  3. Ve a Effect → Noise Reduction.
  4. Haz clic en "Get Noise Profile". Audacity aprende cómo suena el ruido.
💡

Cuanto más representativa sea la muestra de ruido, mejor será la reducción. Busca siempre un fragmento donde solo suene el ruido de fondo sin interferencias de voces.

3

Aplicar la reducción de ruido:

  1. Selecciona todo el audio (Ctrl+A).
  2. Ve a Effect → Noise Reduction de nuevo.
  3. Ajusta los parámetros:
    — Noise reduction (dB): 12 dB (empezar conservador)
    — Sensitivity: 6.00
    — Frequency smoothing: 3 bands
  4. Haz clic en OK.

Filtros de paso alto y bajo

4

Filtro paso alto (elimina zumbidos graves de 50/60Hz de la red eléctrica):

  • Selecciona todo (Ctrl+A).
  • Ve a Effect → High Pass Filter.
  • Frecuencia de corte: 80 Hz · Rolloff: 12 dB/octave
  • Esto elimina el hum de fondo típico de grabaciones en interiores.
5

Filtro paso bajo (aislar la frecuencia de la voz humana):

  • Ve a Effect → Low Pass Filter.
  • Frecuencia de corte: 8000 Hz · Rolloff: 12 dB/octave
  • La voz humana está entre 80 Hz y 8 kHz. Aislarla mejora la inteligibilidad.

Análisis del espectrograma (lo que el oído no escucha)

🔬

Principio clave: El espectrograma convierte la señal de audio en una representación visual tiempo-frecuencia. Las manipulaciones que son inaudibles dejan siempre una huella visual inequívoca en el espectrograma.

6

Activar la vista de espectrograma en Audacity:

  1. Haz clic en la flecha junto al nombre de la pista (parte izquierda).
  2. Selecciona "Spectrogram".
  3. Para mayor detalle: clic derecho en la escala de frecuencias → Spectrogram Settings → Window size: 2048.
7

Qué buscar en el espectrograma — señales de manipulación:

Corte Abrupto (Splice Point)
Línea vertical perfectamente recta donde el ruido de fondo cambia bruscamente. Indica un corte y empalme.
Discontinuidad Espectral
Cambio brusco en el patrón de armónicos. Normal en cambios de locutor, anormal en medio de una frase.
Ruido Residual Inconsistente
El ruido de fondo cambia de características en distintas partes de la misma grabación.
Frecuencias Fantasma
Armónicos artificialmente perfectos o ausencia total de ruido de fondo (señal sintética).
Tono de Referencia
Línea horizontal perfectamente recta y constante. Puede ser un tono de calibración o una inserción sintética.
Zona de Silencio Absoluto
Negro total (energía cero). En grabaciones reales siempre hay algo de ruido de fondo. El silencio absoluto es sospechoso.
⚙️

Automatización del Preprocesamiento con FFmpeg

FFmpeg Pipeline

Cuando hay más de 10 archivos, Audacity se vuelve ineficiente. FFmpeg permite aplicar el mismo procesamiento a cientos de archivos en minutos.

1

Remoción automática de silencios:

ffmpeg -i ~/lab-forense/evidencia/evidencia_01.wav \
  -af silenceremove=1:0:-50dB \
  ~/lab-forense/procesado/sin_silencios.wav
2

Conversión y estandarización de formato (unificar todos los archivos a WAV 16kHz mono):

# Convertir un archivo
ffmpeg -i ~/lab-forense/evidencia/evidencia_01.wav \
  -ac 1 \
  -ar 16000 \
  -sample_fmt s16 \
  ~/lab-forense/procesado/evidencia_01_std.wav

# Convertir TODOS los archivos del directorio (bucle Bash)
for f in ~/lab-forense/evidencia/*.{mp3,wav,flac,m4a}; do
  nombre=$(basename "${f%.*}")
  ffmpeg -i "$f" -ac 1 -ar 16000 -sample_fmt s16 \
    ~/lab-forense/procesado/"${nombre}_std.wav" 2>/dev/null
  echo "✓ Procesado: $nombre"
done
3

Separación de fuentes con Python + Librosa (separar voz del ruido de fondo):

import librosa
import soundfile as sf
import numpy as np

# Cargar el archivo de evidencia
data, sr = librosa.load('~/lab-forense/procesado/evidencia_01_std.wav',
                        sr=None)

# Separar componentes harmónicas (voz) y percusivas (ruido/impactos)
armonica, percusiva = librosa.effects.hpss(data)

# Guardar las componentes separadas
sf.write('~/lab-forense/procesado/voz_separada.wav', armonica, sr)
sf.write('~/lab-forense/procesado/ruido_separado.wav', percusiva, sr)

print(f"✓ Separación completada. Sample rate: {sr} Hz")
print(f"  Duración: {len(data)/sr:.2f} segundos")
🔍

Fase 3: Autenticación y Detección de Fraude

Python
03

Lo que el oído no escucha, el espectrograma lo ve

Esta es la fase central del análisis forense. Detectamos automáticamente cortes, empalmes y manipulaciones que no son perceptibles al oído humano pero que dejan rastros matemáticos inequívocos.

  • Detección de empalmes
  • Análisis de fondo
  • Patrones de frecuencia no naturales

Detección automática de cortes y empalmes

1

Script de detección de empalmes mediante análisis de energía espectral:

#!/usr/bin/env python3
# detector_empalmes.py

import librosa
import librosa.display
import numpy as np
import matplotlib.pyplot as plt
import json

# Cargar evidencia
y, sr = librosa.load('~/lab-forense/procesado/evidencia_01_std.wav')

# Calcular espectrograma de amplitud
D = librosa.amplitude_to_db(
    np.abs(librosa.stft(y)), ref=np.max
)

# Detectar cambios bruscos de energía (posibles cortes)
energia = np.sum(D**2, axis=0)
umbral = np.mean(energia) + 2.5 * np.std(energia)
frames_anomalos = np.where(np.abs(np.diff(energia)) > umbral)[0]

# Convertir frames a segundos
tiempos_anomalos = librosa.frames_to_time(frames_anomalos, sr=sr)

# Generar visualización
fig, axes = plt.subplots(2, 1, figsize=(14, 8))

# Forma de onda
librosa.display.waveshow(y, sr=sr, ax=axes[0], color='#00ff88')
axes[0].set_title('Forma de Onda', color='white')
axes[0].set_facecolor('#0a1018')
for t in tiempos_anomalos:
    axes[0].axvline(x=t, color='red', linewidth=1.5, alpha=0.8)

# Espectrograma
librosa.display.specshow(D, sr=sr, x_axis='time', y_axis='hz',
                         ax=axes[1], cmap='magma')
axes[1].set_title('Espectrograma', color='white')
for t in tiempos_anomalos:
    axes[1].axvline(x=t, color='red', linewidth=1.5, alpha=0.8)

plt.tight_layout()
plt.savefig('~/lab-forense/reportes/analisis_espectral.png',
            dpi=150, facecolor='#060a0f')
plt.show()

# Informe de anomalías
informe = {
    "total_anomalias": len(tiempos_anomalos),
    "puntos_sospechosos": [round(float(t), 3) for t in tiempos_anomalos]
}
print(json.dumps(informe, indent=2))
with open('~/lab-forense/reportes/empalmes.json', 'w') as f:
    json.dump(informe, f, indent=2)
🤖

Combatir Deepfakes e IA Generativa

Python + IA
🚨

El desafío actual: Los deepfakes de voz modernos (ElevenLabs, VoiceClone) pueden engañar al oído humano en más del 95% de los casos. Sin embargo, dejan huellas matemáticas detectables: alta estabilidad del F0 (tono fundamental), entropía espectral anormalmente alta y ausencia de micro-irregularidades naturales.

MétricaVoz humana realVoz sintética (deepfake)
Entropía espectral0.60 – 0.82> 0.90 (excesiva regularidad)
Estabilidad F00.70 – 0.88> 0.95 (tono casi perfecto)
Micro-pausas naturalesPresentes (5-15ms)Ausentes o uniformes
Ruido de respiraciónVariable, orgánicoAusente o sintético
Jitter/Shimmer vocalPresente (~1%)Casi cero
1

Script de detección de deepfakes mediante métricas espectrales:

#!/usr/bin/env python3
# detector_deepfake.py — análisis de métricas para detección de voz sintética

import librosa
import numpy as np

def analizar_autenticidad(ruta_audio):
    y, sr = librosa.load(ruta_audio, sr=None)
    resultados = {}

    # 1. Entropía espectral — valores altos indican voz sintética
    espectro = np.abs(librosa.stft(y))
    espectro_norm = espectro / (np.sum(espectro, axis=0, keepdims=True) + 1e-10)
    entropia = -np.sum(espectro_norm * np.log2(espectro_norm + 1e-10), axis=0)
    resultados["entropia_media"] = float(np.mean(entropia))

    # 2. Estabilidad del tono fundamental (F0)
    f0, voiced_flag, _ = librosa.pyin(y, fmin=50, fmax=400)
    f0_valido = f0[~np.isnan(f0)]
    if len(f0_valido) > 0:
        variacion = np.std(f0_valido) / (np.mean(f0_valido) + 1e-10)
        resultados["estabilidad_f0"] = 1 - min(variacion, 1.0)
    else:
        resultados["estabilidad_f0"] = 0.0

    # 3. Zero Crossing Rate — micro-irregularidades
    zcr = librosa.feature.zero_crossing_rate(y)[0]
    resultados["variabilidad_zcr"] = float(np.std(zcr))

    # 4. Diagnóstico
    e = resultados["entropia_media"]
    f = resultados["estabilidad_f0"]

    if e > 0.90 and f > 0.95:
        diagnostico = "⚠️  POSIBLE DEEPFAKE — métricas fuera de rango natural"
    elif e > 0.85 or f > 0.92:
        diagnostico = "🔍 SOSPECHOSO — requiere análisis adicional"
    else:
        diagnostico = "✅ DENTRO DE PARÁMETROS NORMALES de voz humana"

    resultados["diagnostico"] = diagnostico
    return resultados

# Ejecutar análisis
r = analizar_autenticidad("~/lab-forense/procesado/evidencia_01_std.wav")
print("═══ INFORME DE AUTENTICIDAD ═══")
for k, v in r.items():
    print(f"  {k}: {v:.4f}" if isinstance(v, float) else f"  {k}: {v}")
🕵️

Esteganografía en Audio

CTF · Investigación

La esteganografía es la técnica de ocultar información dentro de otro archivo de modo que su presencia sea imperceptible. En audio forense, es relevante tanto en competiciones CTF como en investigaciones reales de cibercrimen.

1

Analizar si un archivo WAV contiene datos ocultos en los LSB (Least Significant Bits):

#!/usr/bin/env python3
# steg_analyzer.py — análisis de esteganografía en WAV

import wave, numpy as np, sys

def analizar_lsb(ruta_wav):
    with wave.open(ruta_wav, 'rb') as wf:
        frames = wf.readframes(wf.getnframes())
        muestras = np.frombuffer(frames, dtype=np.int16)

    # Extraer bits menos significativos
    lsb = muestras & 1

    # Estadística — si hay datos ocultos, la distribución LSB es no aleatoria
    proporcion_unos = np.mean(lsb)
    entropia_lsb = -(2 * proporcion_unos * np.log2(proporcion_unos + 1e-10))

    print(f"Muestras analizadas: {len(muestras):,}")
    print(f"Proporción LSB=1:    {proporcion_unos:.4f} (esperado ~0.5)")
    print(f"Entropía LSB:        {entropia_lsb:.4f} (max=1.0)")

    if abs(proporcion_unos - 0.5) > 0.05:
        print("\n⚠️  POSIBLE DATOS OCULTOS — distribución LSB anómala")
    else:
        print("\n✅ Distribución LSB normal — no se detectan datos ocultos obvios")

    # Intentar extraer datos ocultos
    print("\n[Primeros 64 bytes de los LSB como texto]:")
    bits = lsb[:512]
    chars = []
    for i in range(0, len(bits), 8):
        byte = 0
        for j, bit in enumerate(bits[i:i+8]):
            byte |= (int(bit) << (7-j))
        if 32 <= byte <= 126:
            chars.append(chr(byte))
        else:
            chars.append('.')
    print(''.join(chars))

analizar_lsb("~/lab-forense/evidencia/evidencia_01.wav")
2

Análisis espectral para detectar datos ocultos en frecuencias ultrasónicas:

import librosa, numpy as np, matplotlib.pyplot as plt

y, sr = librosa.load("~/lab-forense/evidencia/evidencia_01.wav", sr=None)
D = np.abs(librosa.stft(y))

# Energía en banda ultrasónica (>15kHz) — zona sospechosa para datos ocultos
freqs = librosa.fft_frequencies(sr=sr)
mask_ultra = freqs > 15000
energia_ultra = np.mean(D[mask_ultra, :])
energia_total = np.mean(D)
ratio = energia_ultra / (energia_total + 1e-10)

print(f"Energía en banda >15kHz: {energia_ultra:.6f}")
print(f"Ratio respecto al total: {ratio:.4f}")
if ratio > 0.01:
    print("⚠️  ACTIVIDAD ULTRASÓNICA SOSPECHOSA detectada")
else:
    print("✅ Sin actividad ultrasónica anómala")
🧬

Fase 4: Inteligencia y Biometría

Python + ML
04

¿Quién habló, cuándo y qué dijo?

La fase final del análisis forense responde las preguntas de mayor valor judicial: identificar a los hablantes, cuándo interviene cada uno, y detectar eventos acústicos relevantes (disparos, golpes, etc.).

  • Diarización de hablantes
  • Identificación biométrica
  • Detección de eventos

Speaker Diarization — ¿Quién habló y cuándo?

La diarización responde a la pregunta "¿quién habló cuándo?" dividiendo el audio en segmentos y asignando cada uno a un hablante diferente. Usa modelos de ML entrenados en millones de horas de audio.

1

Diarización con pyannote.audio (el estándar de la industria en código abierto):

#!/usr/bin/env python3
# diarizacion.py — identificar hablantes en el audio
# Requiere: pip install pyannote.audio
# Y un token de HuggingFace: https://huggingface.co/settings/tokens

from pyannote.audio import Pipeline
import json

# Cargar el pipeline preentrenado
pipeline = Pipeline.from_pretrained(
    "pyannote/speaker-diarization-3.1",
    use_auth_token="TU_TOKEN_HUGGINGFACE"
)

# Ejecutar diarización
diarization = pipeline("~/lab-forense/procesado/evidencia_01_std.wav")

# Mostrar y guardar resultados
segmentos = []
print("\n═══ DIARIZACIÓN — TIMELINE DE HABLANTES ═══\n")
for turn, _, speaker in diarization.itertracks(yield_label=True):
    seg = {
        "hablante": speaker,
        "inicio": round(turn.start, 2),
        "fin": round(turn.end, 2),
        "duracion": round(turn.end - turn.start, 2)
    }
    segmentos.append(seg)
    print(f"  [{seg['inicio']:6.2f}s - {seg['fin']:6.2f}s]  {speaker}")

with open("~/lab-forense/reportes/diarizacion.json", "w") as f:
    json.dump(segmentos, f, indent=2)
print(f"\n✓ {len(segmentos)} segmentos guardados en reportes/diarizacion.json")
ℹ️

Para usar pyannote, necesitas aceptar las condiciones de uso del modelo en huggingface.co/pyannote/speaker-diarization-3.1 y obtener un token gratuito.

Identificación de hablantes y detección de eventos

2

Extracción de MFCC para comparación biométrica de voz:

#!/usr/bin/env python3
# comparacion_biometrica.py
# Compara la voz de la evidencia con una muestra de referencia

import librosa
import numpy as np
from scipy.spatial.distance import cosine

def extraer_huella_vocal(ruta):
    """Extrae la huella vocal (MFCC) de un archivo de audio."""
    y, sr = librosa.load(ruta, sr=16000)
    # MFCC: representación compacta del timbre vocal
    mfcc = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=40)
    # Estadísticas sobre el tiempo
    huella = np.concatenate([
        np.mean(mfcc, axis=1),
        np.std(mfcc, axis=1)
    ])
    return huella

# Evidencia vs. muestra de referencia
huella_evidencia  = extraer_huella_vocal("~/lab-forense/procesado/voz_separada.wav")
huella_referencia = extraer_huella_vocal("~/lab-forense/evidencia/muestra_referencia.wav")

# Similitud por coseno (1.0 = idéntico, 0.0 = completamente diferente)
similitud = 1 - cosine(huella_evidencia, huella_referencia)
print(f"Similitud biométrica: {similitud:.4f}")

if similitud > 0.85:
    print("✅ COINCIDENCIA ALTA — probable mismo hablante")
elif similitud > 0.65:
    print("🔍 COINCIDENCIA MEDIA — requiere análisis pericial adicional")
else:
    print("❌ COINCIDENCIA BAJA — posiblemente hablantes distintos")
⚠️

Nota pericial importante: La comparación de MFCC es una técnica preliminar de screening. Para admisibilidad judicial, se requiere análisis con herramientas certificadas (Praat, BATVOX) realizadas por un perito acreditado.

📄

Generar el Informe Pericial

El informe pericial es el documento que convierte el análisis técnico en evidencia admisible ante un tribunal. Debe ser reproducible, verificable y trazable.

1

Script que consolida todos los resultados en un informe pericial estructurado:

#!/usr/bin/env python3
# generar_informe.py — Informe pericial completo

import json, datetime, hashlib
from pathlib import Path

def cargar_json(path):
    try:
        return json.loads(Path(path).read_text())
    except:
        return {}

informe = {
    "INFORME_PERICIAL": {
        "numero_caso": "CASO-2026-001",
        "fecha_analisis": datetime.datetime.now().isoformat(),
        "perito": "[Tu nombre y número de colegiado]",
        "herramientas": [
            "FFmpeg 6.0", "Python 3.12 + librosa 0.10", "Audacity 3.4"
        ]
    },
    "CADENA_CUSTODIA": cargar_json("~/lab-forense/reportes/cadena_custodia.json"),
    "ANOMALIAS_BITRATE": cargar_json("~/lab-forense/reportes/anomalias.json"),
    "EMPALMES_DETECTADOS": cargar_json("~/lab-forense/reportes/empalmes.json"),
    "DIARIZACION": cargar_json("~/lab-forense/reportes/diarizacion.json"),
    "CONCLUSION": {
        "autenticidad": "[AUTÉNTICO / MANIPULADO / INDETERMINADO]",
        "confianza": "[ALTA / MEDIA / BAJA]",
        "observaciones": "[Texto de conclusión del perito]"
    }
}

salida = Path("~/lab-forense/reportes/informe_final.json").expanduser()
salida.write_text(json.dumps(informe, indent=2, ensure_ascii=False))
print(f"✅ Informe generado: {salida}")
2

Estructura del informe pericial — campos mínimos requeridos:

◈ INFORME PERICIAL — AUDIO FORENSE
Número de caso:CASO-2026-001
Fecha de análisis:2026-01-15T14:32:00
Perito:[Nombre · Nº Colegiado]
SHA256 evidencia:5e884898da28047...d1542d8
Herramientas:FFmpeg 6.0 · Python 3.12 · Audacity 3.4
Anomalías detectadas:3 cortes, 1 bitrate mismatch
Veredicto de autenticidad:MANIPULADO (confianza: ALTA)
📋

Resumen y Cheatsheet de Referencia

🎉

¡Laboratorio completado! Has aprendido a aplicar el pipeline forense completo de audio: desde la incautación con cadena de custodia hasta la detección de deepfakes y la generación del informe pericial. Herramientas libres. Resultados profesionales. Auditabilidad total.

Comandos FFmpeg de referencia rápida

─── METADATOS ────────────────────────────────────────────────
ffprobe -v quiet -print_format json -show_format -show_streams ARCHIVO

─── INTEGRIDAD ───────────────────────────────────────────────
ffmpeg -i ARCHIVO -map 0:a -f hash -hash SHA256 -
sha256sum ARCHIVO | tee ARCHIVO.sha256

─── CONVERSIÓN / ESTANDARIZACIÓN ────────────────────────────
ffmpeg -i INPUT -ac 1 -ar 16000 -sample_fmt s16 OUTPUT.wav

─── ELIMINAR SILENCIOS ───────────────────────────────────────
ffmpeg -i INPUT -af silenceremove=1:0:-50dB OUTPUT.wav

─── RECORTAR SEGMENTO (desde 30s, durante 60s) ───────────────
ffmpeg -i INPUT -ss 30 -t 60 OUTPUT.wav

─── EXTRAER PISTA DE AUDIO DE UN VÍDEO ──────────────────────
ffmpeg -i video.mp4 -vn -acodec pcm_s16le audio.wav

Capacidades adquiridas

🏛️

Dominar Audacity, Python y FFmpeg no es solo una habilidad técnica; es una ventaja estratégica en la era de la IA y el litigio digital.

— HackConRD 2026 · Informática Forense y Más