파이썬 오디오 합성
- 파이썬 오디오 합성
-
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
)을 나타내는500
Hz로 설정되고길이
는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
파일에 저장하는 방법에 대해 알아보려면 여기를 참조하십시오.