refactor: python implementation of `audioop.mul`
Summary
This PR replaces the PCMVolumeTransformer.read() method with a Python equivalent, that does not use the audioop module, which is deprecated since Python 3.11 and will be removed in Python 3.13.
This implements #2177.
Information
- [ ] This PR fixes an issue.
- [x] This PR adds something new (e.g. new method or parameters).
- [ ] This PR is a breaking change (e.g. methods or parameters removed/renamed).
- [ ] This PR is not a code change (e.g. documentation, README, typehinting, examples, ...).
Checklist
- [x] I have searched the open pull requests for duplicates.
- [x] If code changes were made then they have been tested.
- [x] I have updated the documentation to reflect the changes.
- [ ] If
type: ignorecomments were used, a comment is also left explaining why. - [x] I have updated the changelog to include these changes.
A python equivalent will not be nearly as close as the C one in terms of performance. Live audio is a heavy load and has to be low latency.
A python equivalent will not be nearly as close as the C one in terms of performance. Live audio is a heavy load and has to be low latency.
I mean we can always rewrite it in Rust.
and also this largely uses python stdlib modules which from the seems of things are written in C in many places.
A python equivalent will not be nearly as close as the C one in terms of performance. Live audio is a heavy load and has to be low latency.
I mean we can always rewrite it in Rust.
The whole voice stuff could be rewritten to Rust 😬
and also this largely uses python stdlib modules which from the seems of things are written in C in many places.
Possible to do actual performance tests?
A python equivalent will not be nearly as close as the C one in terms of performance. Live audio is a heavy load and has to be low latency.
I mean we can always rewrite it in Rust.
The whole voice stuff could be rewritten to Rust 😬
only if :)
audioop:
Without audioop:
Hardware: OS Name Microsoft Windows 10 Pro Processor AMD Ryzen 5 5600X 6-Core Processor, 3701 Mhz, 6 Core(s), 12 Logical Processor(s)
Hmm that sure is a difference.
Use time.perf_counter_ns() instead of time.time(). The result will be more accurate and will return ns instead of s
Can we maintain and ship our own audioop C file? Dpy plans to do something like that
Or we could try Cython or maybe Rust?
There, it's faster now:
With time.perf_counter_ns() pure Python:
audioop:
def timeit(f: Callable, ):
def wrapper(*args, **kwargs):
start = time.perf_counter_ns()
result = f(*args, **kwargs)
print(f"Elapsed: {(time.perf_counter_ns() - start)} ns")
return result
return wrapper
for anyone trying to benchmark:
I can rewrite it in C as a actual python module if you'd like, possible compile it first with cython and then optimize? However if you want this to be usable on multiple Python version and OSes you'd have to create a suitable build system with github jobs
CPU running at 1 GHz, latest changes:
I think this should be more than enough optimized, since this function reads 20ms of audio.
R5 5600x 4.7 GHz
Elapsed: 31819500 ns
Elapsed: 1016100 ns
Elapsed: 868800 ns
Elapsed: 739800 ns
Elapsed: 897400 ns
Elapsed: 743300 ns
Elapsed: 732200 ns
Elapsed: 784500 ns
Elapsed: 840000 ns
Wow that is some real improvement 👍
LGTM