Я прочитал буфер байтов из данных, записанных через микрофон моего компьютера (2 канала), используя пример pyaudio
, взятый с сайта.Как преобразовать байты в np.array
import pyaudio
import wave
CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 2
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "output.wav"
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("* recording")
frames = []
for i in range(0, int(RATE/CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
frames.append(data)
print("* done recording")
print frames
frames
выглядит следующим образом:
['\x00\xfd\xff\xff.....\xfc\xff\xff', '\xff\xfc\xff\xff......\xfc\xff\xff', ... ]
или если я меняю CHUNK = 1
:
['\x00\xfd\xff\xff', '\xff\xfc\xff\xff', '\x00\xfd\xcc\xcf']
, хотя, конечно, гораздо больше. Я подозреваю, что байты чередуются для каждого канала, поэтому я думаю, что мне нужно разбить их парами из двух.
То, что я хотел бы это массив так:
np.array([
[123, 43],
[3, 433],
[43, 66]
])
, где первый столбец значения из первого канала, а второй из второго канала. как я могу интерпретировать эти закодированные значения (с CHUNK
установлен на разумное значение, например 1024)?
UPDATE:
Я совершенно запутался. Я использовал ниже, чтобы изменить список строк format
в одну строку шестнадцатеричных значений, разделенных пробелами, но, похоже, их нечетное число ... это не произойдет, если есть два значения: по одному для каждого канала (будет четное число):
fms = ''.join(frames)
fms_string = ''.join([ "%02X " % ord(x) for x in fms ]).strip()
fms_list = fms_string.split(" ")
print len(fms_list) # this prints an ODD number...
UPDATE 2:
Я попробовал более простой путь и попытался это:
import array
fstring = ''.join(frames)
wave_nums = array.array('h', fstring) # this correctly returns list of ints!
print len(wave_nums)
Я попробовал это в разное время записи го были получены следующие результаты (запутанных):
RECORD_SECONDS = 2 ---> len(wave_nums) is 132300 (132300/44100 = 3 seconds of frames)
RECORD_SECONDS = 4 ---> len(wave_nums) is 308700 (308700/44100 = 7 seconds of frames)
RECORD_SECONDS = 5 ---> len(wave_nums) is 396900 (396900/44100 = 9 seconds of frames)
, который подразумевает, что я получаю количество кадров в соответствии с 2*(number of seconds recording) - 1
секунд ... как это возможно?
на 'encode()' строка: 'UnicodeDecodeError: 'ascii' кодек не может декодировать байт 0xff в позиции 608: порядковый номер не в диапазоне (128)' – lollercoaster
и без этого строки 'map()' fail с: 'TypeError: неподдерживаемый тип операндов для <<: 'str' и 'int'' – lollercoaster
Интересный ... Он работает в python3, я посмотрю на него –