夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

Pythonを使用して音源ファイルのシーケンスを行う

本日はPython枠です。

今回は音源ファイルのシーケンスファイルを作成していきます。

もともとのきっかけは私の師であるがちもとさんが動画のシーケンスのやり方を紹介していたため、音源ファイルだとどうなるのかと思ってチャレンジします。

qiita.com

〇環境

Windows 11PC

・Anaconda Propmpt(Anaconda3)

Python 3.10.8

①Anacondaで仮想環境を作成します。

conda create -n audio-converter python=3.10.8

今回はPython3.10.8を使用しています。

②仮想環境を有効化します。

conda activate audio-converter

③pydubをインストールします。

conda install -c conda-forge pydub

pydubPythonを使って音声ファイルを読み込み、波形データを生成、音声処理を行うことができるモジュールです

今回はこれを使用してオーディオファイルを読み込みます。

④任意のディレクトリに次のコードを作成します。

import soundfile as sf
import numpy as np
import os

def read_audio_file(file_path):
    # MP3またはwavファイルを読み込む
    audio, sample_rate = sf.read(file_path)

    return audio, sample_rate

def get_audio_length(file_path):
    audio, sample_rate = read_audio_file(file_path)
    length = len(audio) / sample_rate
    return length

def generate_sequence_data(audio, sample_rate, sequence_length=10, output_folder='Output', output_prefix='output', format='wav'):
    # サンプリングレートを取得
    samples_per_sequence = int(sequence_length * sample_rate)

    # シーケンスごとにファイルに保存
    count = 1
    output_files = []

    for i in range(0, len(audio), samples_per_sequence):
        sequence = audio[i:i+samples_per_sequence]

        # シーケンスが必要なサンプル数に満たない場合は0で埋める
        if len(sequence) < samples_per_sequence:
            sequence = np.pad(sequence, (0, samples_per_sequence - len(sequence)))

        output_file = os.path.join(output_folder, f'{output_prefix}_{count}.{format}')

        # 保存フォーマットに合わせて拡張子を変更
        if format == 'wav':
            sf.write(output_file, sequence, samplerate=sample_rate)
        elif format == 'npy':
            np.save(output_file, sequence)

        output_files.append(output_file)
        count += 1

    return output_files

def concatenate_sequence_files(output_files, output_folder, output_prefix='output', format='wav'):
    # 各シーケンスファイルを読み込み、結合する
    sequences = [sf.read(file)[0] for file in output_files]
    concatenated_sequence = np.concatenate(sequences)

    # 結合したデータをファイルに保存
    final_output_file = os.path.join(output_folder, f'{output_prefix}_concatenated.{format}')

    # 保存フォーマットに合わせて拡張子を変更
    if format == 'wav':
        sf.write(final_output_file, concatenated_sequence, samplerate=sequences[0][1])
    elif format == 'npy':
        np.save(final_output_file, concatenated_sequence)

def main():
    # ファイルパスを指定
    input_folder = 'Input'
    output_folder = 'Output'

    # Inputフォルダ内のファイルを取得
    input_files = [f for f in os.listdir(input_folder) if os.path.isfile(os.path.join(input_folder, f))]

    # ファイルごとに処理
    for file_name in input_files:
        file_path = os.path.join(input_folder, file_name)

        # 音声ファイルを読み込む
        audio, sample_rate = read_audio_file(file_path)

        # ログ出力
        original_length = get_audio_length(file_path)
        print(f'Original Length of {file_name}: {original_length} seconds')

        # シーケンスごとにファイルに保存
        output_files = generate_sequence_data(audio, sample_rate, sequence_length=10, output_folder=output_folder, output_prefix='output', format='wav')

        # 各シーケンスファイルを結合して最終ファイルを保存
        concatenate_sequence_files(output_files, output_folder, output_prefix='output', format='wav')

if __name__ == "__main__":
    main()

スクリプトと同階層にInput,Outputフォルダを作成します。

これはソースとなる音源ファイルを配置するフォルダ、出力するフォルダになります。

⑥Anacondaでスクリプトを実行する

python (スクリプト名).py

これによってOutputフォルダに結果が出力されます。

なおcountの数を変更することでファイル名を変更できます。

    # シーケンスごとにファイルに保存
    count = 1
    output_files = []

またgenerate_sequence_data()sequence_lengthの値を変えることで任意の秒数のシーケンス音源を作成することができます。

        # シーケンスごとにファイルに保存
        output_files = generate_sequence_data(audio, sample_rate, sequence_length=10, output_folder=output_folder, output_prefix='output', format='wav')

以上でPythonを使用して音源ファイルのシーケンスを行うことができました。

 AIの学習データ作成などに使用できそうです。