pyaudio中的数据中的数据是什么格式和数据类型?

发布于 2025-01-24 13:20:20 字数 1229 浏览 3 评论 0原文

我正在尝试将Pyaudio用于实时音频应用程序。我编写的作品的程序,但我正在尝试优化速度。此外,我遇到的主要问题是我正在尝试处理stream.read()数据。在执行此操作的一般方法中,数据存储在一个名为“帧”的数组中,您只需将每个块附加到数组。然后将此数组处理到.WAV文件中。我想将其翻译成具有其数字价值的含义的整数或浮点,但我不知道这样做的转换。为了更清楚,我使用的代码将帧数组转换为.wav文件。然后,我使用声音弹来将.WAV文件数据重新转换为点。然后,我将这些点用于频率处理,并且效果很好。我想切断需要转换为WAV并从WAV返回以获取可用数据的需要。我相信数据值以字节格式为单位,但代表16位整数,但是当我除以2^16时,我没有得到正确的值。对此有些确认会有所帮助。这与我没有频率处理的事情类似

import pyaudio
import wave


filename = "recorded.wav"
chunk = 1024
FORMAT = pyaudio.paInt16
channels = 1
sample_rate = 44100
record_seconds = 5


p = pyaudio.PyAudio()
# open stream object as input & output
stream = p.open(format=FORMAT,
                channels=channels,
                rate=sample_rate,
                input=True,
                output=True,
                frames_per_buffer=chunk)
frames = []
print("Recording...")
for i in range(int(sample_rate / chunk * record_seconds)):
    #what is this value?????????
    data = stream.read(chunk)
    frames.append(data)

print("Finished recording.")

stream.stop_stream()
stream.close()
p.terminate()

wf = wave.open(filename, "wb")
wf.setnchannels(channels)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(sample_rate)
wf.writeframes(b"".join(frames))
wf.close()

I am trying to use pyaudio for a real time audio application. The program that I wrote works, but I am trying to optimize the speed. Additionally, the main issue I have is that I am trying to process the stream.read() data. In the general method for doing this, the data is stored into an array called frames where you just append each chunk to the array. This array is then processed into a .wav file. I want to translate this over into integers or float that have meaning in terms of their digital value but I do not know the conversion to do so. To make this clearer, the code that I use translates the frames array into a .wav file. Then, I use soundfile to translate the .wav file data back into points. These points I then run for frequency processing and it works well.I want to cut out needing to convert to a wav and back from a wav to get usable data. I believe that the data values are in byte format but represent a 16 bit integer, but when I divide by 2^16 I do not get the correct value. Some confirmation on this would be helpful. Here is something similar to what i'm doing without the frequency processing

import pyaudio
import wave


filename = "recorded.wav"
chunk = 1024
FORMAT = pyaudio.paInt16
channels = 1
sample_rate = 44100
record_seconds = 5


p = pyaudio.PyAudio()
# open stream object as input & output
stream = p.open(format=FORMAT,
                channels=channels,
                rate=sample_rate,
                input=True,
                output=True,
                frames_per_buffer=chunk)
frames = []
print("Recording...")
for i in range(int(sample_rate / chunk * record_seconds)):
    #what is this value?????????
    data = stream.read(chunk)
    frames.append(data)

print("Finished recording.")

stream.stop_stream()
stream.close()
p.terminate()

wf = wave.open(filename, "wb")
wf.setnchannels(channels)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(sample_rate)
wf.writeframes(b"".join(frames))
wf.close()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

失退 2025-01-31 13:20:20

将其转换为整数列表,

#data = b"".join(frames)
data = b"\x01\x02\x01\x04"   # example data for test

result = []

for index in range(0, len(data), 2):
    value = int.from_bytes(data[index:index+2], 'big')
    result.append(value)
    #print(value)    

print(result)

它以字符字符串获取数据,您可以使用结果

[258, 260]

我只知道字符的顺序使用了哪个字符串中的16位整数 - biglittlebig-endianLittle-endian


编辑:

您还可以使用标准模块 struct

h表示16位unsigned整数>表示big-endian

#data = b"".join(frames)
data = b"\x01\x02\x01\x04"

import struct

length = len(data) // 2
result = struct.unpack(f'>{length}H', data)

print(result)

或使用迭代器(因此您可以运行它使用每个,而不是使用完整data

result = []

for items in struct.iter_unpack(f'>H', data):
    result.append( items[0] )
    
print(result)

编辑:

您还可以使用标准模块 array

#data = b"".join(frames)
data = b"\x01\x02\x03\x04"
    
import array

#a = array.array('H')
#a.frombytes(data)

a = array.array('H', data)
a.byteswap()  # convert from little-endian to big-endian

print(a.tolist())    

如果您使用numpy,则可以使用 numpy.frombuffer

#data = b"".join(frames)
data = b"\x01\x02\x03\x04"

import numpy as np

arr = np.frombuffer(data, dtype='uint16')

print(arr)

但这使用little-endian order。

对于big-endian您可以使用dtype ='> u2'

arr = np.frombuffer(data, dtype='>u2')

dt = np.dtype('uint16').newbyteorder('>')
arr = np.frombuffer(data, dtype=dt)

It gets data as bytes string and you can convert it to list of integers using

#data = b"".join(frames)
data = b"\x01\x02\x01\x04"   # example data for test

result = []

for index in range(0, len(data), 2):
    value = int.from_bytes(data[index:index+2], 'big')
    result.append(value)
    #print(value)    

print(result)

Result

[258, 260]

I only don't know what order of bytes uses 16bit integer in this string - big or little (big-endian or little-endian)


EDIT:

You can also use standard module struct for this.

H means 16 bit unsigned integer and > means big-endian

#data = b"".join(frames)
data = b"\x01\x02\x01\x04"

import struct

length = len(data) // 2
result = struct.unpack(f'>{length}H', data)

print(result)

or using iterator (so you could run it with every chunk instead of using full data)

result = []

for items in struct.iter_unpack(f'>H', data):
    result.append( items[0] )
    
print(result)

EDIT:

You can also use standard module array

#data = b"".join(frames)
data = b"\x01\x02\x03\x04"
    
import array

#a = array.array('H')
#a.frombytes(data)

a = array.array('H', data)
a.byteswap()  # convert from little-endian to big-endian

print(a.tolist())    

If you use numpy then you can use numpy.frombuffer

#data = b"".join(frames)
data = b"\x01\x02\x03\x04"

import numpy as np

arr = np.frombuffer(data, dtype='uint16')

print(arr)

but this uses little-endian order.

For big-endian you can use dtype='>u2'

arr = np.frombuffer(data, dtype='>u2')

or

dt = np.dtype('uint16').newbyteorder('>')
arr = np.frombuffer(data, dtype=dt)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文