File size: 4,771 Bytes
014496b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
869ad40
014496b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60c0f74
014496b
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# -*- coding: utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt
import librosa
import librosa.display
from pydub import AudioSegment
import subprocess
import gradio as gr

# Encabezado personalizado para Gradio
encabezado = """
Este programa permite analizar un archivo de audio (.mp3 o .wav) mediante la Transformada Rápida de Fourier (FFT) y la generación de un espectrograma.
Desarrollado por José R. Leonett, para el Grupo de Peritos Forenses Digitales de Guatemala www.forensedigital.gt
"""

def obtener_info_audio(archivo_audio):
    """
    Obtiene información técnica del archivo de audio usando ffprobe.
    """
    try:
        resultado = subprocess.run(
            ["ffprobe", "-v", "error", "-show_format", "-show_streams", archivo_audio],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            text=True
        )
        if resultado.returncode != 0:
            return "Error al obtener información del archivo de audio."
        return resultado.stdout
    except Exception as e:
        return f"Error: {e}"

def analizar_transcodificacion(info_audio):
    """
    Analiza si el archivo está transcodificado comparando el codec con el formato.
    """
    if not info_audio:
        return "No se pudo obtener información del archivo."

    codec = None
    formato = None
    for linea in info_audio.split("\n"):
        if linea.startswith("codec_name="):
            codec = linea.split("=")[1]
        if linea.startswith("format_name="):
            formato = linea.split("=")[1]

    if codec and formato:
        if codec.lower() == formato.lower():
            return f"El archivo NO está transcodificado. El codec '{codec}' coincide con el formato '{formato}'."
        else:
            return f"El archivo ESTÁ transcodificado. El codec '{codec}' NO coincide con el formato '{formato}'."
    else:
        return "No se pudo determinar si el archivo está transcodificado."

def procesar_audio(archivo_audio):
    # Cargar el archivo de audio
    y, sr = librosa.load(archivo_audio, sr=None)  # sr=None mantiene la frecuencia de muestreo original

    # Obtener información técnica del archivo
    info_audio = obtener_info_audio(archivo_audio)
    info_audio_str = "\nInformación técnica del archivo:\n" + info_audio

    # Analizar si el archivo está transcodificado
    resultado_transcodificacion = analizar_transcodificacion(info_audio)
    transcodificacion_str = "\nAnálisis de transcodificación:\n" + resultado_transcodificacion

    # Crear una figura para las gráficas
    fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(12, 12))

    # Gráfica de la forma de onda
    librosa.display.waveshow(y, sr=sr, ax=ax1)
    ax1.set_title('Forma de Onda del Audio')
    ax1.set_xlabel('Tiempo (s)')
    ax1.set_ylabel('Amplitud')
    ax1.grid()

    # Transformada Rápida de Fourier (FFT)
    fft = np.fft.fft(y)  # Calcula la FFT
    magnitudes = np.abs(fft)  # Obtiene las magnitudes de la FFT
    frecuencias = np.fft.fftfreq(len(y), d=1/sr)  # Frecuencias correspondientes a la FFT
    ax2.plot(frecuencias[:len(frecuencias)//2], magnitudes[:len(magnitudes)//2])
    ax2.set_title('Transformada Rápida de Fourier (FFT)')
    ax2.set_xlabel('Frecuencia (Hz)')
    ax2.set_ylabel('Magnitud')
    ax2.grid()

    # Representación del espectrograma
    espectrograma = librosa.feature.melspectrogram(y=y, sr=sr)  # Calcula el espectrograma
    espectrograma_db = librosa.power_to_db(espectrograma, ref=np.max)  # Convierte a dB
    librosa.display.specshow(espectrograma_db, x_axis='time', y_axis='mel', sr=sr, fmax=8000, ax=ax3)
    fig.colorbar(ax3.collections[0], ax=ax3, format='%+2.0f dB')
    ax3.set_title('Espectograma')
    ax3.set_xlabel('Tiempo (s)')
    ax3.set_ylabel('Frecuencia (Hz)')

    # Ajustar el layout
    plt.tight_layout()

    # Guardar la figura como una imagen
    ruta_imagen = "graficas.png"
    plt.savefig(ruta_imagen)
    plt.close()

    # Mensaje de crédito
    creditos_str = "\nDesarrollado por José R. Leonett"

    # Devolver la imagen y los resultados de texto
    return ruta_imagen, info_audio_str + transcodificacion_str + creditos_str

# Función para manejar la interfaz de Gradio
def procesar_audio_gradio(archivo_audio):
    return procesar_audio(archivo_audio)

# Crear la interfaz de Gradio
iface = gr.Interface(
    fn=procesar_audio_gradio,
    inputs=gr.Audio(type="filepath", label="Sube tu archivo de audio (.mp3 o .wav)"),
    outputs=[gr.Image(label="Gráficas"), gr.Textbox(label="Resultados")],
    title=" 🎧 Análisis de Audio con FFT y Espectograma",  # Título de la interfaz
    description=encabezado,  # Encabezado personalizado
    allow_flagging="never"
)

# Lanzar la interfaz de Gradio
iface.launch()