Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pyaudioop.rms() TypeError: 'float' object cannot be interpreted as an integer and NameError: name 'buffer' is not defined #768

Open
aaronchantrill opened this issue Dec 24, 2023 · 1 comment

Comments

@aaronchantrill
Copy link

aaronchantrill commented Dec 24, 2023

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

@khoran
Copy link

khoran commented May 15, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants