Python オーディオ合成
- Python オーディオ合成
-
Python での加算合成に
IPython.display
を使用する - Python で加算合成を使用してさまざまな基本的な波形を作成する
-
pyaudio
を使用して Python で音声合成を生成する
今日は、オーディオ合成と、Python を使用してサウンドを生成する方法について学びます。
Python オーディオ合成
サウンド合成またはオーディオ合成は、人間の声や楽器を模倣するサウンドを (ハードウェアまたはソフトウェアを使用して) 電子的に生成します。
合成は主に音楽用であり、シンセサイザーとして知られる電子デバイス/楽器を使用して音楽を録音および実行します。
さて、重要なのは、Python を使用して、これらの種類の単純な音、たとえば正弦波を生成できるかということです。 そのためのモジュールはありますか、または独自のモジュールを作成するにはどうすればよいですか?
以下のさまざまな方法を学びましょう。
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
このステップでは、パラメータとして
frequency
とduration
を取る関数makesine()
を定義します。numpy.linspace()
メソッドでduration
を、numpy.sin()
メソッドでfrequency
を使用して、純粋な正弦波形を再利用します。numpy.linspace()
は数値シーケンスを作成することに注意してください。または、等間隔の数値/サンプルを返すと言えます。 間隔 (開始、停止)。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()
を複数回実行して、指定されたfrequency
とduration
で新しい波形を形成します。 その後、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 で加算合成を使用してさまざまな基本的な波形を作成する
基本的な正弦波が完成しました。 frequency * 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
) の正弦波を作成します。 ここで、frequency
は整数倍です。
次に、それを出力に合計し、output
変数に保存します。 次に、最大振幅が 1
を超えないことを確認し、output
を返します。
ここで、次のコードを実行して高調波正弦波を 1つだけ作成し、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
pyaudio
を使用して Python で音声合成を生成する
ここでは、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 = ""
ここでは、1 秒あたりのフレーム数を示す
bit_rate
を16000
で初期化しました。frequency
は500
Hz に設定され、1 秒あたりの波数 (261.63=C4-note
) を表し、length
は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
まで反復する 2つの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
ファイルへの保存については、こちら をお読みください。