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は500Hz に設定され、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ファイルへの保存については、こちら をお読みください。
