Open bactone opened 3 years ago
Yes, exactly.
The behavior of sd.rec()
is described at https://python-sounddevice.readthedocs.io/en/latest/api/convenience-functions.html#sounddevice.rec.
And according to that, the first thing it does, is calling sd.stop()
, which immediately stops the playback of sd.play()
.
At some point you should also wait for your recording to be finished, otherwise myrecording
will not contain the expected data.
You probably want to use
playrec()
for that.
@HaHeho while, playrec() is not what I want. my application scenario is like this: first, I want to use play() to play a period of sound as the background sound, like 100 seconds. when I call play() with blocking=False, i expect it to return immediately but playback continues in the background, like the doc https://python-sounddevice.readthedocs.io/en/0.4.1/api/convenience-functions.html explained, so that the subsequent code (rec() or any other code) can be executed immediately, but when I set blocking=False, it quit playing sound. here bellow is a new demo code:
import numpy as np
import sounddevice as sd
fs = 44100 # sampling rate f = 1000 # frequency length = 3 # play time t = np.arange(fs length) # pt = 0.005 np.sin(2 np.pi f / fs * t) # data
sd.default.device = 'ASIO Fireface USB' asio_out = sd.AsioSettings(channel_selectors=[0])
sd.play(pt, fs, blocking=False, extra_settings=asio_out, loop=False) print("returns immediately")
2. set blocking=True, the sound is played, and then "returns immediately" is printed.
```python
import numpy as np
import sounddevice as sd
fs = 44100 # sampling rate
f = 1000 # frequency
length = 3 # play time
t = np.arange(fs * length) #
pt = 0.005 * np.sin(2 * np.pi * f / fs * t) # data
sd.default.device = 'ASIO Fireface USB'
asio_out = sd.AsioSettings(channel_selectors=[0])
sd.play(pt, fs, blocking=True, extra_settings=asio_out, loop=False)
print("returns immediately")
Yes, exactly.
The behavior of
sd.rec()
is described at https://python-sounddevice.readthedocs.io/en/latest/api/convenience-functions.html#sounddevice.rec.And according to that, the first thing it does, is calling
sd.stop()
, which immediately stops the playback ofsd.play()
.At some point you should also wait for your recording to be finished, otherwise
myrecording
will not contain the expected data.
@mgeier thanks, I notice that every time play(), rec(), or playrec() is called, it will stop the current running play or record. but even if I don't call rec() after play() with blocking=False, the play() don't play the sound, pls refer to my reply to @HaHeho
but even if I don't call rec() after play() with blocking=False, the play() don't play the sound
I guess this happens at the end of your Python script?
In this case, sd.play()
returns immediately, and since it is the end of the script, the Python interpreter shuts down, which automatically stops the playback (probably before it even starts playing).
You'll have to do something to keep the Python interpreter running. For example, you could run your script with python3 my_script.py -i
, which would keep the interpreter running after the end of the script.
Or you use sd.wait()
or blocking=True
.
I guess this happens at the end of your Python script?
And according to that, the first thing it does, is calling sd.stop(), which immediately stops the playback of sd.play().
@mgeier thanks, I just tried your suggestion and it works. so my question now is : is it ok to quit calling sd.stop() internally when calling play(), rec(), or playrec() , so that we can use play() and rec() (rather than playrec()) with parameter blocking=False asynchronously, besides we may set an ID for each play(), rec() or playrec() instance, and then we can call sd.stop(ID1), sd.wait(ID1) manually etc, i need your suggestions , thanks.
is it ok to quit calling sd.stop() internally when calling play(), rec(), or playrec()
This would have been possible, but I decided against it.
For me, the main use case for play()
, rec()
and playrec()
is in an interactive Python session. The API is optimized for that.
They can of course also be used in non-interactive scripts, but when the situation becomes more complicated, the "stream" API should be used instead.
we may set an ID for each play(), rec() or playrec() instance, and then we can call sd.stop(ID1), sd.wait(ID1) manually etc,
Again, this would have been possible, but I decided against it to keep the interactive use simple.
If you want such a behavior, you can implement it yourself based on the "stream" API.
I am trying to realize asynchronously play and record using play() and rec() methods, but when I set blocking=False for play(), it doesn't play sound anymore, here bellow is my demo-code, please help: