Прочитать данные одного канала из стереофонического файла в Python

Я должен прочитать данные только с одного канала в стереофоническом файле на Python. Для этого я попробовал это с scipy.io:

import scipy.io.wavfile as wf
import numpy

def read(path):
    data = wf.read(path)
    for frame in data[1]:
        data = numpy.append(data, frame[0])
    return data

Но этот код очень медленный, особенно если мне приходится работать с более длинными файлами. Так кто-нибудь знает более быстрый способ сделать это? Я думал о стандартном волновом модуле с помощью wave.readframes (), но как там хранятся кадры?

2 ответа

Решение

scipy.io.wavfile.read возвращает кортеж (rate, data), Если файл стерео, data представляет собой массив с формой (nsamples, 2), Чтобы получить конкретный канал, используйте фрагмент data, Например,

rate, data = wavfile.read(path)
# data0 is the data from channel 0.
data0 = data[:, 0]

wave модуль возвращает кадры в виде строки байтов, которые могут быть преобразованы в числа с struct модуль. Например:

def oneChannel(fname, chanIdx):
""" list with specified channel's data from multichannel wave with 16-bit data """
    f = wave.open(fname, 'rb')
    chans = f.getnchannels()
    samps = f.getnframes()
    sampwidth = f.getsampwidth()
    assert sampwidth == 2
    s = f.readframes(samps) #read the all the samples from the file into a byte string
    f.close()
    unpstr = '<{0}h'.format(samps*chans) #little-endian 16-bit samples
    x = list(struct.unpack(unpstr, s)) #convert the byte string into a list of ints
    return x[chanIdx::chans] #return the desired channel

Если ваш WAV-файл имеет другой размер выборки, вы можете использовать функцию (более уродливый) в другом ответе, который я написал здесь.

Я никогда не использовал scipy"s wavfile функция, поэтому я не могу сравнить скорость, но wave а также struct подход, который я использую здесь, всегда работал для меня.

Скорость , audio = wavfile.read(путь)

audio = np.mean(audio, axis=1)

Другие вопросы по тегам