こちら にも書きましたが、単にPCMファイルをWAVファイルに変換するだけであれば、わざわざsox を使わなくても、Pythonの標準ライブラリの wave を使って簡単に行うことができます。
簡単ですがサンプルを書いてみましたので参考にしてください。
今回のデータがビックエンディアンとのことなので struct をつかってリトルエンディアン に変換しております。この部分はもう少しスマートな方法があるかもしれません。
Python
1import wave
2from struct import pack, unpack
3
4# pcmデータの読み込み
5with open("test.pcm", "rb") as f:
6 data = f.read()
7
8# ビックエンディアン->リトルエンディアン変換
9lst = unpack(">{}h".format(int(len(data)/2)), data)
10data = pack("{}h".format(len(lst)), *lst)
11
12#wavファイルに書き込み
13with wave.open("test.wav", "w") as wav:
14 wav.setnchannels(1) # 1ch
15 wav.setsampwidth(2) # 16bit
16 wav.setframerate(16000) # 16k
17 wav.writeframes(data)
エンディアン変換の補足
行っていることは
「バイト配列(バイナリデータ)」→「Int型のリスト(実データ)」→「バイト配列」
です。
順番に説明しますと、
まず第1ステップとして struct.unpack()
にてバイナリデータを実データに変換します。
その際にどのようなフォーマットで変換するかは第一引数にて指定します。
今回の場合は
- ビックエンディアン('>')
- 1つデータは2Byte('h')
なので ">##h"
としております。(ここで **##**には変換するデータ数が入りますので、format()
を使用して、もとのバイナリ長の1/2の値を入れております。)
ここで変換されたデータは実データとなりますので、信号処理や波形表示などを行う場合はこのlst を使うことができます。(一般的には lstはLR交互のデータなので、更に l,r=lst[0::2],lst[1::2]
などとしてLRを分離して使用することになります。)
で、次のステップとして struct.pack()
にて再度、Int配列をバイナリデータに変換しております。
ここも同様にフォーマット指定が必要な為、
- リトルエンディアン('<' :省略可能)
- 1つデータは2Byte('h')
の "##h"
を指定しております。(**##**には変換するデータ数を入れる必要がありますので、format()
を使用して、実データのサイズを入れております。)
structパッケージの詳細に関しては、公式ドキュメントを見てください。
https://docs.python.jp/3/library/struct.html
以上です。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/04/27 20:27
2017/05/15 21:19
2017/05/15 23:44