Modality-toolkit icon indicating copy to clipboard operation
Modality-toolkit copied to clipboard

MIDI output messages as integers

Open sensestage opened this issue 7 years ago • 9 comments

In some cases it is useful to set the raw value of a MIDI output element, as the bytes may have some clever encoding. This is for example the case with the Tascam US-2400 for the encoder ring display.

I will commit an IntegerClip class which can act as a spec to restrict a value to a certain integer range.

sensestage avatar May 25 '17 16:05 sensestage

The only issue is then for the GUI views, how to display this properly

sensestage avatar May 25 '17 16:05 sensestage

Can't this be done with a (Control)Spec? This seems to be similar to the String specs used in the OSC implementation, or?

LFSaw avatar May 26 '17 15:05 LFSaw

When you do byte-encoding you do not want to go through a floating point representation as is the case in a spec (which always converts to/from a 0 to 1)

I guess it could be an output collective where you combine all of the options into one byte and then send it.

I have to admit that I am not uptodate enough with the code base to know how much of the work on Collectives that I put in is still in the current version.

The ItemSpec comes close, but you'd want to pass in values as symbols/strings and then output integers.

sensestage avatar May 26 '17 15:05 sensestage

For reference, here is the function to set the encoder ring in meter mode:

(
~levelSpec = [0,15,\linear,1].asSpec;
~meterVal = { |level, showPeak=false, resetOverload = false, overload=false|
	level = ~levelSpec.map( level );
	level = level.asInteger & 0x0F;
	if ( showPeak ){
		level = level | 0x10;
	};
	if ( resetOverload ){
		level = level | 0x40; // reset the overload
		if ( overload ){
			level = level | 0x20; // there is an overload
		};
	};
	level.postln;
};
);

and here in the other mode:

(
~levelSpec = [0,15,\linear,1].asSpec;
~ringVal = { |level, mode=1, center=false|
	level = ~levelSpec.map( level );
	level = level.asInteger & 0x0F;
	if ( center ){
		level = level | 0x40;
	};
	switch( mode,
		// 1, { },    // data & 0x30 = 0
		// \dot, { }, // data & 0x30 = 0
		2, { level = level | 0x10; }, // data & 0x30 = 0x10
		\cutBoost, { level = level | 0x10; }, // data & 0x30 = 0x10
		3, { level = level | 0x10; }, // data & 0x30 = 0x20
		\spread, { level = level | 0x20; }, // data & 0x30 = 0x20
		4, {
			level = level | 0x10;
			level = level | 0x20;
		}, // data & 0x30 = 0x20
		\width, {
			level = level | 0x10;
			level = level | 0x20;
		} // data & 0x30 = 0x20
	);
	level.postln;
};
);

Another common case seems to be the LED [ \off, \blink, \on] case.

sensestage avatar May 26 '17 15:05 sensestage

@sensestage:

I have to admit that I am not uptodate enough with the code base to know how much of the work on Collectives that I put in is still in the current version.

@adcxyz , can you comment?

LFSaw avatar May 26 '17 15:05 LFSaw

AFAIR, all the collective stuff is still there and works.

adcxyz avatar Jun 01 '17 16:06 adcxyz

Speaking of MKtlElementCollective, it is missing documentation... And I have no diea whatsoever what it is intended for.

LFSaw avatar Jun 01 '17 17:06 LFSaw

This seems similar to the CinematixWheel #117, hardware with indiosyncratic ways of compressing data into (MIDI) messages. Like there, I think it good to provide a specific solution for the case and document its logic; like there also, I don't understand what the general case to solve is.

For a no-spec MKtlElement, one could use MAbstractElement; for mapped/unmapped integer values, one could write a ControlSpec subclass with a flag whether to do .asInteger on the output or not. collectives for distributing incoming values seems fine - one can also just provide a full example that does the conversion, and tell users to attach that to the MKtl concerned. 2c a

adcxyz avatar Jul 02 '17 08:07 adcxyz

@sensestage ping

adcxyz avatar Jul 25 '17 07:07 adcxyz