LoginSignup
6
2

More than 1 year has passed since last update.

MCD(Mel-cepstrum distortion)を求める(音の長さが異なる版)

Last updated at Posted at 2021-08-15

#MCDを求めるが音の長さは違う

  • 前回の記事でこんなのを書いた

    MCD(Mel-cepstrum distortion)を求める
  • しかし,普通声質変換などで生成された音声がrefrenceと全く同じ長さになるわけない!!
  • よって,今回は音声の長さを異なる音声でMCDを求められるようプログラムを更新
  • 長さの異なるものを合わせるためにDTW(Dynamic Time Warping)を用いて合わせるよ!

    DTW(Dynamic Time Warping)動的時間伸縮法

#使用する要素技術とツール達

\frac{10\sqrt{2}}{\ln10}\frac{1}{T}\sum_t\sqrt{\sum^{25}_i 2||mc(t,i)-mc_{synth}(t,i)||^2}

DTWとは時系列データ同士の距離・類似度を測る際に用いる手法です。波形の距離を求める手法としてはユークリッド距離(Euclidean Distance)や マンハッタン距離等(Manhattan distance)があるかと思います。

DTWは2つの時系列の各点の距離(誤差の絶対値)を総当たりで求め、全て求めた上で2つの時系列が最短となるパスを見つけます。時系列同士の長さや周期が違っても類似度を求めることができます。

  • ツールはlibrosaのlibrosa.sequence.dtwを使います!librosaのリンク
  • librosa.sequence.dtwから得たwpを用いて対応を取ればnnmnkwii.metricsで比較できる!

#実装コード

# -*- coding: utf-8 -*-
import os
import sys
import librosa
import numpy as np
import pyworld
import pysptk
from nnmnkwii.metrics import melcd

args=sys.argv
if len(args) != 3:
    print("python3 mcd_dtw.py [input wavfile1] [input wavfile2]")
    sys.exit()

else:
    sr = 22050
    FRAME_PERIOD = 5.0 #default 5.0
    alpha = 0.65  # commonly used at 22050 Hz
    fft_size = 512 #default 512
    mcep_dim = 34 #default 34

    wav1, _ = librosa.load(sys.argv[1], sr=sr, mono=True)
    wav2, _ = librosa.load(sys.argv[2], sr=sr, mono=True)
 
    # Use WORLD vocoder to spectral envelope
    _, sp1, _ = pyworld.wav2world(wav1.astype(np.double), fs=sr, frame_period=FRAME_PERIOD, fft_size=fft_size)
    # Extract MCEP features
    mgc1 = pysptk.sptk.mcep(sp1, order=mcep_size, alpha=alpha, maxiter=0, etype=1, eps=1.0E-8, min_det=0.0, itype=3)
    # Use WORLD vocoder to spectral envelope
    _, sp2, _ = pyworld.wav2world(wav2.astype(np.double), fs=sr,frame_period=FRAME_PERIOD, fft_size=fft_size)
    # Extract MCEP features
    mgc2 = pysptk.sptk.mcep(sp2, order=mcep_size, alpha=alpha, maxiter=0, etype=1, eps=1.0E-8, min_det=0.0, itype=3)

    ref_frame_no = len(mgc1)

    min_cost, wp = librosa.sequence.dtw(mgc1[:, 1:].T, mgc2[:, 1:].T)
   
    result = melcd(mgc1[wp[:,0]], mgc2[wp[:,1]] , lengths=None)
6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2