파이썬 오디오 합성
- 파이썬 오디오 합성
-
Python에서 추가 합성에
IPython.display사용 - Python에서 가산 합성으로 다양한 기본 파형 만들기
-
Python에서
pyaudio를 사용하여 오디오 합성 생성
오늘은 오디오 합성에 대해 알아보고 파이썬으로 소리를 생성하는 방법에 대해 알아보겠습니다.
파이썬 오디오 합성
사운드 합성 또는 오디오 합성은 사람의 목소리나 악기를 모방하는 사운드를 전자적으로(하드웨어 또는 소프트웨어 사용) 생성합니다.
합성은 주로 음악용으로, 신디사이저로 알려진 전자 장치/악기가 음악을 녹음하고 연주하는 데 사용됩니다.
이제 요점은 파이썬을 사용하여 이러한 종류의 간단한 소리, 예를 들어 사인파를 생성할 수 있습니까? 이를 위한 모듈이 있습니까? 아니면 어떻게 자체 모듈을 만들 수 있습니까?
아래에서 다양한 방법을 알아봅시다.
Python에서 추가 합성에 IPython.display 사용
-
먼저 필요한 모듈과 라이브러리를 가져옵니다. 우리는
IPython을 가져와서 사운드 플레이어를 표시하고numpy를 사용하여 배열 작업을 하고matplotlib를 가져와 차트를 플로팅합니다(기본 파형을 생성하는 동안 수행할 예정임).math를 사용하여 수학 함수를 사용합니다.import IPython.display as ipd import numpy import math import matplotlib.pyplot as plt -
샘플 속도를 설정합니다. 여기에서
sample_rate를22050으로 설정합니다.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이 단계에서
makesine()함수를 정의합니다. 이 함수는주파수및지속 시간을 매개변수로 사용합니다. 순수한 사인 파형을 재사용하기 위해numpy.linspace()에서duration을 사용하고numpy.sin()메소드에서frequency를 사용합니다.numpy.linspace()는 숫자 시퀀스를 생성하거나 균일한 간격의 숫자/샘플 w.r.t를 반환한다고 말할 수 있습니다. 간격(시작, 중지).numpy.arange()와 유사하지만step대신 샘플 번호(num)를 매개 변수로 사용합니다.여기에서 자세한 내용을 확인할 수 있습니다.
반면
numpy.sin()은 지정된 모든x(요소 배열)에 대한 삼각 사인을 계산합니다. -
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)다음으로
makesine()을 여러 번 실행하여 지정된주파수및지속 시간으로 새 파형을 형성합니다. 그런 다음numpy.concatenate()를 사용하여 모두 함께 배치합니다.아래에서 각각의 출력과 함께 작동하는 전체 소스 코드를 찾을 수 있습니다.
-
다음은 전체 소스 코드입니다.
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)출력:
Python에서 가산 합성으로 다양한 기본 파형 만들기
기본 사인 파형으로 작업을 완료했습니다. 주파수 * i를 사용하여 정수 배수의 주파수를 사용하여 다양한 기본 파형을 실험해 봅시다. 여기서 i는 1의 카운터이며 매번 1씩 증가합니다.
이러한 사인파를 미리 정의된 진폭(amplist)으로 부드럽게 해야 합니다. 그런 다음 output에 누적됩니다. 그렇게 하려면 다음과 같이 addsyn()이라는 함수를 만들어야 합니다.
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
addsyn() 내부에서 새 output을 초기화합니다. for 루프 내에서 최대 진폭(amp)으로 사인 파형을 만듭니다. 여기서 주파수는 정수 배수입니다.
그런 다음 출력에 합산하여 output 변수에 저장합니다. 다음으로 최대 진폭이 1을 초과하지 않는지 확인하고 output을 반환합니다.
이제 다음 코드를 실행하여 하나의 고조파 사인파만 만들고 이 파형 모양을 보기 위해 0.005초만 표시하는 차트를 만들 수 있습니다.
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)
전체 소스 코드는 다음과 같습니다.
예제 코드:
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)
출력:
python 오디오 합성 - 기본 사인 파형 harmonic.wav

이제 addsyn() 함수의 다른 값을 사용하여 다른 출력을 얻을 수 있습니다. 아래의 구형파를 생성하는 또 다른 예를 참조하십시오.
예제 코드:
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)
출력:
python 오디오 합성 - 기본 사인 파형 square.wav

Python에서 pyaudio를 사용하여 오디오 합성 생성
여기에서는 Python으로 오디오를 녹음하는 Python 모듈인 pyaudio를 사용합니다.
-
먼저 필요한 라이브러리를 가져옵니다. 수학 함수를 수행하기 위한
math와 웨이브 생성을 위한pyaudio입니다.import math # import needed modules import pyaudio # sudo apt-get install python-pyaudio -
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 = ""여기에서 초당 프레임 수를 나타내는
16000으로bit_rate를 초기화했습니다.주파수는 초당 파동(261.63=C4-note)을 나타내는500Hz로 설정되고길이는1로 초기화됩니다.그런 다음
max()함수를 사용하여bit_rate및frequency+100에서 최대값을 찾고 최대값을bit_rate에 할당합니다. 그런 다음bit_rate와length를 곱하고int()함수를 사용하여int유형으로 변환하고number_of_frames에 할당합니다.다음으로 모듈로 연산자(
%)를 사용하여number_of_frames를bit_rate로 나누고 나머지를rest_frames에 할당합니다. 마지막으로 빈 문자열로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)여기에서는 웨이브를 생성하기 위해
number_of_frames까지 반복되는 두 개의for루프를 사용했습니다. -
오디오를 녹음합니다.
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()여기에서
PyAudio인스턴스를 생성하고p에 참조를 저장한 다음 해당 참조를 사용하여 오디오를 녹음할open()메서드를 사용하여 스트림을 엽니다. 다음으로wave_data를 작성하고 스트림을 중지하고 닫았습니다. 마지막으로PyAudio인스턴스(p)도 종료합니다.open(),write(),stop_stream()및close()여기에 대해 자세히 읽을 수 있습니다. -
다음은 전체 소스 코드입니다.
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()위의 코드를 실행하면 파도 소리가 들립니다. 이 웨이브를
.wav파일에 저장하지 않는다는 점에 유의하십시오..wav파일에 저장하는 방법에 대해 알아보려면 여기를 참조하십시오.
