commit 99df0948b642e7101b94f95e84c96a785ea7f39f Author: fosanz Date: Fri Dec 15 22:17:08 2023 +0100 Initial commit diff --git a/Notas.py b/Notas.py new file mode 100644 index 0000000..82c6e7d --- /dev/null +++ b/Notas.py @@ -0,0 +1,77 @@ +import enum +from math import exp, log + +class eNotas(enum.Enum): + DO = 1 + RE = 3 + MI = 5 + FA = 6 + SOL = 8 + LA = 10 + SI = 12 + SILENCIO = 8 + +class tipoNota(enum.Enum): + ##Redonda, Blanca, Negra, Corchea, Semicorchea + R = 1, 4 + B = 2, 2 + N = 4, 1 + C = 8, 0.5 + S = 16, 0.25 + + ## Redonda, Blanca, Negra, Corchea, Semicorchea con puntillo + RP = 3, 6 + BP = 6, 3 + NP = 12, 1.5 + 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 + ##Bemol + BE = 2 + ##Ninguno + NO = 3 + + + +class Nota(): + + ##Por defecto las notas no tienen modificador y la octava es la 4 + def __init__(self, nota: eNotas, tipo: tipoNota, modificador = modificador.NO, octava = 4): + self.nota = nota + self.tipo = tipo + self.modificador = modificador + self.octava = octava + + + def duracion(self): + return self.tipo.value[1] + + + def frec(self): + + expo = self.octava * 12 + (self.nota.value - 58) + + if self.modificador == modificador.SS: + expo += 1 + + if self.modificador == modificador.BE: + expo -= 1 + + return int(440 * ((2 ** (1 / 12)) ** expo)) \ No newline at end of file diff --git a/__pycache__/Notas.cpython-311.pyc b/__pycache__/Notas.cpython-311.pyc new file mode 100644 index 0000000..fefd0c9 Binary files /dev/null and b/__pycache__/Notas.cpython-311.pyc differ diff --git a/polifonia.py b/polifonia.py new file mode 100644 index 0000000..de099a1 --- /dev/null +++ b/polifonia.py @@ -0,0 +1,114 @@ +import time +from pydub import AudioSegment +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): + + 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): + duration = nota.duracion() * velocidad + 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) + + audio = audio * self.volumen + + # Play the audio + self.stream.write(audio) + + def run(self): + # Wait for all threads to be ready + self.barrier.wait() + for nota in self.notas: + self.beep(nota, self.velocidad) + + def close(self): + 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)] + + + 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 diff --git a/test.py b/test.py new file mode 100644 index 0000000..0105256 --- /dev/null +++ b/test.py @@ -0,0 +1,23 @@ +from math import exp, log + +import numpy as np +import matplotlib.pyplot as plt +plt.style.use("bmh") +import sounddevice as sd +def frec(nota: int, octava: int) -> int: + expo = octava * 12 + (nota - 58) + return int(440 * ((2 ** (1 / 12)) ** expo)) +framerate = 44100 +duration = 1000 +t = np.linspace(0, duration / 1000, int(framerate * duration / 1000)) +frequency = frec(10, 4) # LA4 +data = np.sin(2 * np.pi * frequency * t) +def beep(nota: int, octava: int, duracion: int) -> None: + framerate = 44100 + t = np.linspace(0, duracion / 1000, int(framerate * duracion / 1000)) + frequency = frec(nota, octava) + data = np.sin(2 * np.pi * frequency * t) + sd.play(data, framerate) + sd.wait() +for i in range(1, 13): + beep(i, 4, 1000) \ No newline at end of file