Python 如何将字节转换为np.array

Python 如何将字节转换为np.array,python,audio,bytearray,Python,Audio,Bytearray,我使用pyaudio从现场采集的示例,从计算机麦克风(2个通道)记录的数据中读取字节缓冲区 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,

我使用
pyaudio
从现场采集的示例,从计算机麦克风(2个通道)记录的数据中读取字节缓冲区

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
如下所示:

['\x00\xfd\xff\xff.....\xfc\xff\xff', '\xff\xfc\xff\xff......\xfc\xff\xff', ... ]
np.array([
  [123, 43],
  [3, 433],
  [43, 66]
])
或者如果我更改
CHUNK=1

['\x00\xfd\xff\xff', '\xff\xfc\xff\xff', '\x00\xfd\xcc\xcf']
当然要长得多。我怀疑每个通道的字节是交错的,所以我想我需要将它们分成两对

我想要的是这样一个数组:

['\x00\xfd\xff\xff.....\xfc\xff\xff', '\xff\xfc\xff\xff......\xfc\xff\xff', ... ]
np.array([
  [123, 43],
  [3, 433],
  [43, 66]
])
其中第一列是来自第一个通道的值,第二列是来自第二个通道的值。如何解释这些编码值(将
CHUNK
设置为合理的值,如1024)


更新:

我很困惑。我使用下面的命令将字符串的
格式
列表更改为一个由空格分隔的十六进制值组成的字符串,但其中似乎有奇数…如果有两个值,每个通道一个值(可能是偶数),则不会发生这种情况:


更新2:

我尝试了一条更简单的路线,并尝试了以下方法:

import array
fstring = ''.join(frames)
wave_nums = array.array('h', fstring) # this correctly returns list of ints!
print len(wave_nums) 
我尝试了不同的录制时间,得到了以下结果(令人困惑):


这意味着我得到的帧数与
2*(录制秒数)-1
秒一致……这怎么可能呢?

基于对portaudio源的快速浏览,它看起来像

您可以使用联接来展平列表,计算左值和右值(将其设置为16位长),然后将列表本身压缩

joined = ''.join(frames).encode('latin-1')

left = map(lambda m, l: (m << 8) + l, joined[0::4], joined[1::4])
right = map(lambda m, l: (m << 8) + l, joined[2::4], joined[3::4])

zipped = zip(left, right)
join='''.join(帧).encode('latin-1'))

左=图(λm,l:(m最简单的答案似乎是:

import array
f = ''.join(frames)
nums = array.array('h', f)
left = nums[1::2]
right = nums[0::2]
@Dylan的回答也很好,但有点冗长,而且值是无符号的,其中wav值是有符号的


另外,将
块更改为1225也是最好的,因为44100是1225的倍数,并且不会因为舍入错误而丢失任何帧。

encode()
行:
UnicodeDecodeError:“ascii”编解码器无法解码位置608处的字节0xff:序号不在范围(128)
如果没有舍入错误,
map()
行失败,原因是:
TypeError:不支持的操作数类型似乎可以正常工作,但由于某些原因,在录制1秒音频并使用此代码后,
的长度为44032(此时应为44100)。不知怎的,68帧丢失了。嗯,当你进行
速率/块
,215*1024是44032时,可能会被截断除法。我想你想为pyaudio进行录制,这样你就不必担心手动读取字节了。但是,你的耳朵不应该注意到这么小的加速。尝试使用pyaudio来播放sampled返回数据。
import array
f = ''.join(frames)
nums = array.array('h', f)
left = nums[1::2]
right = nums[0::2]