Material Muestreo Clase Virtual

Material Muestreo Clase Virtual

de PEREZ SEBASTIAN GABRIEL -
Número de respuestas: 0

 

 

import numpy as np
from scipy.io import wavfile
import matplotlib.pyplot as plt

# --- 1. GENERACIÓN DE AUDIO CON ARMÓNICOS Y ENVOLVENTE ---
sample_rate = 44100  # Frecuencia de muestreo (Hz)
note_duration = 0.5  # Duración de cada nota (segundos)

notes = [
    ("Do4", 261.63),
    ("Mi4", 329.63),
    ("Sol4", 392.00),
    ("Do5", 523.25)
]

harmonics = [(1, 1.00), (2, 0.50), (3, 0.25), (4, 0.125)]

audio_signal = np.array([], dtype=np.float32)
note_signals = []  # Para guardar cada nota de forma individual
time_single_note = np.linspace(0, note_duration, int(sample_rate * note_duration), endpoint=False)

for name, freq in notes:
    envelope = np.exp(-3 * time_single_note)
    note_wave = np.zeros_like(time_single_note)
    for mult, weight in harmonics:
        note_wave += weight * np.sin(2 * np.pi * (freq * mult) * time_single_note)
    note_wave *= envelope
    note_signals.append((name, note_wave))
    audio_signal = np.concatenate((audio_signal, note_wave))

# Normalizar señal completa y las notas individuales con la misma escala
max_amp = np.max(np.abs(audio_signal))
audio_signal /= max_amp
note_signals = [(name, wave / max_amp) for name, wave in note_signals]

# Guardar archivo .wav
wavfile.write("melodia_armonicos.wav", sample_rate, (audio_signal * 32767).astype(np.int16))

total_duration = len(audio_signal) / sample_rate
time_vector = np.linspace(0, total_duration, len(audio_signal), endpoint=False)

# ==========================================
# IMAGEN 1: SEÑALES TEMPORALES (COMPLETA + NOTAS INDIVIDUALES)
# ==========================================
fig1, axes = plt.subplots(5, 1, figsize=(10, 10), sharex=False)

# Signal Completa
axes[0].plot(time_vector, audio_signal, color='#2ca02c', linewidth=0.6)
axes[0].set_title("Señal Completa en el Dominio del Tiempo", fontsize=11, fontweight='bold')
axes[0].set_ylabel("Amplitud")
axes[0].set_xlim(0, total_duration)
axes[0].set_ylim(-1.1, 1.1)
axes[0].grid(True, alpha=0.3)

# Notas Individuales
colors = ['#1f77b4', '#ff7f0e', '#d62728', '#9467bd']
for i, (name, wave) in enumerate(note_signals):
    ax = axes[i + 1]
    ax.plot(time_single_note, wave, color=colors[i], linewidth=0.7)
    ax.set_title(f"Nota Individual: {name}", fontsize=10)
    ax.set_ylabel("Amplitud")
    ax.set_xlim(0, note_duration)
    ax.set_ylim(-1.1, 1.1)
    ax.grid(True, alpha=0.3)
    if i == 3:
        ax.set_xlabel("Tiempo por Nota (segundos)")

plt.tight_layout()
plt.savefig("1_senial_temporal.png")
plt.close(fig1)

# ==========================================
# IMAGEN 2: TRANSFORMADA DE FOURIER (FFT LINEAL)
# ==========================================
N = len(audio_signal)
fft_spectrum = np.fft.rfft(audio_signal)
freqs = np.fft.rfftfreq(N, 1 / sample_rate)
magnitude = np.abs(fft_spectrum) / N

fig2, ax = plt.subplots(figsize=(10, 5))
ax.plot(freqs, magnitude, color='#1f77b4', linewidth=0.9)
ax.set_title("Transformada Rápida de Fourier (FFT Lineal) - Señal Completa", fontsize=11, fontweight='bold')
ax.set_xlabel("Frecuencia (Hz)")
ax.set_ylabel("Amplitud Lineal")
ax.set_xlim(0, 2500)
ax.set_ylim(0, np.max(magnitude) * 1.1)
ax.grid(True, alpha=0.3)

plt.tight_layout()
plt.savefig("2_fft_lineal.png")
plt.close(fig2)

# ==========================================
# IMAGEN 3: ESPECTROGRAMA
# ==========================================
fig3, ax = plt.subplots(figsize=(10, 5))
Pxx, freqs_spec, bins, im = ax.specgram(
    audio_signal,
    Fs=sample_rate,
    NFFT=1024,
    noverlap=512,
    cmap='magma'
)
ax.set_title("Espectrograma de la Melodía (Frecuencia vs Tiempo)", fontsize=11, fontweight='bold')
ax.set_xlabel("Tiempo (segundos)")
ax.set_ylabel("Frecuencia (Hz)")
ax.set_ylim(0, 2500)
ax.grid(True, alpha=0.3)

cbar = fig3.colorbar(im, ax=ax)
cbar.set_label("Intensidad (dB)")

plt.tight_layout()
plt.savefig("3_espectrograma.png")
plt.close(fig3)

print("Generated 3 separate images successfully")