Считайте данные одного канала из волнового файла стереофонической волны с 24-битными данными в Python.

Я хочу читать левый и правый канал.

 import wave
 origAudio = wave.open("6980.wav","r")
 frameRate = origAudio.getframerate()
 nChannels = origAudio.getnchannels()
 sampWidth = origAudio.getsampwidth()
 nbframe=origAudio.getnframes()
 da = np.fromstring(origAudio.readframes(48000), dtype=np.int16)
 origAudio.getparams()

параметр

  (2, 3, 48000, 2883584, 'NONE', 'not compressed')

Теперь я хочу разделить левый и правый каналы с волновым файлом в 24-битных данных.


person mouride touba    schedule 09.11.2016    source источник


Ответы (2)


Вы можете использовать wavio, небольшой модуль, который я написал для чтения и записи файлов WAV с использованием массивов numpy. В твоем случае:

import wavio

wav = wavio.read("6980.wav")

# wav.data is the numpy array of samples.
# wav.rate is the sampling rate.
# wav.sampwidth is the sample width, in bytes.  For a 24 bit file,
# wav.sampwdith is 3.

left_channel = wav.data[:, 0]
right_channel = wav.data[:, 1]

wavio находится на PyPi, а исходный код находится на github по адресу https://github.com/WarrenWeckesser/wavio.

person Warren Weckesser    schedule 09.11.2016
comment
спасибо, это работает, но это правильно для волны модификатора, подписанной 24 бита в 16 бит - person mouride touba; 10.11.2016

Параметры говорят вам, что у вас есть 2 канала данных по 3 байта на семпл, на частоте 48 кГц. Поэтому, когда вы говорите readframes(48000), вы получаете одну секунду кадров, которые вы, вероятно, должны считывать в немного другую структуру данных:

da = np.fromstring(origAudio.readframes(48000), dtype=np.uint8)

Теперь у вас должно получиться 48000*2*3 байта, т.е. len(da). Чтобы взять только первый канал, вы должны сделать это:

chan1 = np.zeros(48000, np.uint32)
chan1bytes = chan1.view(np.uint8)
chan1bytes[0::4] = da[0::6]
chan1bytes[1::4] = da[1::6]
chan1bytes[2::4] = da[2::6]

То есть вы создаете массив целых чисел, по одному на выборку, и копируете соответствующие байты из исходных данных (вы можете попробовать скопировать непосредственно из результата readframes() и пропустить создание da).

person John Zwinck    schedule 09.11.2016
comment
Спасибо, @John Zwing. Я хочу взять данные левого и правого каналов. - person mouride touba; 09.11.2016
comment
@mouridetouba Хорошо, тогда попробуйте приведенное выше решение. Если это работает для левого канала, вы можете сделать то же самое для правого канала, но используя da[3::6], da[4::6] и da[5::6]. - person John Zwinck; 09.11.2016