import numpy as np import matplotlib.pyplot as plt plt.style.use("bmh") import sounddevice as sd import threading from Notas import Nota, eNotas, tipoNota, modificador class Instrumento(threading.Thread): # Notas: Lista de notas a reproducir # Velocidad: Velocidad de reproduccion (bpm = 1/vel * 60) (1 = 1 negra por segundo) # Volumen: Volumen de reproduccion (0 (silencio) - 1 (maximo)) # Barrier: Barrier para sincronizar los threads def __init__(self, notas: list, velocidad: int, volumen: float, barrier=None): super().__init__() self.notas = notas self.velocidad = velocidad self.barrier = barrier self.volumen = volumen self.fs = 44100 self.stream = sd.OutputStream(samplerate=self.fs, channels=1) self.stream.start() def beep(self, nota: Nota, velocidad: int): # Calculate the duration of the beep in seconds duration = nota.duracion() * velocidad # Calculate the frequency f = nota.frec() # Generate the time values for the samples t = np.linspace(0, duration, int(self.fs * duration), False) # Generate the samples for the sine wave wave = np.sin(f * t * 2 * np.pi) # Ensure that highest value is in 16-bit range audio = wave * (2**15 - 1) / np.max(np.abs(wave)) audio = audio.astype(np.float32) # Apply volume audio = audio * self.volumen # Play the audio self.stream.write(audio) def run(self): # Wait for all threads to be ready self.barrier.wait() # Play the notes one by one for nota in self.notas: self.beep(nota, self.velocidad) def close(self): # Close the stream self.stream.close() if __name__ == "__main__": # Cancion de We wish you a merry christmas en Do Mayor, cada linea un compás (3/4) melodia = [Nota(eNotas.SOL, tipoNota.N), Nota(eNotas.DO, tipoNota.N, octava=5), Nota(eNotas.DO, tipoNota.C, octava=5), Nota(eNotas.RE, tipoNota.C, octava=5), Nota(eNotas.DO, tipoNota.C, octava=5), Nota(eNotas.SI, tipoNota.C), Nota(eNotas.LA, tipoNota.N), Nota(eNotas.LA, tipoNota.N), Nota(eNotas.LA, tipoNota.N), Nota(eNotas.RE, tipoNota.N, octava=5), Nota(eNotas.RE, tipoNota.C, octava=5), Nota(eNotas.MI, tipoNota.C, octava=5), Nota(eNotas.RE, tipoNota.C, octava=5), Nota(eNotas.DO, tipoNota.C, octava=5), Nota(eNotas.SI, tipoNota.N), Nota(eNotas.SOL, tipoNota.N), Nota(eNotas.SOL, tipoNota.N), Nota(eNotas.MI, tipoNota.N, octava=5), Nota(eNotas.MI, tipoNota.C, octava=5), Nota(eNotas.FA, tipoNota.C, octava=5), Nota(eNotas.MI, tipoNota.C, octava=5), Nota(eNotas.RE, tipoNota.C, octava=5), Nota(eNotas.DO, tipoNota.N, octava=5), Nota(eNotas.LA, tipoNota.N), Nota(eNotas.SOL, tipoNota.C), Nota(eNotas.SOL, tipoNota.C), Nota(eNotas.LA, tipoNota.N), Nota(eNotas.RE, tipoNota.N, octava=5), Nota(eNotas.SI, tipoNota.N), Nota(eNotas.DO, tipoNota.B, octava=5),Nota(eNotas.SOL, tipoNota.N), Nota(eNotas.DO, tipoNota.N, octava=5), Nota(eNotas.DO, tipoNota.N, octava=5), Nota(eNotas.DO, tipoNota.N, octava=5), Nota(eNotas.SI, tipoNota.B), Nota(eNotas.SI, tipoNota.N), Nota(eNotas.DO, tipoNota.N, octava=5), Nota(eNotas.SI, tipoNota.N), Nota(eNotas.LA, tipoNota.N), Nota(eNotas.SOL, tipoNota.B), Nota(eNotas.RE, tipoNota.N, octava=5), Nota(eNotas.MI, tipoNota.N, octava=5), Nota(eNotas.RE, tipoNota.N, octava=5), Nota(eNotas.DO, tipoNota.C, octava=5), Nota(eNotas.DO, tipoNota.C, octava=5), Nota(eNotas.SOL, tipoNota.N, octava=5), Nota(eNotas.SOL, tipoNota.N), Nota(eNotas.SOL, tipoNota.C), Nota(eNotas.SOL, tipoNota.C), Nota(eNotas.LA, tipoNota.N), Nota(eNotas.RE, tipoNota.N, octava=5), Nota(eNotas.SI, tipoNota.N), Nota(eNotas.DO, tipoNota.B, octava=5), Nota(eNotas.SOL, tipoNota.N), Nota(eNotas.DO, tipoNota.N, octava=5), Nota(eNotas.DO, tipoNota.C, octava=5), Nota(eNotas.RE, tipoNota.C, octava=5), Nota(eNotas.DO, tipoNota.C, octava=5), Nota(eNotas.SI, tipoNota.C), Nota(eNotas.LA, tipoNota.N), Nota(eNotas.LA, tipoNota.N), Nota(eNotas.LA, tipoNota.N), Nota(eNotas.RE, tipoNota.N, octava=5), Nota(eNotas.RE, tipoNota.C, octava=5), Nota(eNotas.MI, tipoNota.C, octava=5), Nota(eNotas.RE, tipoNota.C, octava=5), Nota(eNotas.DO, tipoNota.C, octava=5), Nota(eNotas.SI, tipoNota.N), Nota(eNotas.SOL, tipoNota.N), Nota(eNotas.SOL, tipoNota.N), Nota(eNotas.MI, tipoNota.N, octava=5), Nota(eNotas.MI, tipoNota.C, octava=5), Nota(eNotas.FA, tipoNota.C, octava=5), Nota(eNotas.MI, tipoNota.C, octava=5), Nota(eNotas.RE, tipoNota.C, octava=5), Nota(eNotas.DO, tipoNota.N, octava=5), Nota(eNotas.LA, tipoNota.N), Nota(eNotas.SOL, tipoNota.C), Nota(eNotas.SOL, tipoNota.C), Nota(eNotas.LA, tipoNota.N), Nota(eNotas.RE, tipoNota.N, octava=5), Nota(eNotas.SI, tipoNota.N), Nota(eNotas.DO, tipoNota.B, octava=5)] acompañamiento = [Nota(eNotas.SILENCIO, tipoNota.N), Nota(eNotas.MI, tipoNota.BP, octava=3), Nota(eNotas.LA, tipoNota.BP, octava=3), Nota(eNotas.FA, tipoNota.BP, octava=3, modificador=modificador.SS), Nota(eNotas.SI, tipoNota.BP, octava=3), Nota(eNotas.LA, tipoNota.BP, octava=3, modificador=modificador.BE), Nota(eNotas.DO, tipoNota.BP), Nota(eNotas.FA, tipoNota.B, octava=3), Nota(eNotas.SI, tipoNota.N, octava=3), Nota(eNotas.DO, tipoNota.B, octava=3), Nota(eNotas.SILENCIO, tipoNota.N), Nota(eNotas.MI, tipoNota.BP, octava=3), Nota(eNotas.SI, tipoNota.BP, octava=3), Nota(eNotas.LA, tipoNota.BP, octava=3), Nota(eNotas.MI, tipoNota.BP, octava=3), Nota(eNotas.MI, tipoNota.BP, octava=3), Nota(eNotas.SOL, tipoNota.BP, octava=3), Nota(eNotas.FA, tipoNota.B, octava=3), Nota(eNotas.SI, tipoNota.N, octava=3), Nota(eNotas.DO, tipoNota.B, octava=3), Nota(eNotas.SILENCIO, tipoNota.N), Nota(eNotas.MI, tipoNota.BP, octava=3), Nota(eNotas.LA, tipoNota.BP, octava=3), Nota(eNotas.FA, tipoNota.BP, octava=3, modificador=modificador.SS), Nota(eNotas.SI, tipoNota.BP, octava=3), Nota(eNotas.LA, tipoNota.BP, octava=3, modificador=modificador.BE), Nota(eNotas.DO, tipoNota.BP), Nota(eNotas.FA, tipoNota.B, octava=3), Nota(eNotas.SI, tipoNota.N, octava=3), Nota(eNotas.DO, tipoNota.B, octava=3)] #Create the barrier barrier = threading.Barrier(2) #Create the threads instrumento1 = Instrumento(melodia, 0.5, 1, barrier) instrumento2 = Instrumento(acompañamiento, 0.5, 0.5, barrier) #Start both threads instrumento1.start() instrumento2.start() #Wait for both threads to finish instrumento1.join() instrumento2.join() #Close the streams instrumento1.close() instrumento2.close()