Reading Qaudioprobe Buffer
Solution 1:
I ran into the same issue with a fresh PySide2 5.13.2
environment, and running print(probe.data().toBytes())
returned chunks of size 0 which I knew couldn't be the case because other built-in functionality was accessing the data.
I hate this hack as much as anyone else, but if you want to test things it is possible to access the buffer contents this way (please do not use this in production code):
Find out about the datatype, endian-ness etc of your buffer via format, and infer the proper C type that you'll need (e.g. signed int 16).
Extract the printed address from the
VoidPtr
printout, and convert it to an integerCreate a numpy array by reading at the given address, with the given type, and by the given amount of frames.
Code:
First of all, somewhere in your app, you'll be connecting your QAudioProbe
to your source via setSource
, and then the audioBufferProbed
signal to a method e.g.:
self.audio_probe.audioBufferProbed.connect(self.on_audio_probed)
Then, the following on_audio_probed
functionality will fetch the numpy array and print its norm, which should increase in presence of sound:
import numpy as np
import ctypes
defget_buffer_info(buf):
"""
"""
num_bytes = buf.byteCount()
num_frames = buf.frameCount()
#
fmt = buf.format()
sample_type = fmt.sampleType() # float, int, uint
bytes_per_frame = fmt.bytesPerFrame()
sample_rate = fmt.sampleRate()
#if sample_type == fmt.Float and bytes_per_frame == 4:
dtype = np.float32
ctype = ctypes.c_float
elif sample_type == fmt.SignedInt and bytes_per_frame == 2:
dtype = np.int16
ctype = ctypes.c_int16
elif sample_type == fmt.UnsignedInt and bytes_per_frame == 2:
dtype = np.uint16
ctype = ctypes.c_uint16
#return dtype, ctype, num_bytes, num_frames, bytes_per_frame, sample_rate
defon_audio_probed(audio_buffer):
"""
"""
cdata = audio_buffer.constData()
(dtype, ctype, num_bytes, num_frames,
bytes_per_frame, sample_rate) = get_buffer_info(audio_buffer)
pointer_addr_str = str(cdata).split("Address ")[1].split(", Size")[0]
pointer_addr = int(pointer_addr_str, 16)
arr = np.array((ctype * num_frames).from_address(pointer_addr))
print(np.linalg.norm(arr)) # should increase in presence of sound
I just tested it with a QAudioRecorder
using 16-bit unsigned wavs, and it worked "fine" (audio looked and sounded good, see screenshot below). Again, this is basically a meme code so anything above showing your fancy audio buffered app to your cousins will be extremely risky, do not use in serious code. But in any case let me know if any other workarounds worked for you, or if this also worked in a different context! Hopefully if the devs see that people are actually using this approach they'll fix the issue much sooner :)
Cheers! Andres
Post a Comment for "Reading Qaudioprobe Buffer"