0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

モノラル音声をステレオ音声(2チャネル)に変換し,各チャネルに話者ごとの音声を割り当てる.

Posted at

J-CHATを機械学習で扱いやすいデータに整形

2話者が対話しているモノラルな音声を,話者分離をしたのちに書き起こしを作成する手順をメモしておきます.この記事では話者分離をしてステレオ音声として保存するところまで書きます.
pyannoteでも分離可能なんですが,精度がいまいちだったのでAsteroidを使いました.(Colabで実行しています.)

扱う音声データ

以下のように,チャネル1,サンプリング周波数が22050(Hz),1分41秒の対話音声データを扱います.
https://drive.google.com/file/d/1D3N_wTC5d4fX08jbsbyEw5CdK_cZNF5F/view?usp=sharing

$ soxi 15f97caafef4a4b352e54781236cf2b4.wav 

Input File     : '15f97caafef4a4b352e54781236cf2b4.wav'
Channels       : 1
Sample Rate    : 22050
Precision      : 16-bit
Duration       : 00:01:41.54 = 2238891 samples ~ 7615.28 CDDA sectors
File Size      : 4.48M
Bit Rate       : 353k
Sample Encoding: 16-bit Signed Integer PCM

もろもろインポートします.

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

librosaで波形を見てみます.

file_name = "/content/15f97caafef4a4b352e54781236cf2b4.wav"

y, sr = librosa.load(file_name)
time = np.arange(0, len(y)) / sr

plt.plot(time,y)
plt.xlabel("Time(s)")
plt.ylabel("Sound Amptitude")

plt.show()

image.png

話者分離(ステレオ音声ファイルを出力)

Asteroidを使って2話者に分離します.

!pip install asteroid でAsteroidをインストールしておいてください.

from asteroid.models import ConvTasNet
import torch
import torchaudio

# モデルのロード(最大2話者対応のモデル)
model = ConvTasNet.from_pretrained("JorisCos/ConvTasNet_Libri2Mix_sepclean_16k")

# 音声データの整形
waveform_torch = torch.tensor(y).unsqueeze(0)  # (1, 1, T)
resampler = torchaudio.transforms.Resample(orig_freq=22050, new_freq=16000)
waveform_torch = resampler(waveform_torch)

# モデルで話者分離(出力:話者数 x サンプル数)
separated_sources = model.separate(waveform_torch)
separated_sources_np = separated_sources.cpu().numpy()

それぞれの音声を出力したかったら,以下のプログラムを動かします.

import IPython.display as ipd
ipd.display(ipd.Audio(separated_sources_np[0, 0], rate=16000))
ipd.display(ipd.Audio(separated_sources_np[0, 1], rate=16000))

それぞれの音声を波形で見てみます.

time = np.arange(0, len(separated_sources_np[0, 0])) / sr

plt.plot(time,separated_sources_np[0, 0])
plt.xlabel("Time(s)")
plt.ylabel("Sound Amptitude")

plt.show()

time = np.arange(0, len(separated_sources_np[0, 1])) / sr

plt.plot(time,separated_sources_np[0, 1])
plt.xlabel("Time(s)")
plt.ylabel("Sound Amptitude")

plt.show()

左が話者A,右が話者Bの波形です.(分離されていることがわかります.)

ステレオ音声として保存

import soundfile as sf

# separated_sources_np: shape = (1, 2, T) → (2, T)
stereo_data = separated_sources_np[0]  # shape: (2, T)

# 転置して shape を (T, 2) にする → ステレオ形式
stereo_data = stereo_data.T  # shape: (T, 2)

# 保存
sf.write("separated_stereo.wav", stereo_data, samplerate=16000)

このようにチャネルごとに話者が割り振られた2チャネル音声になりました.

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?