Wizard Notes

Python, JavaScript を使った音楽信号分析の技術録、作曲活動に関する雑記

PythonのMDCT(修正離散コサイン変換)ライブラリ: mdct

MP3などで使われている周波数変換方法であるMDCT (Modified Discrete Cosine Transform)

現状、Scipy等の準標準的なライブラリに関数はありませんが、以下のライブラリがありました。

GitHub - nils-werner/mdct: A fast MDCT implementation using SciPy and FFTs

MDCT — MDCT 0.4 documentation

ライセンスはMIT Licenseとなっています。

インストール方法

pip install mdct

使い方

順変換mdct.mdctと逆変換mdct.imdctの関数を利用します

mdct.mdct(x, odd=True, transforms=None, **kwargs) mdct.imdct(X, odd=True, transforms=None, **kwargs)

重要な引数をいくつかピックアップします。

  • x
    • モノラル: shape=(サンプル数, )
    • マルチチャネル: shape=(サンプル数, チャネル数)
  • framelength
    • 1フレームのサンプル数
  • overlap
    • オーバーラップ数

mdct module — MDCT 0.4 documentation

スペクトログラムプロット用スクリプト

import numpy as np
import matplotlib.pyplot as plt
import librosa
import librosa.display
import mdct


y, sr = librosa.load(librosa.example('brahms'))
print(y.shape)
framelength = 1024
overlap     = 2
hop_length = framelength // overlap


# 入力信号の shape は (n_samples, ) or (n_samples, n_ch)
spec_mdct = mdct.mdct(y, framelength=framelength, overlap=overlap)
sig_imdct = mdct.imdct(spec_mdct, framelength=framelength, overlap=overlap)


# STFTの振幅
spec_stft_mag = np.abs(librosa.stft(y, n_fft=framelength, hop_length=hop_length))

# スペクトログラムのプロット
y_axis = "log"#"linear"
plt.subplot(2,1,1)
librosa.display.specshow(spec_stft_mag**0.5, hop_length=hop_length,
                         y_axis=y_axis, x_axis='time', cmap="jet", sr=sr)
plt.title('STFT Spectrogram (Magnitude)')
plt.colorbar()
plt.subplot(2,1,2)
librosa.display.specshow(np.sign(spec_mdct)*(np.abs(spec_mdct)**0.5), hop_length=hop_length,
                         y_axis=y_axis, x_axis='time', cmap="twilight", sr=sr)
plt.title('MDCT Spectrogram')
plt.colorbar()
plt.tight_layout()
plt.show()

スペクトログラムのプロット

STFTの振幅スペクトログラムと、MDCTスペクトログラムをプロットしてみました*1

f:id:Kurene:20210120225702p:plain

*1:見やすくするため、振幅の絶対値は0.5乗しています