Closed ethancrawford closed 3 years ago
A minimal example (not too much, if you neglect all the input parameter parsing) is shown in play_file.py.
There you see that writing to the stream actually happens in the callback()
function which is automatically triggered in the appropriate pace (depending on chunk size and sampling frequency). The code becomes much more complicated obviously, but the examples provide a good assistance to learn how to. And in this way, you may have full control over each individual chunk being delivered in time to the output.
It gets even more funky with an additional queues being filled, if you want to playback a very long file (one that may not fit into memory all at once) with this advanced method in play_long_file.py.
Ah, yes. Thanks for pointing all that out - good to know 🙂
I'm wondering if I'm missing something obvious.
No, you might have found a bug.
Is your file a mono file?
It looks like when data
is one-dimensional, the Stream.write()
function doesn't check whether the stream has one channel.
In your case, the stream has 4 channels, so the audio data is distributed over 4 channels, each one being four times faster (i.e. two octaves higher) than intended (and probably having some aliasing artifacts).
So I think this is a bug.
As a work-around, you can use channels=1
when creating the OutputStream
.
Oh! It was indeed a mono sample. Thanks for the clarification and workaround 😄
I've just created #372 which hopefully fixes this issue.
@ethancrawford Can you please check if that works for your example?
And by "work" I mean it should raise a meaningful error instead of playing back the wrong thing.
🙂
As requested:
Running the code snippet in my original comment plays a sound for the call to .play
, and for the manual OutputStream, produces the following:
Traceback (most recent call last):
File "/Users/ethan/Desktop/test_sound.py", line 13, in <module>
output.write(data)
File "/Users/ethan/.pyenv/versions/3.9.0/lib/python3.9/site-packages/sounddevice.py", line 1532, in write
raise ValueError('number of channels must match')
(After running the following commands to bring in your fix of course):
python3 -m pip uninstall sounddevice
python3 -m pip install git+https://github.com/mgeier/python-sounddevice.git@write-one-dimensional
Thanks for testing! I've just merged #372. If there's anything else not working, please let me know!
When I use the convenience function
play
to play a wav file at a particular samplerate, it seems to play back at the correct rate. However, when I attempt to play the same wav file by manually creating an OutputStream with the same samplerate, the sample seems to play back at far too high a rate.To the best of my knowledge, I set things up correctly, but I'm wondering if I'm missing something obvious. I'd appreciate some advice if so. Below are some details - pardon me if I've left anything important out, I can update this (such as with a link to the sound file itself) if needed.
Platform/API: macOS/Core Audio Audio device: Scarlett 4i4 USB (6 in, 4 out) (device 3 according to
query_devices()
) Python module versions:The minimal(ish) script that reproduces this on my system: