ぽきたに 〜ありきたりな非凡〜

日々の独り言とちょっとした発信

【Python】WAVファイルを等間隔に分割するプログラム【サウンドプログラミング】

どうもこんにちは。たっきーです。

もうすっかり寒くなって暖房なしの氷河期部屋じゃ息ができませんね。。。

 

 

なにする?

タイトル通り、WAVファイルを等間隔で分割するプログラムをPythonで書く。

↓一秒に切り取ったWAVファイル。

f:id:tacky0612:20171121155747p:plain
piano/1.wav

 

モチベーション

機械学習用にデータセットを用意したい。

機械学習用のデータ[行列(配列?)]はデータの個数が等しくしなちゃめんどくさいので等間隔に切り取りたい。

Audacityを使って手作業で切り取るのもちょっと考えたけど、等間隔に切り取る作業初めて3秒で飽きた。

ちょっと人間には厳しいので、Pythonにやらせる。

つまり、自動化して楽したい。

 

環境

  • numpy 1.13.3
  • scipy 0.19-.1

 

コード

 

import wave
import struct
import math
import os
from scipy import fromstring, int16

# 一応既に同じ名前のディレクトリがないか確認。
file = os.path.exists("output")
print(file)

if file == False:
    #保存先のディレクトリの作成
    os.mkdir("output")

def cut_wav(filename,time):  # WAVファイルを刈り奪る 形をしてるだろ? 
    # timeの単位は[sec]

    # ファイルを読み出し
    wavf = filename + '.wav'
    wr = wave.open(wavf, 'r')

    # waveファイルが持つ性質を取得
    ch = wr.getnchannels()
    width = wr.getsampwidth()
    fr = wr.getframerate()
    fn = wr.getnframes()
    total_time = 1.0 * fn / fr
    integer = math.floor(total_time) # 小数点以下切り捨て
    t = int(time)  # 秒数[sec]
    frames = int(ch * fr * t)
    num_cut = int(integer//t)

    # 確認用
    print("Channel: ", ch)
    print("Sample width: ", width)
    print("Frame Rate: ", fr)
    print("Frame num: ", fn)
    print("Params: ", wr.getparams())
    print("Total time: ", total_time)
    print("Total time(integer)",integer)
    print("Time: ", t) 
    print("Frames: ", frames) 
    print("Number of cut: ",num_cut)

    # waveの実データを取得し、数値化
    data = wr.readframes(wr.getnframes())
    wr.close()
    X = fromstring(data, dtype=int16)
    print(X)


    for i in range(num_cut):
        print(i)
        # 出力データを生成
        outf = 'output/' + str(i) + '.wav' 
        start_cut = i*frames
        end_cut = i*frames + frames
        print(start_cut)
        print(end_cut)
        Y = X[start_cut:end_cut]
        outd = struct.pack("h" * len(Y), *Y)

        # 書き出し
        ww = wave.open(outf, 'w')
        ww.setnchannels(ch)
        ww.setsampwidth(width)
        ww.setframerate(fr)
        ww.writeframes(outd)
        ww.close()

print("input filename = ")
f_name = input()
print("cut time = ")
cut_time = input()
cut_wav(f_name,cut_time)

 

実行すると同じディレクトリ内にoutputというディレクトリが作成され、カットしたいファイル名とカットしたい時間[sec]の入力を求められるので入力してください。

※ファイル名に.wavの記入は必要ありません。

※カットしたいWAVファイルと同じ階層にこの.pyファイルを書く必要有り

 

↓一秒で等間隔にカットした結果。

f:id:tacky0612:20171121162539p:plain

 

f:id:tacky0612:20171121162550p:plain

上手く動いた✌

 

 

参考

qiita.com

yukara-13.hatenablog.com

 

退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング

退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング

 

 

 

入門 Python 3

入門 Python 3

 

 

 

おわりに・感想 

手作業でAudacityを使うと20分割するだけで10分ぐらいかかってたけど、これなら1分とかからず済むので強い💪

機械学習用データセット作り頑張るぞい。

print文は確認用なので消したほうがスッキリするぞい。 

tacky0612.hatenablog.com

スポンサードリンク