CVCenterKeyboard:
Filter:
Classes (extension) | Conductor > CVCenter | External Control > MIDI

CVCenterKeyboard : Object
ExtensionExtension

A MIDI keyboard implementation for CVCenter

Description

A CVCenterKeyboard consists of a collection of SynthDefs and provides a convenient way to play them on a MIDI keyboard.

CVCenterKeyboard lets you create a MIDI keyboard layout instantly from either a SynthDef whose instances free themselves (e.g. for percussive instruments having an envelop defined in an EnvGen that has the parameter doneAction set to 2 or Done.freeSelf) or a SynthDef that provides a \gate key, meaning that a Synth that has been instanced upon receiving a note-on message gets finished when it gets a not-off message from an external MIDI keyboard. That allows for playing sustained notes that can be controlled through asr or adsr envelopes. A SynthDef with a "gated" envelope should answer true on executing the following line:

WARNING: If the Synths that get created from your SynthDefs do not free themselves or get freed upon MIDI NoteOff messages they will clog the server, eventually making it unresponsive!

Beyond the that you may add an arbitrary number of other SynthDefs. You may switch between these SynthDefs or play more than one at a time by calling -setSynthDef. Playing the keyboard should immediately play generated nodes using the selected SynthDefs.

Setting up the keyboard basically involves two steps: First instancing a keyboard (through *new or *newSynthDef) and then setting up the keyboard for a given SynthDef through -setUpControls (will boot the Server).

You can assign four arbitray controls from your SynthDef to the following standard parameters:

outControl
the arg that sets the output bus of the Synth
keyboardControl
whatever melody you want to play with your keyboard, often expressed in a parameter \freq (Hertz).
NOTE: A MIDI keyboard by default will return MIDI notes (0-127). These will be converted to frequencies in Hertz internally.

velocControl
whatever you want to control through keyboard velocity
bendControl
whatever you want to control through the pitch bend wheel (the internal control will automatically assigned a spec ControlSpec(0.midicps.neg, 0.midicps, \lin, 0, 0, " hz"))
NOTE: To set up a CVCenterKeyboard instance with a SynthDef you will either have to create a new CVCenterKeyboard by calling CVCenterKeyboard.newSynthDef (adding the SynthDef as an argument) and then call -setUpControls or, if the CVCenterKeyboard instance already exists, first add your SynthDef by calling -addSynthDef and then call -setUpControls.

All other controls you may have defined in your SynthDef will automatically be picked up by the setup process and get assigned appropriate widgets automatically.

NOTE: All Synths generated from your SynthDefs will play in one Group (or, if supernova is used as audio backend, ParGroup). That means arguments with the same name across different SynthDefs will always get set to the same value. That may be desired e.g. for the frequency you're playing over the keyboard but probably not for others that e.g. get set through a knob or a slider. So, take special care for duplicate argument names in your SynthDefs!

Additionally an output proxy - a NodeProxy or an Ndef - can be added through -addOutProxy which allows you to build an effects chain and to do other kinds of NodeProxy trickery.

Class Methods

CVCenterKeyboard.new(keyboardDefName: 'keyboard', srcID, chan, addRecorder: true, touchOSCAddr)

Instanciate a new keyboard under keyboardName. The keyboard will be accessible under CVCenterKeyboard.all[keyboardName]

Arguments:

keyboardDefName

a String or Symbol, denoting the name of the new keyboard

srcID

Optional - an Integer corresponding to the unique ID of the MIDI device. If omitted the keyboard will be usable on any currently connected MIDI keyboard. To find out the unique numeric ID of your MIDI device you could use thefollowing code:

(See also: Using MIDI: MIDIFunc and MIDIdef: Filtering based on device or message data)

chan

Optional - an Integer denoting the MIDI channel the keyboard should use. If omitted the keyboard can be played on any MIDI channel (See also: Using MIDI: MIDIFunc and MIDIdef: Filtering based on device or message data)

addRecorder

Optional - this argument will be set to true by default and adds a sampler that records all keystrokes on the keyboard upon calling -record. Calling -record again will stop recording and the just recorded sequence will immediately start playing. See CVCenterKeyboardRecorder for more information on the recording mechanism and the structure of the recorded sequences.

touchOSCAddr

Optional - a NetAddr instance, refering to an installation of a TouchOSC app on a mobile phone or tablet computer. The device must be in the same network as the computer. The IP address must be the device' IP address, the port is the "incoming" port as set in TouchOSC's OSC setup. Included with the distribution of this class (library) you should find a TouchOSC layout that can be edited in the TouchOSCEditor - download at https://hexler.net/touchosc-mk1#resources . The layout is built for a resolution of 800 x 1280 pixels, so you might have to adapt it to the resolution of your device.

NOTE: You might want to use a different OSC app for control, using different OSC command names. Though the class is named CVCenterKeyboardTouchOSC it is not necessarily bound to the TouchOSC app. You should be able to set your own command names, either in the class or one of its instances. See CVCenterKeyboardTouchOSC: Predefined OSC commands or CVCenterKeyboardTouchOSC: Predefined OSC commands in instances

CVCenterKeyboard.newSynthDef(synthDefName, keyboardDefName: 'keyboard', srcID, chan, addRecorder: true, touchOSCAddr)

Instantiate a new CVCenterKeyboard holding the SynthDef denoted by synthDefName. The SynthDef must have beem compiled in advance.

Arguments:

synthDefName

A Symbol or a String denoting the SynthDef that should be added to the keyboard. Note that the SynthDef must have a gated envelope (i.e. executing SynthDescLib.at(synthDefName).hasGate must return true. synthDefName must be given as Symbol to return the expected result. See EnvGen for an explanation of how to create an envelope with a gate).

keyboardDefName

a String or Symbol, denoting the name of the new keyboard

srcID

Optional - an Integer corresponding to the unique ID of the MIDI device. If omitted the keyboard will be usable on any currently connected MIDI keyboard. See *new for how to determine the unique ID of your MIDI device. (See also: Using MIDI: MIDIFunc and MIDIdef: Filtering based on device or message data)

chan

Optional - an Integer denoting the MIDI channel the keyboard should use. If omitted the keyboard can be played on any MIDI channel (See also: Using MIDI: MIDIFunc and MIDIdef: Filtering based on device or message data)

addRecorder

Optional - this argument will be set to true by default and adds a sampler that records all keystrokes on the keyboard upon calling -record. Calling -record again will stop recording and the just recorded sequence will immediately start playing. See CVCenterKeyboardRecorder for more information on the recording mechanism and the structure of the recorded sequences.

touchOSCAddr

Optional - a NetAddr instance, refering to an installation of a TouchOSC app on a mobile phone or tablet computer. For detailed description see *new argument touchOSC.

CVCenterKeyboard.at(keyboardDefName)

A simple convenience method, same as CVCenterKeyboard.all[keyboardDefName] except for the fact that keyboardDefName can be given as String as well (will be converted to a Symbol internally).

Arguments:

keyboardDefName

A String or Symbol denoting the name of the CVCenterKeyboard instance.

Returns:

The CVCenterKeyboard instance under the given name if it exists or nil.

CVCenterKeyboard.all

Returns:

an Event, containing all CVCenterKeyboard instances.

Inherited class methods

Instance Methods

.addSynthDef(synthDefName)

Add a new SynthDef to an existing CVCenterKeyboard instance. The SynthDef must already have been compiled and contain a gated envelope.

Arguments:

synthDefName

A String or an Symbol, denoting the name of the SynthDef.

.removeSynthDef(synthDefName)

Remove a SynthDef to an existing CVCenterKeyboard instance.

Arguments:

synthDefName

A String or an Symbol, denoting the name of the SynthDef.

.setUpControls(synthDefName, prefix, pitchControl: 'freq', velocControl: 'veloc', bendControl: 'bend', outControl: 'out', tuning, theServer, outbus: 0, deactivateDefaultWidgetActions: true, tab, setSynthDef: false)

Whenever a new SynthDef is added, either by creating a new instance by calling *newSynthDef or adding a SynthDef with -addSynthDef, the CVCenterKeyboard instance must be set up for the new SynthDef. This will configure outControl, keyboardControl, velocControl and bendControl as well as it will create CVWidgets for all other controls in the SynthDef. It should be possible to call this method repeatedly, so you can update an existing SynthDef while it's already being used.

Arguments:

synthDefName

The SynthDef's name, given as Symbol or String

prefix

An optional Symbol or String for CVCenter, to make sure the resulting widgets get a unique name.

pitchControl

A Symbol or String referencing the keyboard key, incoming note. Default: \freq.

velocControl

A Symbol or String referencing velocity (the physical pressure on a keyboard key) coming with the note. Default: \veloc.

bendControl

A Symbol or String referencing the control to be set by the pitch bend wheel. Default: \bend.

outControl

A Symbol or String referencing the output bus. Default: \out.

tuning

An ControlSpec. If set the given SynthDef may be 'tuned' using an extra CVWidget. The given ControlSpec determines the range of possible tuning.

theServer

Optional - the Server to run the Synths on produced with every keystroke.

outbus

Optional - an Integer denoting a default output bus (can be set in the SynthDef beforehand as well).

deactivateDefaultWidgetActions

When CVWidgets are created from a running Classes/Synth these widgets will be added default actions to set the regarding controls in the Synth, which is not desirable in this case. However, actions will just get deactivated and can get re-activated at any time. Default: true.

tab

Optional - a Symbol or String denoting the tab in which the CVWidgets for the Synth instances will appear. If none is given the tab name will default the the SynthDef's name.

setSynthDef

A Boolean. If set to true the CVCenterKeyboard instance can be played using the given SynthDef immediately (otherwise you will have to call -setSynthDef explicitly). Default: false.

Discussion:

.setSynthDef( ... synthDefName)

This method may be called implicitly for every new SynthDef in -setUpControls by adding an argument setSynthDef set to true or it may be called explicitly to switch between currently stored SynthDefs or to play more than one SynthDef at the same time within the CVCenterKeyboard instance.

Arguments:

... synthDefName

One or more Strings or a Symbols, denoting the SynthDef(s) to be selected. If more than one SynthDef is given the keys triggering one of the SynthDefs will be equally distributed over the -keysBlockSize. I.e. by default the -keysBlockSize will extend over 24 keys on the keyboard (two octaves). The keys triggering one of the given SynthDefs will (more or less) be equally distributed over the given block (the keysBlockSize may not be divisible by the number of SynthDefs and therefore the number of keys for each SynthDef may not be exactly equal). Note that the order of arguments matters: The first argument (SynthDef) will take the lowest keys, the next one the keys to the right of the first one and the last one the highest keys in the block.

Discussion:

Using multiple SynthDefs on one keyboard

As you may already have recognized you can use more than one SynthDef on one physical keyboard. When doing so by calling -setSynthDef with more than one SynthDef the keys are being equally distributed over a predefined block of keys (by default 24 keys or two octaves). The blocks will repeat over the full range of 128 MIDI notes, beginning at MIDI note 0. Here are some schematic examples using two SynthDefs on a three-octaves keyboard1 :

.keysBlockSize

.keysBlockSize = size

This method lets you either read or set the number of keys over which two or more SynthDefs are being distributed that have been set by calling -setSynthDef. By default it will be 24 (two octaves). You can set a new value at any time and the CVCenterKeyboard instance should pick up the new value immediately.

Returns:

.keysDistribution

.keysDistribution = ratios

By default keys for different SynthDefs in a CVCenterKeyboard instance that has been set to more than one SynthDef by calling -setSynthDef will be distributed (more or less) equally over the given -keysBlockSize. This method, however, allows you to set the number of keys for the SynthDefs unequally. If you e.g. have two SynthDefs distributed over 24 keys each of them will occupy twelve keys within that -keysBlockSize. You can change that by executing

~kb.keysDistribution_([8, 16])

to eight keys for the first SynthDef and 16 keys for the second SynthDef. If the given array sums to the -keysBlockSize it should be guaranteed that the number of keys playing one of the SynthDefs is exactly equal to the number given in the array ratios. If you change the -keysBlockSize later, however, the ratio of the keys should be kept. I.e. executing the following to line will first change the -keysBlockSize and subsequently change the number of keys for the first SynthDef to 4 and the number of keys for the second SynthDef to 8.

If ratios sums up to an even number and -keysBlockSize is set to an odd number, the ratio of the number of keys will be approximated.

Returns:

an Array of Integers

Other utility methods

.clear( ... synthDefName)

Clear one or more SynthDef(s) from a CVCenterKeyboard instance but don't remove it from the keyboard. This is used internally by -setSynthDef before switching to a new SynthDef. You will usually not call this method directly.

Arguments:

... synthDefName

One or more Strings or a Symbols, denoting the SynthDef(s) to be cleared.

.free

Free the CVCenterKeyboard instance. You will not be able to use the CVCenterKeyboard instance any longer after calling this method.

.freeHangingNodes

Frees all currently playing Nodes (Synth instances) on the Server belonging to the CVCenterKeyboard instance. This can be useful if, for some reason, a note "hangs" after releasing a key on the keyboard which could happen e.g. if the server is under heavy load. A CVCenterKeyboard instance will create all its Synths in a dedicated Group (respectively ParGroup if supernova is used as audio engine) which allows control the playing nodes via the group's interface.

.addTouchOSC(addr)

Assosciate an instance of CVCenterKeyboardTouchOSC which allows the CVCenterKeyboard instance and an assigned CVCenterKeyboardRecorder instance (if it exists. See also: -addRecorder) to be controlled via pre-defined OSC commands comming and gong to TouchOSC or a different OSC control app installed on some external device within the current network. The CVCenterKeyboardTouchOSC instance can also be created by passing a NetAddr in the argument touchOSC when calling *new or *newSynthDef. The CVCenterKeyboardTouchOSC instance will be accessible by calling -touchOSC.

Arguments:

addr

A class NetAddr

MIDI related Instance variables

.on

The default noteOn function, added when creating a new CVCenterKeyboard instance. By default the function will only hold some debug code that gets executed when -debug is set to true.

.off

The default noteOff function, added when creating a new CVCenterKeyboard instance. By default the function will only hold some debug code that gets executed when -debug is set to true.

.bend

The default bend function, added when creating a new CVCenterKeyboard instance. By default the function will only hold some debug code that gets executed when -debug is set to true.

MIDIFunc storage for added SynthDefs

The following three variables all implement an Event, holding the individual noteOn, noteOff and bend Functions at a key identical to the corresponding SynthDef. When calling MIDIFunc instance when calling setSynthDef(\mySynthDef) the corresponding Function in the Event will be added to the CVCenterKeyboard instance's default MIDIFunc instance (-on, -off or -bend).

.onFuncs

The functions to be executed for a noteOn. To each of these functions the arguments veloc (velocity), num (the MIDI value for the key played on the keyboard), chan (the MIDI channel, if defined) and src (the MIDI device' unique ID, if defined) will be passed. If -debug has been set to true the following output will be posted:

.offFuncs

The functions to be executed for a noteOff. To each of these functions the arguments veloc (velocity), num (the MIDI value for the key played on the keyboard), chan (the MIDI channel, if defined) and src (the MIDI device' unique ID, if defined) will be passed. If -debug has been set to true the following output will be posted:

.bendFuncs

The functions to be executed for a bend (when moving the the bend wheel). To each of these functions the arguments bendVal (the value coming from the bend wheel), chan (the MIDI channel, if defined) and src (the MIDI device' unique ID, if defined) will be passed. If -debug has been set to true the following output will be posted:

Instance variables

.debug

.debug = value

Acttivate or deactivate debugging. If set to true various output from noteOn, noteOff and bend events will be posted.

.currentSynthDef

Returns:

The name(s) of the currently used SynthDef(s) as an Array of Symbols.

.synthParams

Returns:

An Event holding all ControlNames of all currently stored SynthDefs within a CVCenterKeyboard instance.

.synthDefNames

Returns:

A List, filled with the names of the SynthDefs currently stored with the CVCenterKeyboard instance.

.keyboardDefName

Returns:

A Symbol representing the name of the CVCenterKeyboard instance. The name can will be set in *new or *newSynthDef. If no name has been given it will default to \keyboard.

.group

Returns:

The Group or ParGroup in which all Synths generated by the CVCenterKeyboard instance will be playing.

.namesCVs

Returns:

An Event, holding a List with the CVWidget instance names, the ControlNames and the CVs of all SynthDefs currently stored with the CVCenterKeyboard instance. Usually this will not be of any use for the user but it is needed for sampling keyboard sequences. Hence, this variable must be public and can be used for introspection.

.bendSpec

.bendSpec = value

Set or get the ControlSpec for the pitch bend wheel. By default:

.pairs

Returns:

An Array containing all controls and CV instances of the currently used SynthDef (see: -currentSynthDef) that appear in CVCenter.

.valuePairs

Returns:

An Array containing all controls and their current values of the SynthDef (see: -currentSynthDef) that appear in CVCenter.

.out

.out = value

Set or get the out Bus of the currently used SynthDef.

Returns:

An Integer.

.server

Returns:

The Server used by the CVCenterKeyboard instance.

.touchOSC

Returns:

The CVCenterKeyboardTouchOSC instance associated with the CVCenterKeyboard instance if it exists.

Adding an effects chain

Building an effects chain is accomplished by adding a NodeProxy or an Ndef catching the output of the Synths played with the keyboard. These can then be filtered by using NodeProxy roles. Only adding the NodeProxy or Ndef by calling -addOutProxy will have no audible effect - the keyboard should just play as before adding the proxy.

.addOutProxy(numChannels: 2, useNdef: false, transbus, outbus)

Add a NodeProxy or an Ndef, catching the audio output of the CVCenterKeyboard instance.

Arguments:

numChannels

An Integer representing the number of output channels. Default: 2.

useNdef

If set to true the proxy will be created as Ndef. By default the proxy will be a NodeProxy.

transbus

Optional - an Integer represeting a Bus allowing the user to isolate effects and filters. This is handled by setting output bus of the CVCenterKeyboard instance to this bus. Ideally one will use a private bus, e.g: s.options.firstPrivateBus.

outbus

Optional - an Integer represeting the Bus on which the filtered sound of the CVCenterKeyboard shall play. By default this will be the out bus of the CVCenterKeyboard instance.

.removeOutProxy(outbus)

Remove the NodeProxy or Ndef added by -addOutProxy.

Arguments:

outbus

If the argument transbus in -addOutProxy has been given one needs to re-set the out bus of the CVCenterKeyboard instance.

.outProxy

Returns:

The proxy created by calling -addOutProxy.

Recording sequences

.addRecorder

To be able to record keystrokes on the keyboard a CVCenterKeyboardRecorder has to be assigned. By default this is already done when calling *new or *newSynthDef if the argument addRecorder hasn't explicitly been set to false (given that CVCenterKeyboardRecorder is installed, which should be the case as its part of the CVCenterKeyboard library).

.record(onOff)

A convenience method, calling CVCenterKeyboardRecorder: -record. Start or stop recording keyboard sequences. The CVCenterKeyboardRecorder instance should keep track of its state internally (is currently it recording or not), so, the argument onOff should be optional. However, it might be convenient to tell the recorder explicitly to start or stop in some situations.

Arguments:

onOff

Optional - by default the CVCenterKeyboardRecorder should remember its internal state (is it currently sampling or not). The parameter allows you to set the state explicitly.

.recorder

Returns:

The CVCenterKeyboardRecorder instance, giving access to all methods of the CVCenterKeyboardRecorder instance.

Setting synth controls through busses

Controls within Synth instances created when playing the keyboard may also be controlled through busses.

.mapBus(ctrlname, bus)

Map a Bus to a Synth control. The bus can be control or audio rate.

Arguments:

ctrlname

A Symbol referencing the control in the Synth that shall be set by the Bus.

bus

The audio or control rate Bus that will set the control in the Synth instance.

.unmapBus(ctrlname)

The opposite to -mapBus - delegate control over the given ControlName back to manual control by the user.

Arguments:

ctrlname

A Symbol referencing the ControlName whose control should be delegated to the user again.

.mappedBusses

Returns:

An Event holding all currently mapped busses. The keys will be ControlNames that get set by the bus(ses) referenced by the assigned bus indexes.

Inherited instance methods