spotify / pedalboard

🎛 🔊 A Python library for audio.
https://spotify.github.io/pedalboard
GNU General Public License v3.0
4.96k stars 249 forks source link

Add AudioFile::encode. #303

Closed psobot closed 3 months ago

psobot commented 3 months ago

Instead of:

buf = io.BytesIO()
with AudioFile(buf, "w", samplerate, num_channels, bit_depth, format, quality) as f:
    f.write(samples)
result = buf.getvalue()

...this PR adds:

result = AudioFile.encode(samples, samplerate, format, num_channels, bit_depth, format)

...which releases the GIL while processing, doesn't require calling Python for every .write()/.seek()/.tell() during encoding, and is much cleaner to read. This particularly speeds up encoding for OGG files, which involves a lot of small .write() calls.


Comes with new docs:

image image

Comparing performance between these two APIs when another thread is hogging the GIL:

GIL: 94.00%, Active: 161.00%, Threads: 9

  %Own   %Total  OwnTime  TotalTime  Function (filename)                                                                                                                                 
 98.00%  98.00%    9.84s     9.84s   use_gil (tests/test_io_threading.py)
 63.00%  63.00%    7.68s     7.68s   do_work_with_bytesio (tests/test_io_threading.py)
GIL: 100.00%, Active: 795.00%, Threads: 9

  %Own   %Total  OwnTime  TotalTime  Function (filename)                                                                                                                                 
697.00% 697.00%   43.83s    43.83s   do_work_with_encode (tests/test_io_threading.py)
 98.00%  98.00%    6.33s     6.33s   use_gil (tests/test_io_threading.py)
Time taken to call write(10 minutes) for 1 file per thread in 8 threads: 74.01 seconds
Time taken to call encode(10 minutes) for 1 file per thread in 8 threads: 4.30 seconds