N.Y.Cityのまちかど

PythonSound

Pythonで音を鳴らす

Pythonを使って音を鳴らす実験のメモ。

前提環境

開発環境のインストール

Anacondaのインストーラを利用して環境をインストールし、同梱のJupyterNotobook上でPythonスクリプトを実行する。

ライブラリのインストール

NumPy

Anaconda環境と共にインストール済み

simpleaudio

スタートメニューから「Anacond Prompt」を開き、

pip install simpleaudio

でインストール完了

プログラム

平均律で1オクターブ半音階

import numpy as np
import simpleaudio as sa

#定数の設定
vol=0.5 #そのままだとうるさかったので音量調整
A_freq = 440 #開始周波数
sample_rate = 44100 #サンプリングレート
T = 0.25 #1音の時間(秒)

#時系列配列の生成
t = np.linspace(0, T, int(T * sample_rate), False)


audio = np.array([])#空配列で初期化

#1オクターブの音程を生成(平均律)
for nt in range(0,13):
    note = np.sin(A_freq*(2**(nt/12)) * t * 2 * np.pi) #sin波で波形生成
    print(A_freq*(2**(nt/12))) #周波数を表示
    audio = np.hstack((audio,note)) #配列の末尾に追記

#再生準備
audio *= 32767 / np.max(np.abs(audio))*vol #最大値を正規化しvolをかけて音量調整
audio = audio.astype(np.int16) #16bitintに

#再生後、再生オブジェクトを停止
play_obj = sa.play_buffer(audio, 1, 2, sample_rate)
play_obj.wait_done()

平均律、ピタゴラス音律、純正律で全音階

import numpy as np
import simpleaudio as sa

#定数の設定
vol=0.5 #そのままだとうるさかったので音量調整
A_freq = 440 #開始周波数
sample_rate = 44100 #サンプリングレート
T = 0.25 #1音の時間(秒)

#時系列配列の生成
t = np.linspace(0, T, int(T * sample_rate), False)


#1オクターブの音程を生成(平均律)
print("Equal Temperament")
eq_audio = np.array([])#空配列で初期化
step=[1,2**(2/12),2**(2/12),2**(1/12),2**(2/12),2**(2/12),2**(2/12),2**(1/12)]
freq = A_freq
for nt in step:
    freq = freq * nt
    note = np.sin(freq * t * 2 * np.pi) #sin波で波形生成
    print(freq) #周波数を表示
    eq_audio = np.hstack((eq_audio,note)) #配列の末尾に追記
eq_audio *= 32767 / np.max(np.abs(eq_audio))*vol #最大値を正規化しvolをかけて音量調整
eq_audio = eq_audio.astype(np.int16) #16bitintに

#1オクターブの音程を生成(ピタゴラス音律)
print("Pythagorean Tuning")
pt_audio = np.array([])#空配列で初期化
step=[1,9/8,9/8,256/243,9/8,9/8,9/8,256/243]
freq = A_freq
for nt in step:
    freq = freq * nt
    note = np.sin(freq * t * 2 * np.pi) #sin波で波形生成
    print(freq) #周波数を表示
    pt_audio = np.hstack((pt_audio,note)) #配列の末尾に追記
pt_audio *= 32767 / np.max(np.abs(pt_audio))*vol #最大値を正規化しvolをかけて音量調整
pt_audio = pt_audio.astype(np.int16) #16bitintに

#1オクターブの音程を生成(純正律)
print("Just Intonation")
js_audio = np.array([])#空配列で初期化
step=[1,9/8,10/9,16/15,9/8,10/9,9/8,16/15]
freq = A_freq
for nt in step:
    freq = freq * nt
    note = np.sin(freq * t * 2 * np.pi) #sin波で波形生成
    print(freq) #周波数を表示
    js_audio = np.hstack((js_audio,note)) #配列の末尾に追記
js_audio *= 32767 / np.max(np.abs(js_audio))*vol #最大値を正規化しvolをかけて音量調整
js_audio = js_audio.astype(np.int16) #16bitintに

#再生後、再生オブジェクトを停止
play_obj = sa.play_buffer(eq_audio, 1, 2, sample_rate)
play_obj.wait_done()

play_obj = sa.play_buffer(pt_audio, 1, 2, sample_rate)
play_obj.wait_done()

play_obj = sa.play_buffer(js_audio, 1, 2, sample_rate)
play_obj.wait_done()

API

公式ドキュメント https://simpleaudio.readthedocs.io/en/latest/simpleaudio.html(2021/5/17現在)からの拙訳

class simpleaudio.WaveObject(audio_data, num_channels=2, bytes_per_sample=2, sample_rate=44100)

WaveObjectのインスタンスは再生待ちの音源を表します.内部にはオーディオデータバッファ・再生パラメータ(サンプリングレートなど),そして再生初期化のためのメソッドを内包します.

パラメータ
audio_data
音源オブジェクト (要バッファインタフェース対応)
num_channels (int)
チャンネル数
bytes_per_sample (int)
片チャンネルの1サンプル当たりのバイト長
sample_rate (int)
サンプリングレート(Hz)
WaveObject.play()

音源の再生を開始する

戻り値
再生用のPlayObject インスタンス
Wclassmethod WaveObject.from_wave_file(wave_file)

ディスク上のWaveファイルからWaveObjectを生成する.

パラメータ
wave_file (str)
Waveファイルのパス文字列
classmethod WaveObject.from_wave_read(wave_read)

wave.open()が返したWave_readオブジェクトからWaveObjectを生成する.

パラメータ
wave_read
Wave_readオブジェクト

class simpleaudio.PlayObject

PlayObjectのインスタンスは、WaveObject.play()およびplay_buffer()によって返され、基本的には開始されたオーディオ再生ジョブへのハンドルです.基本的なアクション(再生の停止など)を実行できます。

PlayObject.stop()

再生を停止する.

PlayObject.is_playing()

再生中であればTrue,完了していればFalseを返す.

戻り値
bool
PlayObject.wait_done()

再生が完了するまで待機する

simpleaudio.stop_all()

現在再生中のすべての音を停止する.

simpleaudio.play_buffer(audio_data, num_channels, bytes_per_sample, sample_rate)

バッファインタフェース・再生パラメータを含むオブジェクトから音声の再生を行う.

パラメータ
audio_data
音源オブジェクト (要バッファインタフェース対応)
num_channels (int)
チャンネル数
bytes_per_sample (int)
片チャンネルの1サンプル当たりのバイト長
sample_rate (int)
サンプリングレート(Hz)
戻り値
再生に使用するPlayObjectのインスタンス

サンプル

ファイルの再生
import simpleaudio as sa

wave_obj = sa.WaveObject.from_wave_file(path_to_file)
play_obj = wave_obj.play()
play_obj.wait_done()
Wave_readオブジェクトの再生
import simpleaudio as sa
import wave

wave_read = wave.open(path_to_file, 'rb')
wave_obj = sa.WaveObject.from_wave_read(wave_read)
play_obj = wave_obj.play()
play_obj.wait_done()
バッファインタフェース対応のオブジェクトから再生
import simpleaudio as sa
import wave

wave_read = wave.open(path_to_file, 'rb')
audio_data = wave_read.readframes(wave_read.getnframes())
num_channels = wave_read.getnchannels()
bytes_per_sample = wave_read.getsampwidth()
sample_rate = wave_read.getframerate()

wave_obj = sa.WaveObject(audio_data, num_channels, bytes_per_sample, sample_rate)
play_obj = wave_obj.play()
play_obj.wait_done()
WaveObjectを生成せず,直接オブジェクトを再生する
import simpleaudio as sa
import wave

wave_read = wave.open(path_to_file, 'rb')
audio_data = wave_read.readframes(wave_read.getnframes())
num_channels = wave_read.getnchannels()
bytes_per_sample = wave_read.getsampwidth()
sample_rate = wave_read.getframerate()

play_obj = sa.play_buffer(audio_data, num_channels, bytes_per_sample, sample_rate)
play_obj.wait_done()

参考

「Pythonでサウンドを扱う」
https://qiita.com/hisshi00/items/62c555095b8ff15f9dd2
Simpleaudio Package
https://simpleaudio.readthedocs.io/en/latest/
Simpleaudio Package - Short Tutorial - Using Numpy
https://simpleaudio.readthedocs.io/en/latest/tutorial.html#using-numpy

現在ご覧のページの最終更新日時は2021/05/17 18:55:18です。

Copyright (C) N.Y.City ALL Rights Reserved.

Email: info[at]nycity.main.jp