Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multichannel Audio Recording/Routing on Windows 10 #4895

Closed
tugrulsalci opened this issue Apr 25, 2020 · 15 comments
Closed

Multichannel Audio Recording/Routing on Windows 10 #4895

tugrulsalci opened this issue Apr 25, 2020 · 15 comments

Comments

@tugrulsalci
Copy link

tugrulsalci commented Apr 25, 2020

I am trying to record multichannel audio on Supercollider. I am using Tidalcycles and I can see with s.meter that I get the audio multichannel in Supercollider. But I cannot hear any sound after third channel (after d3 or orbit 2) from speakers. Same with recording the audio, in the output file there is no more than 3 channels. I think it is because Windows has some kind of limitations and drivers give most 8 channels (so 4 stereo). Do you have any suggestions to solve this problem, including routing the audio to any daw?

Environment

  • SuperCollider version: 3.11
  • Operating system: Windows 10
  • Audio driver: Realtek ASIO
@tugrulsalci tugrulsalci added the bug Issues that relate to unexpected/unwanted behavior. Don't use for PRs. label Apr 25, 2020
@tugrulsalci tugrulsalci changed the title Multichannel Multichannel Audio Recording on Windows 10 Apr 25, 2020
@dyfer
Copy link
Member

dyfer commented Apr 25, 2020

@tugrulsalci could you provide more details? Are you setting appropriate number of channels in ServerOptions, i.e. command line to the server (not sure how that's done in TidalCycles)? And by "recording audio" do you mean recording the server output? Unfortunately I don't use TidalCycles so I can't help with its specific setup. But at the first glance doesn't seem like an issue with Windows inherently.

@tugrulsalci
Copy link
Author

tugrulsalci commented Apr 25, 2020

Sure, I don't know much about Supercollider but I will try to explain. Basically this is how my startup file looks like:

(
s.reboot { // server options are only updated on reboot
	// configure the sound server: here you could add hardware specific options
	// see http://doc.sccode.org/Classes/ServerOptions.html
	s.options.numBuffers = 1024 * 256; // increase this if you need to load more samples
	s.options.memSize = 8192 * 32; // increase this if you get "alloc failed" messages
	s.options.numWireBufs = 64; // increase this if you get "exceeded number of interconnect buffers" messages
	s.options.maxNodes = 1024 * 32; // increase this if you are getting drop outs and the message "too many nodes"
	s.options.numOutputBusChannels = 12; // set this to your hardware output channel size, if necessary
	s.options.numInputBusChannels = 2; // set this to your hardware output channel size, if necessary
	// boot the server and start SuperDirt
	s.waitForBoot {
		~dirt = SuperDirt(2, s); // two output channels, increase if you want to pan across more channels
		~dirt.loadSoundFiles;   // load samples (path containing a wildcard can be passed in)
		// for example: ~dirt.loadSoundFiles("/Users/myUserName/Dirt/samples/*");
		// s.sync; // optionally: wait for samples to be read
		~dirt.start(57120, [0,2,4,6,8,10]);
	(
			~d1 = ~dirt.orbits[0]; ~d2 = ~dirt.orbits[1]; ~d3 = ~dirt.orbits[2];
			~d4 = ~dirt.orbits[3]; ~d5 = ~dirt.orbits[4]; ~d6 = ~dirt.orbits[5];
			~d7 = ~dirt.orbits[6]; ~d8 = ~dirt.orbits[7]; ~d9 = ~dirt.orbits[8];
			~d10 = ~dirt.orbits[9]; ~d11 = ~dirt.orbits[10]; ~d12 = ~dirt.orbits[11];
		);
 s.meter;
 s.latency = 0.3;
   }
};
);

And I am recording with command > Server.default.record(numChannels:12);

@dyfer
Copy link
Member

dyfer commented Apr 25, 2020

I think I see what the problem is. You need to set server options before you call boot/reboot. Let me know if it works.
EDIT: I see s.waitForBoot. You should just remove s.reboot I think.

@tugrulsalci
Copy link
Author

Sever doesn't boot in this way... it just compiles the library

@dyfer
Copy link
Member

dyfer commented Apr 25, 2020

Sorry I wasn't clear. You need to remove the s.reboot call, but then also deal with the resulting function - either remove the function brackets or call .value on it.

BTW don't you also need to increase number of channels in ~dirt = SuperDirt(2, s); ?

This is the proper way to set the server options (i.e. before the boot). I did not change the SuperDirt parameter though.

(
// server options are only updated on reboot
// configure the sound server: here you could add hardware specific options
// see http://doc.sccode.org/Classes/ServerOptions.html
s.options.numBuffers = 1024 * 256; // increase this if you need to load more samples
s.options.memSize = 8192 * 32; // increase this if you get "alloc failed" messages
s.options.numWireBufs = 64; // increase this if you get "exceeded number of interconnect buffers" messages
s.options.maxNodes = 1024 * 32; // increase this if you are getting drop outs and the message "too many nodes"
s.options.numOutputBusChannels = 12; // set this to your hardware output channel size, if necessary
s.options.numInputBusChannels = 2; // set this to your hardware output channel size, if necessary
// boot the server and start SuperDirt
s.waitForBoot {
	~dirt = SuperDirt(2, s); // two output channels, increase if you want to pan across more channels
	~dirt.loadSoundFiles;   // load samples (path containing a wildcard can be passed in)
	// for example: ~dirt.loadSoundFiles("/Users/myUserName/Dirt/samples/*");
	// s.sync; // optionally: wait for samples to be read
	~dirt.start(57120, [0,2,4,6,8,10]);
	(
		~d1 = ~dirt.orbits[0]; ~d2 = ~dirt.orbits[1]; ~d3 = ~dirt.orbits[2];
		~d4 = ~dirt.orbits[3]; ~d5 = ~dirt.orbits[4]; ~d6 = ~dirt.orbits[5];
		~d7 = ~dirt.orbits[6]; ~d8 = ~dirt.orbits[7]; ~d9 = ~dirt.orbits[8];
		~d10 = ~dirt.orbits[9]; ~d11 = ~dirt.orbits[10]; ~d12 = ~dirt.orbits[11];
	);
	s.meter;
	s.latency = 0.3;
	
};
);

@jamshark70
Copy link
Contributor

Try removing s.reboot and the function braces:

s.options.numBuffers = 1024 * 256;
... all the other s.options lines...

s.waitForBoot {
    ... the rest of that block...
};

But I cannot hear any sound after third channel (after d3 or orbit 2) from speakers.

I believe this is expected. If your hardware interface allows 4 output channels, and you request 8 channels, then the first 4 will be connected to the hardware output channels but the other 4 will have nothing to connect to, hence silent.

If I'm understanding you right, you want:

  • SuperDirt to write its audio signals to a number of output channels you choose, for recording.

  • Then, the virtual output buses should be further mixed down for the number of physical speakers you have.

The usual approach to this case in SC is to use separately allocated buses for recording, and then mix down to the physical outputs.

If SuperDirt requires a 1:1 map between orbits and output buses (and I don't know if it does or doesn't), that strikes me as a limitation within SuperDirt. It really shouldn't be designed that way. It should be:

  • 1 orbit : 1 virtual bus (not hardware bus)
  • 1 hardware bus : mixdown of many orbits

It might be possible to work around by inserting mixing synths into the chain, but the order of synths will be very important and possibly fragile. (It wouldn't be fragile if SuperDirt manages it, but if that wasn't part of its design then it wouldn't.)

Same with recording the audio, in the output file there is no more than 3 channels.

That... I'm puzzled... and curious. Let me check it on my computer later.

@tugrulsalci
Copy link
Author

tugrulsalci commented Apr 25, 2020

The issue is that in macOS there is no such problem.
Just to make it clear that I am having audio information in all channels in Supercollider, I can see it on s.meter.
And these are the device options shown in the post window, as you can see the most has 6 outs:

Device options:
  - MME : Microsoft Sound Mapper - Input   (device #0 with 2 ins 0 outs)
  - MME : Microphone (Realtek Audio)   (device #1 with 2 ins 0 outs)
  - MME : Microsoft Sound Mapper - Output   (device #2 with 0 ins 2 outs)
  - MME : Speakers / Headphones (Realtek    (device #3 with 0 ins 6 outs)
  - Windows DirectSound : Primary Sound Capture Driver   (device #4 with 2 ins 0 outs)
  - Windows DirectSound : Microphone (Realtek Audio)   (device #5 with 2 ins 0 outs)
  - Windows DirectSound : Primary Sound Driver   (device #6 with 0 ins 2 outs)
  - Windows DirectSound : Speakers / Headphones (Realtek Audio)   (device #7 with 0 ins 6 outs)
  - ASIO : Realtek ASIO   (device #8 with 2 ins 2 outs)
  - Windows WASAPI : Speakers / Headphones (Realtek Audio)   (device #9 with 0 ins 2 outs)
  - Windows WASAPI : Microphone (Realtek Audio)   (device #10 with 2 ins 0 outs)
  - Windows WDM-KS : Microphone (Realtek HD Audio Mic input)   (device #11 with 2 ins 0 outs)
  - Windows WDM-KS : Speakers 1 (Realtek HD Audio output with SST)   (device #12 with 0 ins 2 outs)
  - Windows WDM-KS : Speakers 2 (Realtek HD Audio output with SST)   (device #13 with 0 ins 6 outs)
  - Windows WDM-KS : PC Speaker (Realtek HD Audio output with SST)   (device #14 with 2 ins 0 outs)
  - Windows WDM-KS : Stereo Mix (Realtek HD Audio Stereo input)   (device #15 with 2 ins 0 outs)

@dyfer @jamshark70 Thank you for your help but the result is the same, no sound after third orbit and same in the audio file output.

That... I'm puzzled... and curious. Let me check it on my computer later.

@jamshark70 Channels that I set exist in the file but there is no audio information after third channel*

BTW don't you also need to increase number of channels in ~dirt = SuperDirt(2, s); ?

@dyfer This stands for the stereo output. That's why orbits are arenged like this:

~dirt.start(57120, [0,2,4,6,8,10]);

@tugrulsalci tugrulsalci changed the title Multichannel Audio Recording on Windows 10 Multichannel Audio Recording/R on Windows 10 Apr 25, 2020
@tugrulsalci tugrulsalci changed the title Multichannel Audio Recording/R on Windows 10 Multichannel Audio Recording/Routing on Windows 10 Apr 25, 2020
@tugrulsalci
Copy link
Author

tugrulsalci commented Apr 26, 2020

@jamshark70 Actually in the last file with the last changes, I have the audio info in the all channels set. :) On the other hand, still there is no sound while playing live... Would it be possible to mix all the channels for the speaker output and still being able to record the multichannel audio?

@dyfer
Copy link
Member

dyfer commented Apr 26, 2020

@jamshark70 Actually in the last file with the last changes, I have the audio info in the all channels set. :) On the other hand, still there is no sound while playing live...

Multiple output channels are used to drive multiple physical outputs/multiple speakers. Your ASIO device has only 2 outputs so you won't hear sound sent to other outputs.

Would it be possible to mix all the channels for the speaker output and still being able to record the multichannel audio?

Yes, but you should send your signal to another (multichannel) Bus for recording, per @jamshark70's advice. You can use Recorder to record from any private Bus (not only from hardware inputs/outputs).

To hear all the channels in your stereo output, you should mix them, also per @jamshark70's suggestion. You can use a separate synth running at the end or after the main group for that

@dyfer dyfer removed the bug Issues that relate to unexpected/unwanted behavior. Don't use for PRs. label Apr 26, 2020
@dyfer
Copy link
Member

dyfer commented Apr 26, 2020

The issue is that in macOS there is no such problem.

I don't see a way for this to be the case but if you believe that's true, please provide a full reproducer.

@jamshark70
Copy link
Contributor

Yes, but you should send your signal to another (multichannel) Bus for recording, per @jamshark70's advice.

To hear all the channels in your stereo output, you should mix them, also per @jamshark70's suggestion.

Right.

To be more clear, I am guessing that the problem arises if SuperDirt assumes a 1:1 correspondence between channels that you hear in realtime and channels that you record. If I'm right about that, then SuperDirt's current design doesn't directly support the case of recording a different topology than is routed out to the speakers.

SuperCollider is capable of handling both, but it has to be built into the SC code that is running. (In my work, I have separate MixerChannels for individual layers, mixed down into some submixes for recording, and finally down to stereo for the speakers.) So it should be added as a SuperDirt feature: each orbit should have a dedicated internal bus for recording, mixed down to an equal or smaller number of hardware buses.

I'm not familiar with SuperDirt's design, so I don't know how hard it would be to implement. Ideally it wouldn't be hard at all.

Very likely this doesn't require any code changes in SC.

@dyfer
Copy link
Member

dyfer commented Apr 30, 2020

@tugrulsalci could you confirm whether you were able to solve this? As @jamshark70 pointed out this doesn't seem to be an issue with the SC code in itself.

@jamshark70
Copy link
Contributor

I've responded to the thread at the toplap forum where this is being discussed, asking whether SuperDirt has the required mixdown feature (only a couple hours ago, waiting for reply).

@mossheim
Copy link
Contributor

mossheim commented May 5, 2020

any follow up on this?

@jamshark70
Copy link
Contributor

I think we can close it. It's more of a SuperDirt issue IMO -- nobody from Tidal has confirmed that, but I think it needs to be demonstrated that it's really a SuperCollider problem before taking more action here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants