pyaudioop.rms() TypeError: 'float' object cannot be interpreted as an integer and NameError: name 'buffer' is not defined
aaronchantrill opened this issue · 1 comments
Steps to reproduce
I am attempting to use pyaudioop as a replacement for audioop which is deprecated and slated for removal in Python 3.13
I am using the rms method to get a volume level.
I found an issue here #725 that seems to address the change and recommends using pydub.pyaudioop as a substitute.
Unfortunately, pydub.pyaudioop makes heavy use of the buffer() function, which appears to have been removed from python 3 early in its development, so I'm not sure how it helps with the Python 3.13 transition.
Expected behavior
The rms function should return an integer
$ python
Python 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pydub import pyaudioop as audioop
>>> print(audioop.rms(b'\x00'*960, 2))
0
Actual behavior
$ python
Python 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pydub import pyaudioop as audioop
>>> print(audioop.rms(b'\x00'*960, 2))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "~/.virtualenvs/Naomi/lib/python3.11/site-packages/pydub/pyaudioop.py", line 149, in rms
sum_squares = sum(sample**2 for sample in _get_samples(cp, size))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "~/.virtualenvs/Naomi/lib/python3.11/site-packages/pydub/pyaudioop.py", line 149, in <genexpr>
sum_squares = sum(sample**2 for sample in _get_samples(cp, size))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "~/.virtualenvs/Naomi/lib/python3.11/site-packages/pydub/pyaudioop.py", line 36, in _get_samples
for i in range(_sample_count(cp, size)):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'float' object cannot be interpreted as an integer
Now, the value being returned here is actually the floating point form of an integer (480.0), so if we wrap the _sample_count() in an int(), then we get:
$ python
Python 3.11.2 (main, Mar 13 2023, 12:18:29) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from pydub import pyaudioop as audioop
>>> print(audioop.rms(b'\x00'*960, 2))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "~/.virtualenvs/Naomi/lib/python3.11/site-packages/pydub/pyaudioop.py", line 149, in rms
sum_squares = sum(sample**2 for sample in _get_samples(cp, size))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "~/.virtualenvs/Naomi/lib/python3.11/site-packages/pydub/pyaudioop.py", line 149, in <genexpr>
sum_squares = sum(sample**2 for sample in _get_samples(cp, size))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "~/.virtualenvs/Naomi/lib/python3.11/site-packages/pydub/pyaudioop.py", line 37, in _get_samples
yield _get_sample(cp, size, i, signed)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "~/.virtualenvs/Naomi/lib/python3.11/site-packages/pydub/pyaudioop.py", line 53, in _get_sample
return struct.unpack_from(fmt, buffer(cp)[start:end])[0]
^^^^^^
NameError: name 'buffer' is not defined
In my case, my data is being pulled from PyAudio or pyAlsaAudio is already in a bytes-like string, so I can just define buffer like:
def buffer(o):
return o
and it works, but I have seen some different discussions of replacements for the buffer() function including memoryview() and bytes(). As far as I can tell, the purpose is to collapse an iterable object into a byte array so that slicing operations can be used on it.
Your System configuration
- Python version: Python 3.11.2
- Pydub version: 0.25.1 (installed via pip)
- ffmpeg or avlib?: ffmpeg
- ffmpeg/avlib version: 5.1.4-0
Is there an audio file you can include to help us reproduce?
This is not related to a specific audio file, but you can use the code above to verify
I'm also getting a similar error when using the audioop.max function:
Traceback (most recent call last):
File "/opt/LED_VU.py", line 42, in <module>
max_vol=audioop.max(data,2)
^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/site-packages/pydub/pyaudioop.py", line 120, in max
return builtin_max(abs(sample) for sample in _get_samples(cp, size))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/site-packages/pydub/pyaudioop.py", line 120, in <genexpr>
return builtin_max(abs(sample) for sample in _get_samples(cp, size))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.11/site-packages/pydub/pyaudioop.py", line 36, in _get_samples
for i in range(_sample_count(cp, size)):
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'float' object cannot be interpreted as an integer
data
is from alsaaudio PCM.read.