質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2521閲覧

Python3でpcm形式データを読み込ませたい

Kenza

総合スコア21

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/06/25 10:23

前提・実現したいこと

pythonを用いて、ステレオ音源であるpcm形式データを読み込ませたいです。

発生している問題・エラーメッセージ

エラーメッセージ Error Traceback (most recent call last) <ipython-input-7-d3736e6975de> in <module> ----> 1 wave_file = wave.open(read_path, "rb") /anaconda3/envs/tensorflow/lib/python3.7/wave.py in open(f, mode) 508 mode = 'rb' 509 if mode in ('r', 'rb'): --> 510 return Wave_read(f) 511 elif mode in ('w', 'wb'): 512 return Wave_write(f) /anaconda3/envs/tensorflow/lib/python3.7/wave.py in __init__(self, f) 162 # else, assume it is an open file object already 163 try: --> 164 self.initfp(f) 165 except: 166 if self._i_opened_the_file: /anaconda3/envs/tensorflow/lib/python3.7/wave.py in initfp(self, file) 129 self._file = Chunk(file, bigendian = 0) 130 if self._file.getname() != b'RIFF': --> 131 raise Error('file does not start with RIFF id') 132 if self._file.read(4) != b'WAVE': 133 raise Error('not a WAVE file') Error: file does not start with RIFF id

該当のソースコード

Python3

1import wave 2import scipy as sp 3import numpy as np 4from scipy import signal 5import matplotlib.pyplot as plt 6 7read_path = "asmrdata/faucet_1.wav.new.pcm" 8write_path = "asmrdata/re_test.wav" 9 10wave_file = wave.open(read_path, "rb") 11

試したこと

そもそもしたいことは、Pythonでステレオ音源データを読み込ませたいです。

ので、はじめに、wavデータとして読み込ませましたが、Error: unknown format: 3 というエラー文が吐き出されたました。

この解決策を模索したところ、 https://teratail.com/questions/87433 を参考にし、
wavデータをpcm形式に変換し、読み込ませようとしました。

補足情報(FW/ツールのバージョンなど)

使用PC: macOS Mojave
実行環境: Python3

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tiitoi

2019/06/25 11:27

ライブラリが対応していないか、正しく変換できていないかのどちらかだと思いますが、元ファイルをどこかにアップしていただけないと、質問の情報だけでは回答するのは難しいです。
guest

回答1

0

ベストアンサー

うーん・・PCM形式って特に決まったフォーマットがあるわけでは無く、ただのRAWデータなので。

このデータを再生するには
・データのチャンネル数(今回はステレオ音源とのことなので2チャンネル)
・サンプリング周波数
・1データあたりのバイト数
・バイトオーダ(エンディアン)
等々が分からないと何ともなりません。

とりあえず読み込むだけであればサンプルレートは無くてもよいので他は「決め打ち」で

・チャンネル数:2
・データサイズ:16bit(2バイト)
・バイトオーダ:リトルエンディアン

として読み込む場合、単純に

Python

1import numpy as np 2with open('data.pcm', 'rb') as f: 3 buf = f.read() 4 data = np.frombuffer(buf, dtype='int16') 5 L = data[::2] 6 R = data[1::2]

で良いかと思います。


##【追記】

データを提示していただいたので。

とりあえず以下のようにWAVのデータ部のみをfloat32にて読み込み、int16 に変換してみたところ問題なく再生できているようです。
(データの開始位置 (0x58) は実データをバイナリエディタで解析した値を直打ちしております。)

Python

1import pyaudio 2import struct 3import numpy as np 4 5with open('faucet_1.wav', 'rb') as f: 6 buf = f.read()[0x58:] 7 8channel_num = 2 9sample_rate = 44100 10 11data = np.frombuffer(buf, dtype='float32') 12 13# 2バイトデータに変換して再生してみる 14sample_width = 2 15data = [int(d * 32767.0) for d in data] 16data = struct.pack('h' * len(data), *data) 17 18audio = pyaudio.PyAudio() 19stream = audio.open(format=audio.get_format_from_width(sample_width), 20 channels=channel_num, 21 rate=sample_rate, 22 output=True) 23 24chunk = 1024 25pos = 0 26while data != '': 27 stream.write(data[pos:pos+chunk]) 28 pos += chunk 29stream.close() 30 31audio.terminate()

今回の質問はデータを読み込みたいということでしたので、データを表示するとなるとこんな感じになるかと思います。

Python

1import numpy as np 2import matplotlib.pyplot as plt 3 4with open('faucet_1.wav', 'rb') as f: 5 buf = f.read()[0x58:] 6 7channel_num = 2 8sample_rate = 44100 9 10data = np.frombuffer(buf, dtype='float32') 11l_data = data[0::2] 12r_data = data[1::2] 13 14# 0~1 秒のデータを表示 15t = np.arange(0, 1., 1/sample_rate) 16fig, axs = plt.subplots(2,1) 17axs[0].plot(t, l_data[:len(t)]) 18axs[1].plot(t, r_data[:len(t)]) 19plt.show() 20

投稿2019/06/26 00:03

編集2019/06/27 09:01
magichan

総合スコア15898

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

magichan

2019/06/27 08:43

データを確認しましたが、提示されたPCMデータはうまく変換できていないような気がします。 単にRIFFヘッダを外して、3バイト単位でバイトオーダを変更しただけのデータのようなので、真っ当に変換できていないように思います。
magichan

2019/06/27 09:00

とりあえず実データを元にデータを取得する方法を追記しました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問