GameOfLife / Unit-Lib

The Unit Library is a system that provides high level abstractions on top of the SuperCollider language.
25 stars 6 forks source link

UX - plays a mono Udef as if it was multichannel of n channels by playin... #38

Closed miguel-negrao closed 10 years ago

miguel-negrao commented 10 years ago

UX - plays a mono Udef as if it was multichannel of n channels by playing n synths. Addresses #36.

UChain( UX(4, \sine), UX(4, \whiteNoise), UX(4, \lowPass), [\output, [\numChannels, 4] ]).gui

//nice syntax:
UChain( [4, \sine], [4, \whiteNoise], [4, \lowPass], [\output, [\numChannels, 4] ]).gui

//only works for mono in or mono out
Udef(\test,{
    UIn.ar(0,2)
})
UChain( UX(4, \test) )

//generates the correct compile string
UChain( [4, \sine], [4, \whiteNoise], [4, \lowPass], [\output, [\numChannels, 4] ]).asCompileString

//bundle generated:
UX(4, \sine).makeBundle(s)[0].dopostln

[ 9, u_sine, 1014, 1, 1, freq, 440, amp, 0.1, u_o_ar_0_lvl, 0, u_o_ar_0_bus, 0 ]
[ 9, u_sine, 1015, 1, 1, freq, 440, amp, 0.1, u_o_ar_0_lvl, 0, u_o_ar_0_bus, 1 ]
[ 9, u_sine, 1016, 1, 1, freq, 440, amp, 0.1, u_o_ar_0_lvl, 0, u_o_ar_0_bus, 2 ]
[ 9, u_sine, 1017, 1, 1, freq, 440, amp, 0.1, u_o_ar_0_lvl, 0, u_o_ar_0_bus, 3 ]

I gave it a go at implementing this. I deliberately choose to address only a specific case which is where there is a maximum one input and one output on the original Udef. This was as not to complicate matters regarding where those inputs and outputs should go. So we just take the bus number of the inputs and output and then use n-1 next consecutive buses. This is implemented by creating n synths and then passing the correct bus number to u_i_ar_0_bus and u_o_ar_0_bus. Everything else seems to work out of the box due to the fact that the synths get added to the synth array and so all of them will get the same set messages, etc. The main disadvantage of this approach is that when going to the IO panel what you see doesn't reflect what will happen since you don't see the additional connections happening. In any case, since I wanted to address the most simple solution, I didn't want the user to be able to change where things got routed for each channel (for that they can already duplicate the udef in the gui or by code). The mix level in the gui is still functional though and will change all channels. The main reason I didn't implement that is that for the current implementation I didn't have to touch the udef at all, while if I wanted to add the args u_o_ar_1_bus, etc in order to be able to change them in the gui then they would not be present in the specs array of the udef and I would be more work to get this working. I would say that this solution addresses the basic use case, which is "gee, I wished that lowpass could do 8 channels intead of just 1...".

I tried to test things but I might have missed something.

woutersnoei commented 10 years ago

Looks like a good start indeed. We could develop special methods for managing i/o I suppose at a later stage. And perhaps we could make a check in Udef if it would be compatible with UX (i.e. have one output only). I could imagine there to be an "ux" button in the gui for units that are ux-able, and then the +/- buttons would become add/remove channel buttons. One could then always de-ux a multichannel UX into separate units. I say merge :-)

woutersnoei commented 10 years ago

oh, wait, I think the UMap \makeSynth thing only needs to be called for the first synth, not for the rest. The UMap synth will only need to be created once, and the other synths will read from the same bus.

woutersnoei commented 10 years ago

ah, and one more thing; the loadbalancer may get confused over this: load count is added once at U:prepare, but removed multiple times in Udef:makeSynth (in the freeAction of each synth). Not sure how to fix that easily..

woutersnoei commented 10 years ago

and one last, more generic comment; generative units such as \sine are probably not very useful for UX; if you want 4 channels with the same sine wave you'd better use: UChain( \sine, [ \duplicateChannel, [ \numChannels: 4 ] ] ... )

miguel-negrao commented 10 years ago

Thanks for the feedback. I've tweaked it so that only one umap is created before all the synths and I added n*apxCPU at start so that the balance still makes sense. Testing the balance it returns to 0 after the uchain stops. Does this look good ? Yes, you're right about the \sine, but I just wanted to test if the mix of UMixOut was working.

woutersnoei commented 10 years ago

Ah yes, I guess it would work like that. I say merge :-)

miguel-negrao commented 10 years ago

merged