Síntesis de audio Python
- Síntesis de audio Python
-
Utilice
IPython.displaypara la síntesis aditiva en Python - Cree varias formas de onda básicas con síntesis aditiva en Python
-
Use
pyaudiopara generar síntesis de audio en Python
Hoy aprenderemos sobre la síntesis de audio y cómo podemos generar sonido usando Python.
Síntesis de audio Python
La síntesis de sonido o síntesis de audio genera sonido electrónicamente (usando hardware o software) que imita la voz humana o instrumentos musicales.
La síntesis es principalmente para música, donde un dispositivo/instrumento electrónico conocido como sintetizador se usa para grabar e interpretar música.
Ahora, el punto es ¿podemos usar Python para generar este tipo de sonidos simples, por ejemplo, onda sinusoidal? ¿Tenemos algún módulo para eso, o cómo podemos crear uno propio?
Aprendamos las diferentes formas a continuación.
Utilice IPython.display para la síntesis aditiva en Python
-
Primero, importamos los módulos y bibliotecas necesarios. Importamos
IPythonpara mostrar el reproductor de sonido,numpypara trabajar con matrices,matplotlibpara trazar gráficos (lo haremos mientras generamos formas de onda básicas) ymathpara usar funciones matemáticas.import IPython.display as ipd import numpy import math import matplotlib.pyplot as plt -
Establezca la frecuencia de muestreo. Aquí, establecemos el
sample_ratecon22050.sample_rate = 22050 -
Haz la forma de onda sinusoidal.
def makesine(frequency, duration): t = numpy.linspace(0, duration, math.ceil(sample_rate * duration)) x = numpy.sin(2 * numpy.pi * frequency * t) return xEn este paso, definimos una función
makesine(), que tomafrecuenciayduracióncomo parámetros. Utilizamos los métodosdurationennumpy.linspace()yfrequencyennumpy.sin()para reutilizar formas de onda sinusoidales puras.Tenga en cuenta que
numpy.linspace()crea secuencias numéricas, o podemos decir que devuelve números/muestras espaciados uniformemente w.r.t. intervalo (comienzo, parada). Es similar anumpy.arange()pero toma un número de muestra (num) como parámetro en lugar depaso.Puedes encontrar más sobre eso aquí.
Por otro lado,
numpy.sin()calcula el seno trigonométrico para todas lasxespecificadas (una matriz de elementos). -
Ejecute
makesine().output = numpy.array(()) y = makesine(261.63, 0.5) # C for 0.5 seconds output = numpy.concatenate((output, y)) y = makesine(293.66, 0.5) # D for 0.5 seconds output = numpy.concatenate((output, y)) y = makesine(329.63, 0.5) # E for 0.5 seconds output = numpy.concatenate((output, y)) ipd.Audio(output, rate=sample_rate)A continuación, ejecutamos
makesine()varias veces para formar una nueva forma de onda con unafrecuenciay unaduraciónespecificadas. Después de eso, usamosnumpy.concatenate()para colocarlos todos juntos.Puede encontrar el código fuente de trabajo completo a continuación con la salida respectiva.
-
Aquí está el código fuente completo.
import IPython.display as ipd import matplotlib.pyplot as plt import numpy import math sample_rate = 22050 def makesine(frequency, duration): t = numpy.linspace(0, duration, math.ceil(sample_rate * duration)) x = numpy.sin(2 * numpy.pi * frequency * t) return x output = numpy.array(()) y = makesine(261.63, 0.5) # C for 0.5 seconds output = numpy.concatenate((output, y)) y = makesine(293.66, 0.5) # D for 0.5 seconds output = numpy.concatenate((output, y)) y = makesine(329.63, 0.5) # E for 0.5 seconds output = numpy.concatenate((output, y)) ipd.Audio(output, rate=sample_rate)PRODUCCIÓN:
Cree varias formas de onda básicas con síntesis aditiva en Python
Hemos terminado con la forma de onda sinusoidal básica. Experimentemos con varias formas de onda básicas con frecuencias en múltiplos enteros usando frecuencia * i; aquí, i es el contador de 1 y se incrementa en 1 cada vez.
Necesitamos suavizar estas ondas sinusoidales en amplitudes predefinidas (amplist), que luego se apilan en la “salida”. Para que eso suceda, debemos crear una función llamada addsyn() de la siguiente manera:
def addsyn(frequency, duration, amplist):
i = 1
t = numpy.linspace(0, duration, math.ceil(sample_rate * duration))
output = numpy.zeros(t.size)
for amp in amplist:
x = numpy.multiply(makesine(frequency * i, duration), amp)
output = output + x
i += 1
if numpy.max(output) > abs(numpy.min(output)):
output = output / numpy.max(output)
else:
output = output / -numpy.min(output)
return output
Dentro de addsyn(), inicializamos una nueva salida. Dentro del ciclo for, hacemos la forma de onda sinusoidal con una amplitud máxima (amp); aquí, frecuencia es un múltiplo entero.
Luego, lo sumamos a la salida y lo guardamos en la variable salida. A continuación, nos aseguramos de que la amplitud máxima no supere 1 y devolvemos la salida.
Ahora, podemos ejecutar el siguiente fragmento de código para hacer solo una onda sinusoidal armónica y hacer un gráfico para ella que muestre solo 0.005 segundos para ver esta forma de onda.
t = numpy.linspace(0, 1, sample_rate)
sinewave = addsyn(440, 1, [1])
plt.plot(t, sinewave)
plt.xlim(0, 0.005)
ipd.Audio(sinewave, rate=sample_rate)
El código fuente completo sería el siguiente.
Código de ejemplo:
import IPython.display as ipd
import matplotlib.pyplot as plt
import numpy
import math
sample_rate = 22050
def addsyn(frequency, duration, amplist):
i = 1
t = numpy.linspace(0, duration, math.ceil(sample_rate * duration))
output = numpy.zeros(t.size)
for amp in amplist:
x = numpy.multiply(makesine(frequency * i, duration), amp)
output = output + x
i += 1
if numpy.max(output) > abs(numpy.min(output)):
output = output / numpy.max(output)
else:
output = output / -numpy.min(output)
return output
t = numpy.linspace(0, 1, sample_rate)
sinewave = addsyn(440, 1, [1])
plt.plot(t, sinewave)
plt.xlim(0, 0.005)
ipd.Audio(sinewave, rate=sample_rate)
PRODUCCIÓN:
síntesis de audio de Python - forma de onda sinusoidal básica armónica.wav

Ahora, podemos jugar con diferentes valores de la función addsyn() para obtener diferentes resultados. Vea otro ejemplo para crear una onda cuadrada a continuación.
Código de ejemplo:
import IPython.display as ipd
import matplotlib.pyplot as plt
import numpy
import math
sample_rate = 22050
def addsyn(frequency, duration, amplist):
i = 1
t = numpy.linspace(0, duration, math.ceil(sample_rate * duration))
output = numpy.zeros(t.size)
for amp in amplist:
x = numpy.multiply(makesine(frequency * i, duration), amp)
output = output + x
i += 1
if numpy.max(output) > abs(numpy.min(output)):
output = output / numpy.max(output)
else:
output = output / -numpy.min(output)
return output
t = numpy.linspace(0, 1, sample_rate)
square_wave = addsyn(440, 1, [1, 0, 0.349, 0, 0.214, 0, 0.156, 0, 0.121, 0])
plt.plot(t, square_wave)
plt.xlim(0, 0.005)
ipd.Audio(square_wave, rate=sample_rate)
PRODUCCIÓN:
síntesis de audio de Python: forma de onda sinusoidal básica cuadrada.wav

Use pyaudio para generar síntesis de audio en Python
Aquí, usaremos pyaudio, un módulo de Python que graba audio con Python.
-
Primero, importamos las bibliotecas necesarias:
mathpara realizar funciones matemáticas ypyaudiopara generar ondas.import math # import needed modules import pyaudio # sudo apt-get install python-pyaudio -
Inicializa
pyaudio.PyAudio = pyaudio.PyAudio -
Inicializar variables.
bit_rate = 16000 frequency = 500 length = 1 bit_rate = max(bit_rate, frequency + 100) number_of_frames = int(bit_rate * length) rest_frames = number_of_frames % bit_rate wave_data = ""Aquí, inicializamos el
bit_ratecon16000, que muestra el número de fotogramas por segundo. Lafrecuenciase establece en500Hz que denota las ondas por segundo (261.63=nota C4) mientras que lalongitudse inicializa con1.Después de eso, usamos la función
max()para encontrar el máximo debit_rateyfrequency+100y asignamos el valor máximo abit_rate. Luego, multiplicamos elbit_ratey lalongitud, lo convertimos al tipointusando la funciónint()y lo asignamos anumber_of_frames.A continuación, usamos el operador de módulo (
%) para dividirnumber_of_framesconbit_ratey asignamos el resto arest_frames. Finalmente, inicializamoswave_datacon una cadena vacía. -
Generar ondas.
for x in range(number_of_frames): wave_data = wave_data + chr( int(math.sin(x / ((bit_rate / frequency) / math.pi)) * 127 + 128) ) for x in range(rest_frames): wave_data = wave_data + chr(128)Aquí, usamos dos bucles
forque iteran hasta elnumber_of_framespara generar ondas. -
Grabar audio.
p = PyAudio() stream = p.open( format=p.get_format_from_width(1), channels=1, rate=bit_rate, output=True ) stream.write(wave_data) stream.stop_stream() stream.close() p.terminate()Aquí, creamos una instancia de
PyAudio, guardamos la referencia enp, y usamos esa referencia para abrir una secuencia usando el métodoopen(), que grabará audio. A continuación, escribimoswave_data, detuvimos la transmisión y la cerramos. Finalmente, termine también la instanciaPyAudio(p).Puede leer sobre
open(),write(),stop_stream()yclose()aquí en detalle. -
Aquí está el código fuente completo.
import math import pyaudio PyAudio = pyaudio.PyAudio bit_rate = 16000 frequency = 500 length = 1 bit_rate = max(bit_rate, frequency + 100) number_of_frames = int(bit_rate * length) rest_frames = number_of_frames % bit_rate wave_data = "" for x in range(number_of_frames): wave_data = wave_data + chr( int(math.sin(x / ((bit_rate / frequency) / math.pi)) * 127 + 128) ) for x in range(rest_frames): wave_data = wave_data + chr(128) p = PyAudio() stream = p.open( format=p.get_format_from_width(1), channels=1, rate=bit_rate, output=True ) stream.write(wave_data) stream.stop_stream() stream.close() p.terminate()Una vez que ejecutamos el código anterior, podemos escuchar una onda. Tenga en cuenta que no estamos guardando esta ola en un archivo
.wav.Puede leer aquí para aprender a guardar en un archivo
.wav.
