spatialaudio / python-sounddevice

:sound: Play and Record Sound with Python :snake:
https://python-sounddevice.readthedocs.io/
MIT License
1.02k stars 149 forks source link

Recording multiple channels and one goes silent #391

Closed krote closed 2 years ago

krote commented 2 years ago

I'm trying to use ASIO's ChannelSelector to record and save sound sources coming in from multiple channels of a device into separate files.

I was able to record one channel at a time with no problem.

When I tried to do this in a separate process, an error occurred.

sounddevice.PortAudioError: Error starting stream: Unanticipated host error [PaErrorCode -9999]: 'Hardware input or output is not present or available' [ASIO error -1000]

If I call multiple rec functions in one process, I don't get an error, but the recording in the first rec doesn't seem to work and there is silence.

import sounddevice as sd
import soundfile as sf
import numpy as np

    asio_in = sd.AsioSettings(channel_selectors=[0]);
    recording1 = sd.rec(int(duration * rate), samplerate=rate, channels=1, extra_settings=asio_in)

    asio_in = sd.AsioSettings(channel_selectors=[1]);
    recording2 = sd.rec(int(duration * rate), samplerate=rate, channels=1, extra_settings=asio_in)
    sd.wait() 

    sf.write(filepath1, recording1, rate)
    sf.write(filepath2, recording2, rate)

In this code, the file saved with "recording2" is recording fine, but the file saved with "recording1" is silent.

mgeier commented 2 years ago

I'm trying to use ASIO's ChannelSelector to record and save sound sources coming in from multiple channels of a device into separate files.

Why don't you just record multiple channels at once and then split the result into separate channels which you can store in separate files?

When I tried to do this in a separate process, an error occurred.

There have been issues with multiprocessing in the past: https://github.com/spatialaudio/python-sounddevice/search?q=multiprocessing&type=issues

Maybe ASIO simply doesn't support that?

If I call multiple rec functions in one process, I don't get an error, but the recording in the first rec doesn't seem to work

It depends what you mean by "work".

Did you look at the docs?

According to https://python-sounddevice.readthedocs.io/en/0.4.4/api/convenience-functions.html#sounddevice.rec, rec() calls stop() first, which should explain the behavior, right?

krote commented 2 years ago

Hi mgeier,

Thank you for your response!

Why don't you just record multiple channels at once and then split the result into separate channels which you can store in separate files?

Since I was trying to record multiple channels of something like a radio program, I was trying to record each program separately. Since the recording timings are different, I was thinking of separate recording processes.

I didn't realize, looking at the old documentation, that stop was called in the rec. I understand now.

I guess I'll have to think about splitting it up after recording on multiple channels.

mgeier commented 2 years ago

Why don't you just record multiple channels at once and then split the result into separate channels which you can store in separate files?

Since I was trying to record multiple channels of something like a radio program, I was trying to record each program separately. Since the recording timings are different, I was thinking of separate recording processes.

That sounds like multiple processes would help, but I don't know if the ASIO API allows that. I have the feeling that the same device cannot be used simultaneously in multiple streams, let alone if those are used in different processes.

But I'm not a Windows user and haven't tried that. You should!

If it indeed is not possible to use multiple streams (with the host API of your choice), you can use a single stream with a custom callback function where you implement the necessary logic to record the channels that are currently requested (probably using a queue per recording?).

If the recording times are not hugely different, you might as well record everything all the time and separate the channels (and probably trim the individual recordings) afterwards.

krote commented 2 years ago

Hi, mgeier.

Thanks for the confirmation. I'm so glad you took the time to do this.

I'll think about it in the way you suggested. Thank you very much.

Regards.