Capture MIDI input

Work in progress

Capturing MIDI input opens the way to "learn­ing" from the per­for­mance of a musi­cian or anoth­er MIDI device. The first step is to use the cap­tured incom­ing NoteOn/Noteoff events, and option­al­ly ControlChange and PitchBend events, to build a poly­met­ric struc­ture that repro­duces the stream.

The dif­fi­cul­ty of this task lies in the design of the most sig­nif­i­cant poly­met­ric struc­ture — for which AI tools may prove help­ful in the future. Proper time quan­ti­za­tion is also need­ed to avoid over­ly com­pli­cat­ed results.

We've made it pos­si­ble to cap­ture MIDI events while oth­er events are play­ing. For exam­ple, the out­put stream of events can pro­vide a frame­work for the tim­ing of the com­pos­ite per­for­mance. Consider, for instance, the tem­po set by a bass play­er in a jazz improvisation.

The _capture() command

A sin­gle com­mand is used to enable/disable a cap­ture: _capture(x), where x (in the range 1…127) is an iden­ti­fi­er of the 'source'. This para­me­ter will be used lat­er to han­dle dif­fer­ent parts of the stream in dif­fer­ent ways.

_capture(0) is the default set­ting: input events are not recorded.

The cap­tured events and the events per­formed on them are stored in a 'cap­ture' file in the temp_bolprocessor fold­er. This file will lat­er be processed by the interface.

(Examples are found in the project "-da.tryCapture".

The first step to use _capture() is to set up the MIDI input and more specif­i­cal­ly its fil­ter. It should at least treat NoteOn and NoteOff events. ControlChange and PitchBend mes­sages can also be captured.

If the pass option is set (see pic­ture), incom­ing events will also be heard on the out­put MIDI device. This is use­ful if the input device is a silent device.

It is pos­si­ble to cre­ate sev­er­al inputs con­nect­ed to sev­er­al sources of MIDI events, each one with its own fil­ter settings.

Another impor­tant detail is the quan­ti­za­tion set­ting. If we want to con­struct poly­met­ric struc­tures, it may be impor­tant to set the data to the near­est mul­ti­ple of a fixed dura­tion, typ­i­cal­ly 100 mil­lisec­onds. This can be set in the set­tings file "-se.tryCapture".

Simple example

Let us take a look at a very sim­ple exam­ple of a cap­ture on top of a performance.

C4 _D4 _capture(104) E4 F4 G4 _capture(0) A4 B4

The machine will play the sequence of notes C4 D4 E4 F4 G4 A4 B4. It will lis­ten to the input while play­ing E4 F4 G4. It will record both the sequence E4 F4 G4 and the notes received from a source tagged "104".

Suppose that the sequence G3 F3 D3 was played on top of E4 F4 G4. The cap­ture file might look like this:

Note that all dates are approx­i­mat­ed to mul­ti­ples of 100 mil­lisec­onds. For exam­ple, the NoteOff of input note G3 falls exact­ly on the date 3000 ms, which is the NoteOff of the played note E4.

The record­ing of input and played notes starts at note E4 and ends at note G4, as spec­i­fied by _capture(104) and _capture(0).

An accept­able approx­i­ma­tion of this sequence would be the poly­met­ric expression:

C4 D4 {E4 F4 G4, - - G3 - F3 - D3 - -} A4 B4

Approximations will be cre­at­ed from the cap­ture files at a lat­er stage.

Combining 'wait' instructions

Try:

_script(wait for C3 channel 1) C4 D4 _capture(104) E4 F4 G4 _script(wait for D3 channel 1) _capture(0) A4 B4

The record­ing takes place dur­ing the exe­cu­tion of E4 F4 G4 and dur­ing the unlim­it­ed wait­ing time for note D3. This allows events to be record­ed even when no events are being played.

The C3 and D3 notes have been used for ease of access on a sim­ple key­board. The dates in the cap­ture file are not incre­ment­ed by the wait times.

The fol­low­ing is a set­up for record­ing an unlim­it­ed sequence of events while no event is being played. Note C0 will not be heard as it has a veloc­i­ty of zero. Recording ends when the STOP or PANIC but­ton is clicked.

_capture(65) _vel(0) C0 _script(wait forever) C0

Interpreting the record­ed input as a poly­met­ric struc­ture will be made more com­plex by the fact that no rhyth­mic ref­er­ence has been provided.

Microtonal corrections

In the fol­low­ing exam­ple, both input and out­put receive micro­ton­al cor­rec­tions of the just into­na­tion scale.

_scale(just intonation,0) C4 D4 _capture(104) E4 F4 G4 A4 _capture(0) B4

Below is a cap­ture file obtained by enter­ing G3 F3 D3 over the sequence E4 F4 G4 A4.

The out­put events (source 0) are played on MIDI chan­nel 2, and the input events (source 104) on MIDI chan­nel 1. More chan­nels will be used if out­put notes have an over­lap — see the page MIDI micro­tonal­i­ty. In this way, pitch­bend com­mands and the notes they address are dis­trib­uted across dif­fer­ent channels.

More pitchbend

In the fol­low­ing exam­ple, a pitch­bend cor­rec­tion of +100 cents is applied to the entire piece. It does mod­i­fy out­put events, but it has no effect on input events.

_pitchrange(200) _pitchbend(+100) _scale(just intonation,0) C4 D4 _capture(104) E4 F4 G4 A4 _capture(0) B4

Again, after play­ing G3 F3 D3 over the sequence E4 F4 G4 A4:

Pitchbend cor­rec­tions applied to the input (source 104) are only those induced by the micro­ton­al scale. Pitchbend cor­rec­tions applied to the out­put (source 0) are the com­bi­na­tion of micro­ton­al adjust­ments (see pre­vi­ous exam­ple) and the +100 cents of the pitch­bend command.

Leave a Reply

Your email address will not be published. Required fields are marked *