Sending values over bus

Hey everyone,

I have got the following problem:
I want to receive values in a Tdef via a Bus. The values come from a MidiController.

I tried the following:

~volumeBus = Bus.control(s, 1).set(0);

//this works
{Out.kr(~volumeBus, MouseX.kr(0, 1))}.play

But instead of MouseX.kr(), I want to send the value of the MidiController.
Do buses only work with kr. or ar.? How could I apply this to a variable?

//this doesnt work
{Out.kr(~volumeBus, ~incomingMidi)}.play

Thank you very much :slight_smile:

Hi!
What do you mean when you say it doesn’t work? When the “doesn’t work” situation happens, it’s more informative to post an example that clearly illustrates what you are doing, for example:

  • how you are getting this value from the buffer, so that it doesn’t fulfill your expectation?
  • what is inside the ~incomingMidi variable? How do you use it? How do you update it?

…so that everyone has more informations about what exactly you are doing :slight_smile:

Anyway, I guess the problem is that ~incomingMidi is treated a static value, while MouseX is a UGen. This means that Out.kr is continuously getting values from MouseX, because MouseX runs on the server. With variables in a SynthDef what happens is the following:

  1. You execute {Out.kr(~volumeBus, ~incomingMidi)}.play
  2. Your code is translated, so that your variables are “resolved”. In this case your translated function would like a bit like Out.kr(1, 0) (supposing that ~volumeBus has a bus number of 1, and that the value of ~incomingMidi at that time is 0).
  3. The synth is created and runs. There are no more references to your variables, only their value at the moment you created the Synth, so if you change ~incomingMidi, Out.kr will not know.

If ~incomingMidi comes from something like an OSCFunc, you could send it to the bus already there, using ~volumeBus.set() like you’re doing on your first line, without needing to go through the server.

Thank you for your response! Sorry for the lack of information!

This is what is happening I think.
I try to change ~incomingMidi message in a MidiDef. But I dont know how to constantly update it to the server.

~volumeBus = Bus.control(s, 1).set(0);

MIDIdef.cc(\GranulatorCC, {|val, ccNum|
	switch(ccNum,
		//so this works, but the volume gets updated only 
		//when the Tdef gets retriggered (.wait)
		19, {~volumeBus = Bus.control(s, 1).set(val.linlin(0, 127, 0,1));},
		
		//so I tried something like this, but it doesnt work
		17, { ~incomingMidi = val.linlin(0, 127, 0,1);}
		
		
	);
});

//this works even when the Tdef is not retriggerd
//so I can basically change the volume at any time, which would be 
//the ideal solution, just controling the volume with a MidiController instead of MouseX
{Out.kr(~volumeBus, MouseX.kr(0, 1))}.play

// This only works when I evaluate the function. What would be an approach to 
//update the varialbe to the Server everytime I change its value?
{Out.kr(~volumeBus, ~incomingMidi)}.play


(
Tdef(\Granulator, {|ev|
	loop{
		(
		    instrument: \playback,
			\vol: ~volumeBus.asMap,
			\out:0
		).play;

		((~setSize)/s.sampleRate.asInteger).wait;
	};
}).play;
)

Thank you :slight_smile:

19, {~volumeBus = Bus.control(s, 1).set(val.linlin(0, 127, 0,1));},

What this function is doing, is to reserve a new bus every time it receives a midi message, and set the midi value to that new bus. This is why the Tdef needs to be retriggered: because it is still on the old, abandoned Bus.
You don’t need to reserve a new Bus for each message, one is enough :slight_smile: And you reserve it correctly at the beginning of the code you sent.
So, in the MIDIdef, it is sufficient to do:

19, {~volumeBus.set(val.linlin(0, 127, 0,1));},

And there you have it, constantly updating values for the server to read on the Bus

1 Like