Pythonで手軽に音のピッチ抽出!5つの簡単なステップ

Pythonを使ったピッチ抽出のイラストとサンプルコードPython
この記事は約13分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

音楽や音声認識の領域で一般的に使われる技術の一つに、ピッチ抽出があります。

これは音声の基本周波数、つまり音の高さを決定する情報を取得するプロセスです。

この記事では、高度なプログラミング言語であるPythonを使用して、音声データからピッチを抽出する方法について説明します。

●Pythonとピッチ抽出について

○Pythonとは?

Pythonは直感的で読みやすい構文が特徴の高水準プログラミング言語です。

学習曲線が比較的緩やかであり、初心者にも扱いやすいとされています。

また、Pythonはオープンソースであり、多数のライブラリやフレームワークが存在します。

これにより、データ分析、ウェブ開発、機械学習など、幅広い領域で活用されています。

○ピッチ抽出とは?

ピッチ抽出は音声から音の高さ、すなわち基本周波数を取り出すプロセスのことを指します。

これは音楽分析や音声認識、音声合成など、音響信号処理のさまざまな分野で使われています。

特に音楽のメロディー分析や、一人の話者がどのような音を出しているかを識別するために、この技術は非常に有用です。

●Pythonでのピッチ抽出の基礎

○必要なライブラリ

Pythonで音声データからピッチを抽出するためには、いくつかのライブラリが必要になります。

主に「librosa」という音声分析ライブラリと、視覚化のための「matplotlib」、データ操作のための「numpy」、音声データの読み書きに使う「soundfile」を使います。

○ライブラリのインストール方法

Pythonのパッケージ管理システムであるpipを使って、上記のライブラリを簡単にインストールできます。

コマンドラインまたはターミナルを開き、次のコマンドを入力します。

pip install librosa matplotlib numpy soundfile

このコマンドでは、’pip install’に続けてライブラリ名をスペースで区切って指定します。

この例では、’librosa’, ‘matplotlib’, ‘numpy’, ‘soundfile’の4つのライブラリをインストールしています。

●Pythonを使用したピッチ抽出のステップ

ピッチ抽出には、いくつかのステップがあります。

それでは、そのプロセスを順に解説していきます。

○ステップ1:音声ファイルの読み込み

まずは音声ファイルをPythonで読み込むところから始めます。

ここでは、soundfileライブラリを使用します。

このライブラリは音声ファイルを読み込む機能を提供しています。

□サンプルコード1:音声ファイルの読み込み

import soundfile as sf

def read_audio_file(file_path):
    data, sample_rate = sf.read(file_path)
    return data, sample_rate

data, sample_rate = read_audio_file('sample.wav')

このコードでは、まずsoundfileをsfという名前でインポートします。

次に、音声ファイルを読み込む関数’read_audio_file’を定義します。

この関数はファイルパスを引数とし、sf.readを使って音声データとサンプリングレートを取得します。

最後に、’sample.wav’という音声ファイルを読み込み、結果を変数’data’と’sample_rate’に格納します。

○ステップ2:波形データの視覚化

音声ファイルが無事読み込めたら、次にその波形データを視覚化してみましょう。

波形データを視覚化することで、音声の強弱や周期性など、音声の特性を直感的に理解することができます。

視覚化は音声分析において非常に重要なステップです。

□サンプルコード2:波形データの視覚化

下記のコードでは、matplotlibというライブラリを使用して音声の波形をグラフとして表示します。

この例では、読み込んだ音声データ(data)とサンプリングレート(sr)を使用しています。

import matplotlib.pyplot as plt
import numpy as np

# 時間軸の作成
time = np.arange(0, len(data)) / sr

# グラフ作成
plt.figure(figsize=(20, 4))
plt.plot(time, data)
plt.xlabel('Time [s]')
plt.ylabel('Amplitude')
plt.title('Waveform of Audio')
plt.show()

このコードではまず、numpyを使って時間軸を作成しています。

時間軸は、サンプリングレートによって音声データの各点が何秒に対応するかを計算することで得られます。

その後、matplotlibのplot関数を使用して時間軸と音声データをプロットし、グラフを表示しています。

実行すると、x軸が時間(秒)、y軸が振幅(音の強弱)となるグラフが出力されます。

ここで観察できる波形は、人間の耳に直接届く音の振動そのものです。

○ステップ3:ピッチ抽出

波形データの視覚化が完了したら、次はピッチ抽出を行います。ピッチとは音の高低(音高)を示す情報です。

言葉で言えば、「ドレミファソラシド」のそれぞれの音がピッチに該当します。

□サンプルコード3:ピッチ抽出

下記のコードでは、librosaという音声処理ライブラリを使用してピッチ抽出を行います。

ここでは音声データ(data)とサンプリングレート(sr)を入力としてピッチ(frequency)を得ることができます。

import librosa

# ピッチ抽出
pitch, magnitude = librosa.piptrack(y=data, sr=sr)

# ピッチ情報の取得
pitch = pitch[magnitude > np.median(magnitude)]

このコードでは、librosaのpiptrack関数を使ってピッチとその振幅の情報を抽出しています。

その後、振幅が中央値よりも大きいピッチのみを取得しています。

これにより、音量が小さくてピッチの特定が難しい部分を排除しています。

実行すると、音声データ中の各時点でのピッチの配列が得られます。

これにより、音声中の各時点での音の高低を数値として理解することが可能となります。

○ステップ4:ピッチデータの視覚化

ピッチ抽出が完了したら、次にこのピッチデータを視覚化してみましょう。

これにより、音の高低が時間と共にどのように変化しているかを直感的に理解することができます。

□サンプルコード4:ピッチデータの視覚化

下記のコードでは、matplotlibを使用してピッチデータをグラフとして表示します。

この例では、抽出したピッチデータ(pitch)を使用しています。

# グラフ作成
plt.figure(figsize=(20, 4))
plt.plot(time[:len(pitch)], pitch)
plt.xlabel('Time [s]')
plt.ylabel('Frequency [Hz]')
plt.title('Pitch over Time')
plt.show()

このコードでは、先程と同様にmatplotlibのplot関数を使用して時間軸とピッチデータをプロットし、グラフを表示しています。

ただし、ここではy軸が音の高さ(ピッチ)を表しています。

実行すると、x軸が時間(秒)、y軸がピッチ(ヘルツ)となるグラフが出力されます。

音の高低が時間と共にどのように変化しているかを視覚的に理解することができます。

○ステップ5:ピッチデータの保存

視覚化が完了したら、最後にこのピッチデータを保存します。

これにより、後から再度分析を行う際に同じデータを再度抽出する必要がなく、時間を節約できます。

□サンプルコード5:ピッチデータの保存

下記のコードでは、numpyのsave関数を使用してピッチデータをnumpyファイルとして保存します。

この例では、ピッチデータ(pitch)を”pitch.npy”という名前のファイルとして保存しています。

# ピッチデータの保存
np.save('pitch.npy', pitch)

このコードでは、numpyのsave関数を使用してピッチデータを.npy形式のファイルとして保存します。

.npy形式はnumpy配列をそのまま保存できる形式なので、後から読み込んだときに同じ配列を得ることができます。

実行すると、カレントディレクトリに”pitch.npy”という名前のファイルが作成され、その中にピッチデータが保存されます。

後からこのファイルを読み込むことで、今回抽出したピッチデータを再度使用することができます。

●ピッチ抽出の応用例

ピッチ抽出の結果は、音楽分析や音声認識、音響信号処理など、様々な応用があります。

ここではその一例として、統計解析と音楽理論への応用について解説します。

○ピッチの統計解析

抽出したピッチデータから、各ピッチがどの程度出現するか、つまりピッチの頻度を調べることで、音声の特性を統計的に分析することが可能です。

□サンプルコード6:ピッチの統計解析

下記のコードでは、numpyのhistogram関数を使用してピッチデータのヒストグラムを作成し、matplotlibを使用して表示します。

この例では、抽出したピッチデータ(pitch)を使用しています。

# ヒストグラムの作成
hist, bin_edges = np.histogram(pitch, bins=50)

# ヒストグラムの表示
plt.figure(figsize=(10, 4))
plt.bar(bin_edges[:-1], hist, width = bin_edges[1]-bin_edges[0])
plt.xlabel('Frequency [Hz]')
plt.ylabel('Count')
plt.title('Histogram of Pitch')
plt.show()

このコードでは、numpyのhistogram関数を使用してピッチデータのヒストグラムを作成しています。

ヒストグラムとは、データの分布を視覚化するためのグラフで、各ビン(範囲)に含まれるデータの数(頻度)を表します。作成したヒストグラムをmatplotlibを使用して表示しています。

実行すると、x軸がピッチ(ヘルツ)、y軸が頻度となるヒストグラムが表示されます。

このヒストグラムから、どのピッチが多く出現し、どのピッチが少なく出現するか、音声の特性を統計的に理解することができます。

○音楽理論への応用

また、ピッチ抽出は音楽理論への応用にも活用できます。

例えば、特定の音声データから最も頻繁に出現するピッチを調べることで、その音声のキー(調)を推定することも可能です。

□サンプルコード7:音楽理論への応用

下記のコードでは、最も頻繁に出現するピッチを調べて、その音名を表示します。

この例では、抽出したピッチデータ(pitch)を使用しています。

# 最も頻繁に出現するピッチの音名を表示
pitch_counts = np.bincount(pitch)
most_common_pitch = np.argmax(pitch_counts)
note_name = note_spelling(most_common_pitch)
print(f"The most common pitch is {most_common_pitch} Hz, which is a {note_name}.")

このコードでは、numpyのbincount関数とargmax関数を使用して最も頻繁に出現するピッチを求め、その音名を表示しています。

音名の表示には、note_spellingという関数を使用しています。

これはピッチ(ヘルツ)を音名に変換する関数で、自分で定義するか、適切なライブラリを使用することができます。

実行すると、最も頻繁に出現するピッチのヘルツ数とその音名が表示されます。

これにより、音声データの主要なキー(調)を推定することが可能となります。

●注意点と対処法

ピッチ抽出を行う上で考慮すべき点として、音声データの質と長さが挙げられます。

○音声データの質

音声データの質がピッチ抽出の精度に大きく影響します。

ノイズが多い、または録音品質が低い音声データでは、正確なピッチ抽出が難しくなることがあります。

これを避けるために、ノイズリダクションや音声のクリーニングなどの前処理を行うと良い結果が得られることがあります。

○音声データの長さ

また、音声データの長さも重要です。

短すぎる音声データではピッチのパターンが十分に捉えられない可能性があります。

一方で、長すぎる音声データは処理に時間がかかる上、データの扱いが複雑になることがあります。

適切な音声データの長さは、目的や状況によりますが、通常は数秒から数十秒程度が適切とされています。

●カスタマイズ方法

ピッチ抽出には既存のライブラリやツールを使用することが多いですが、特定の目的や要件に合わせてカスタマイズすることも可能です。

一例として、カスタム抽出関数の作成について解説します。

○カスタム抽出関数の作成

既存のピッチ抽出関数ではなく、自分で定義した関数を使用することで、特定の目的に対応した結果を得ることができます。

□サンプルコード8:カスタム抽出関数の作成

下記のコードでは、特定の範囲のピッチのみを抽出するカスタム抽出関数を作成しています。

この例では、抽出対象のピッチの範囲を引数として指定できるようにしています。

def custom_pitch_extraction(audio_data, sampling_rate, min_pitch, max_pitch):
    # ピッチ抽出
    pitch = librosa.yin(audio_data, min_pitch, max_pitch, sr=sampling_rate)
    return pitch

このコードでは、librosaのyin関数を使用してピッチを抽出しています。

yin関数はピッチ抽出のためのアルゴリズムで、min_pitchとmax_pitchという引数を指定することで、抽出するピッチの範囲を制限することができます。

この関数を使用することで、特定の範囲のピッチのみを抽出することが可能になります。

実行すると、指定した範囲のピッチのみが抽出された結果が得られます。

これにより、特定の目的に合わせたピッチ抽出が可能になります。

まとめ

本記事では、音声データからピッチを抽出する方法について詳しく解説しました。

音声データのピッチ抽出は、音声分析や音楽理論の研究、さらには音楽制作や言語学研究など、様々な場面で応用可能です。

まず、Pythonのライブラリであるlibrosaを使用した基本的なピッチ抽出の方法を解説しました。

その後、ピッチ抽出の応用例として、ピッチの統計解析と音楽理論への応用を探りました。

これらは、ピッチ抽出の結果をさらに深く理解し、具体的な分析や作業に役立てるための手法です。

さらに、音声データの質や長さといった、ピッチ抽出の精度に影響を与える要素についての注意点と、それらを改善するための対処法を解説しました。

音声データの品質を確保し、適切な長さのデータを扱うことで、より正確なピッチ抽出が可能となります。

また、カスタム抽出関数の作成によるカスタマイズ方法も紹介しました。

既存のツールだけでなく、自身で定義した関数を使用することで、特定の目的に最適化したピッチ抽出が行えます。

以上の内容を踏まえ、ピッチ抽出が音声データ解析における重要な要素であることを理解いただけたことと思います。

音声データから得られる情報は多岐にわたり、それぞれの目的に応じた解析や抽出方法が求められます。

ピッチ抽出を始めとするこれらの技術を理解し、適切に活用することで、音声データの持つ可能性を最大限に引き出すことができます。

これからも音声データ解析に関する知識や技術を深めていきましょう。

本記事がその一助となれば幸いです。