From 8f82c447e9a7e737dc0cb8f2debc50dd1240ccab Mon Sep 17 00:00:00 2001 From: fosanz Date: Fri, 15 Dec 2023 22:27:00 +0100 Subject: [PATCH] Cleaned code, added comments for better understanding --- Notas.py | 21 ++++++--------------- polifonia.py | 40 ++++++++++++++++++++++++++++------------ 2 files changed, 34 insertions(+), 27 deletions(-) diff --git a/Notas.py b/Notas.py index 82c6e7d..369e1f8 100644 --- a/Notas.py +++ b/Notas.py @@ -1,6 +1,10 @@ import enum -from math import exp, log +# Cada nota tiene un valor, un tipo, un modificador y una octava +# El valor es un enum de eNotas, cada nota tiene un valor de 1 a 12, yendo de Do a Si en semitonos +# El tipo es un enum de tipoNota, cada tipo tiene un valor de 1 a 48, yendo de Redonda a Semicorchea (con puntillo o no) +# El modificador es un enum de modificador, cada modificador tiene un valor de 1 a 3, siendo 1 sostenido, 2 bemol y 3 ninguno +# La octava es un entero de 0 a 8, siendo 4 la octava central del piano class eNotas(enum.Enum): DO = 1 RE = 3 @@ -26,20 +30,6 @@ class tipoNota(enum.Enum): CP = 24, 0.75 SP = 48, 0.375 - ## Silencios - XR = 1, 4 - XB = 2, 2 - XN = 4, 1 - XC = 8, 0.5 - XS = 16, 0.25 - - ## Silencios con puntillo - XRP = 3, 6 - XBP = 6, 3 - XNP = 12, 1.5 - XCP = 24, 0.75 - XSP = 48, 0.375 - class modificador(enum.Enum): ##Sostenido SS = 1 @@ -64,6 +54,7 @@ class Nota(): return self.tipo.value[1] + # Calcula y devuelve la frecuencia de la nota aplicando la formula def frec(self): expo = self.octava * 12 + (self.nota.value - 58) diff --git a/polifonia.py b/polifonia.py index de099a1..6282876 100644 --- a/polifonia.py +++ b/polifonia.py @@ -1,5 +1,3 @@ -import time -from pydub import AudioSegment import numpy as np import matplotlib.pyplot as plt plt.style.use("bmh") @@ -9,6 +7,10 @@ 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 @@ -20,7 +22,10 @@ class Instrumento(threading.Thread): 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 @@ -33,6 +38,7 @@ class Instrumento(threading.Thread): audio = wave * (2**15 - 1) / np.max(np.abs(wave)) audio = audio.astype(np.float32) + # Apply volume audio = audio * self.volumen # Play the audio @@ -41,10 +47,12 @@ class Instrumento(threading.Thread): 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() @@ -102,13 +110,21 @@ if __name__ == "__main__": Nota(eNotas.DO, tipoNota.B, octava=3)] - barrier = threading.Barrier(2) - instrumento1 = Instrumento(melodia, 0.5, 1, barrier) - instrumento2 = Instrumento(acompañamiento, 0.5, 0.5, barrier) - #Barrier to ensure that both threads start at the same time - instrumento1.start() - instrumento2.start() - instrumento1.join() - instrumento2.join() - instrumento1.close() - instrumento2.close() \ No newline at end of file +#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() \ No newline at end of file