-
Notifications
You must be signed in to change notification settings - Fork 151
Closed
Description
Grettings,
I am trying to write a script that reads two different output streams, the first being continuous while the second consists of short signals controlled by the user via the keyboard.
The script works well on the laptop sound card using MME, but I got a "unvailable output device" error when I try to run it on an external sound card (RME Fireface 802) using ASIO drivers (on Windows 10).
Here is a minimal example with a sine wave and a noise signal:
import sys
import numpy as np
import sounddevice as sd
start_index = 0
def main() -> None:
# General parameters
# asio_setting = sd.query_devices("asio")
asio_setting = sd.query_devices(None, "output")
sample_rate = int(asio_setting["default_samplerate"])
device_index = asio_setting["index"]
dtype = "float32" # sounddevice uses float32 by default
n_channels = 2
# Noise duration
noise_duration = 2
n_samples_noise = round(noise_duration * sample_rate)
noise = np.random.randn(n_samples_noise)
noise *= 0.1
output_buffer = np.zeros((n_samples_noise, n_channels), dtype=dtype)
output_buffer[:, 1] = noise
def callback(outdata, frames, time, status):
# Check for any errors
if status:
print(status, file=sys.stderr)
# Generate a sine wave signal
global start_index
t = (start_index + np.arange(frames)) / sample_rate
outdata[:, 0] = 0.2 * np.sin(
2 * np.pi * 440 * t
) # 440 Hz sine wave at 20% amplitude
outdata[:, 1] = 0.0
start_index += frames
try:
with sd.OutputStream(
samplerate=sample_rate,
channels=n_channels,
callback=callback,
device=device_index,
):
sd.sleep(1_000) # Wait 1 second
# Loop over all the sentences and play them
for _ in range(3):
with sd.OutputStream(
samplerate=sample_rate, channels=n_channels, device=device_index
) as stream:
stream.write(output_buffer)
# Once the noise is played, let user launch the next one
print("#" * 80)
print(
"Presser 'Entrée' pour continuer ou 'q' puis 'Entrée' pour quitter"
)
print("#" * 80)
input_str = input()
if input_str.lower() == "q":
sd.stop()
break
except KeyboardInterrupt:
sys.exit("\nInterrompu par l'utilisateur")
except Exception as e:
sys.exit(type(e).__name__ + ": " + str(e))
if __name__ == "__main__":
main()
The error occurs when creating the second OutputStream.
Do I need to call both OutputStreams from the same thread ? How can I code it ?
Could asyncio be a solution ?
Metadata
Metadata
Assignees
Labels
No labels