Pythonで音符やコード進行の音声波形を扱うライブラリを作った
munotes
タイトルにあるようなライブラリです。
たとえば、「ド」とか「C#7」みたいな音やコードの波形(sin波とか矩形波とか)が欲しい、という場面で使えます。
- PyPI: https://pypi.org/project/munotes/
- GitHub: https://github.com/misya11p/munotes/
- API reference: https://misya11p.github.io/munotes/
インストール
pip install munotes
対応しているPythonのバージョンは3.7以上です。
使い方
このライブラリはいくつかのクラスを提供します。
音符や和音を扱うクラスと、それらを並べてシーケンスとして扱うクラスがあります。
mn.Note
単音を扱うクラスです。音名を入力し、オブジェクトを生成します。
import munotes as mn
note = mn.Note("C4")
print(str(note)) # C4
音名とオクターブを分けた入力や、midiノートナンバーでの指定も可能です。
note = mn.Note("C", 4)
note = mn.Note(60)
このオブジェクトは以下のような属性を持ちます。
print(note.name) # C
print(note.octave) # 4
print(note.num) # 60
print(note.freq) # 261.6255653005986
Note.freq
から得られる周波数はA4=440Hzを基準としたものです。生成される波形に影響を与えます。以下のように変更することができます。
note.tuning(270)
print(note.freq) # 270
A4を基準とした指定もできます。
note.tuning(441, stand_A4=True)
print(note.freq) # 262.2201688581
Note.freq
やNote.A4
を直接変更しても問題なく動きます。
note.freq = 270
note.A4 = 441
transpose()
メソッドで音を平行移動できます。
note.transpose(1)
print(note.name) # C#
では、波形を生成していきましょう。以下のメソッドを使用します。
-
sin()
: sin波 -
square()
: 矩形波 -
sawtooth()
: ノコギリ波
引数は以下の二つです。
-
sec
: 秒数(デフォルト=1) -
sr
: サンプリングレート(デフォルト=22050)
numpyの配列が返ってきます。
import matplotlib.pyplot as plt
note = mn.Note("C4")
sin = note.sin(sec=1, sr=22050)
square = note.square()
sawtooth = note.sawtooth()
fig, (ax1, ax2, ax3) = plt.subplots(3, 1)
ax1.plot(sin[:400])
ax2.plot(square[:400])
ax3.plot(sawtooth[:400])
square()
とsawtooth()
は固有の引数を1つ持っています。
square = note.square(duty=0.1)
sawtooth = note.sawtooth(width=0.5)
render()
メソッドで任意の波形を生成することもできます。
import numpy as np
y = note.render(lambda t: np.sin(t) + np.sin(2 * t))
plt.plot(y[:400])
play()
メソッドを使うと、notebookに埋め込める音声を直接取得できます
mn.Notes
複数のNote
をまとめて和音として扱うクラスです。
notes = mn.Notes(
mn.Note("C4"),
mn.Note("E4"),
mn.Note("G4")
)
print(notes.names) # ['C', 'E', 'G']
Note
(やNotes
)同士を足すことでも和音を生成できます。
notes = mn.Note("C4") + mn.Note("E4") + mn.Note("G4")
print(notes.names) # ['C', 'E', 'G']
基本的な使い方(属性・メソッド)はNote
と同じです。以下のメソッドで波形を扱うことができます。
Notes.sin()
Notes.square()
Notes.sawtooth()
Notes.render()
Notes.play()
mn.Chord
コードを扱うクラスです。入力されたコード名から、コードを構成する音符でのNotes
オブジェクトを生成します。
chord = mn.Chord("C#m7", octave=4)
print(chord.names) # ['C#', 'E', 'G#', 'B']
octave
は生成する波形に影響を与えます。デフォルトは4です。
基本的な使い方はNote
と同じです。
transpose()
を使用するとコード名も変わります。
chord.transpose(1)
print(chord.name) # Dm7
mn.Track
複数の音符を並べてシーケンスとして扱うクラスです。
音符と長さのタプルを一つの音符として扱い、それらをリストで渡すことでTrack
オブジェクトを生成します。
track = mn.Track([
("C4", 1),
("E4", 1),
("G4", 1)
])
ド→ミ→ソが1秒ずつ鳴る、合計3秒の音符列が生成されます。
タプル内の音符として、Note
やNotes
オブジェクトまたは音名を表す文字列が入力可能です。
長さの単位は秒になっていますが、引数unit
を指定することで変更可能です。以下の中から選択できます。
-
s
: 秒(デフォルト) -
ms
: ミリ秒 -
ql
: QuarterLength(4分音符)
ql
を選択した場合はbpm
の指定が必要になります。
track = mn.Track([
("C4", 1),
("E4", 1),
("G4", 1)
], unit="ql", bpm=120)
Track.sequence
から音符を取り出せます。
print(track.sequence) # [(Note C4, 1), (Note E4, 1), (Note G4, 1)]
append()
メソッドで音符を追加できます。音符と長さのタプルを好きなだけ与えます。
track.append(("C5", 1), (mn.Chord("C"), 2))
print(track.sequence) # [(Note C4, 1), (Note E4, 1), (Note G4, 1), (Note C5, 1), (Chord C, 2)]
その他の使い方はNote
と同じです。
mn.Stream
複数のTrack
をまとめて扱うクラスです。所謂polyphonicな音楽になりますね。
Track
オブジェクトをリストで渡すことでStream
オブジェクトを生成します。
melody = mn.Track([
("C4", 1),
("D4", 1),
("E4", 1)
])
chords = mn.Track([
(mn.Chord("C"), 3),
])
stream = mn.Stream([melody, chords])
使い方はTrack
と同じです。
基本的な機能は以上になります。
Discussion