Fl classes
fl_classes
This module contains definitions for FL Studio's built-in types, which can be used to assist with type hinting in your project.
NOTE: This module is not included in FL Studio's runtime, and should be
included by initializing fl_typing
as a submodule for your project.
https://github.com/MiguelGuthridge/fl_typing
# With fl_typing enabled so that the typing module works correctly
from fl_classes import FlMidiMsg
def OnMidiIn(event: FlMidiMsg) -> None:
...
FlMidiMsg
A shadow of FL Studio's FlMidiMsg
object. Note that although creating
these is possible, it should be avoided during runtime as FL Studio's API
won't accept it as an argument for any of its functions. It can be used
within a testing environment, however.
Note that two sub-types are also included, which allow for type narrowing by separating standard MIDI events and Sysex MIDI events. These will work for FL Studio's types as well.
-
isMidiMsgStandard()
-
isMidiMsgSysex()
Basic type checking is performed when accessing properties of FlMidiMsg
objects, to ensure that incorrect properties aren't accessed (for example
accessing data1
for a sysex event). These checks won't be performed
during runtime for your script, but can help to add more certainty to your
tests.
controlNum: int
property
writable
The control number for a control change event.
This is a shadow of the data1
property. Modifications to this will
affect all data1
derived properties.
Note that this property is inaccessible for sysex events.
controlVal: int
property
writable
The value of a control change event.
This is a shadow of the data2
property. Modifications to this will
affect all data2
derived properties
Note that this property is inaccessible for sysex events.
data1: int
property
writable
The first data byte of a MIDI message.
This is used to determine the control number for CC events, the note number for note events, and various other values.
Note that this property is inaccessible for sysex events.
data2: int
property
writable
The second data byte of a MIDI message.
This is used to determine the value for CC events, the velocity for note events, and various other values.
Note that this property is inaccessible for sysex events.
handled: bool
property
writable
Whether the event is considered to be handled by FL Studio.
If this is set to True
, the event will stop propagating after this
particular callback returns.
You script should set it when an event is processed successfully.
inEv: int
property
writable
MIDI inEv
HELP WANTED:
- What is this?
isIncrement: bool
property
writable
Whether the event should be an increment event
If the script sets this to True
, FL Studio will consider it to be a
relative event, meaning that it will change values relative to that
value, rather than setting them absolutely.
HELP WANTED:
- Notes on the particular cases where this happens.
midiChan: int
property
writable
MIDI chan
HELP WANTED:
-
What is this?
-
No, it's not a channel. It always seems to be zero, regardless of the channel of the event.
midiChanEx: int
property
writable
MIDI chanEx
HELP WANTED:
- What is this?
midiId: int
property
writable
MIDI ID
HELP WANTED:
- What is this?
note: int
property
writable
The note number of a MIDI note on/off message.
This is a shadow of the data1
property. Modifications to this will
affect all data1
derived properties.
Note that this property is inaccessible for sysex events.
outEv: int
property
writable
MIDI outEv
HELP WANTED:
- What is this?
pitchBend: int
property
MIDI pitch bend value
HELP WANTED:
- This only ever seems to equal
1
. How should it be used?
Note that this property is read-only.
pmeFlags: int
property
Flags used by FL Studio to indicate the permissions of the script in the current environment.
These can be used to ensure safety while running the script. If a
script ever attempts to execute unsafe behavior, a TypeError
will be
raised.
TypeError("Operation unsafe at current time")
Flag analysis
The flags can be analyzed by performing bitwise operations to determine the current permissions of the script.
-
0b000010
(PME_System
) System operations allowed (play/pause, etc). -
0b000100
(PME_System_Safe
) Critical operations allowed (add markers, etc). Things that can't be done when a modal dialog is showing. -
0b001000
(PME_PreviewNote
) Note events will trigger a preview. -
0x010000
(PME_FromHost
) FL Studio is being hosted as a VSTi (meaning it's probably a bad idea to do anything meaningful as it could interfere with the behavior of other DAWs). In my testing, using MIDI scripts in the FL Studio VST causes a crash anyway, so I suppose it isn't that important either way. -
0x100000
This event was triggered by a MIDI event.
Alternate to flag analysis
It could be considered to be more Pythonic, as well as much simpler to catch this exception rather than checking the flags. The following is a simple decorator that will catch the exception. This does come with the risk that any unsafe behavior that FL Studio misses will cause a system lock-up in FL Studio.
def catchUnsafeOperation(func):
'''
Decorator to prevent exceptions due to unsafe operations
### Args:
* `func` (`Callable`): function to decorate
'''
def wrapper(*args, **kwargs):
try:
func(*args, **kwargs)
except TypeError as e:
if e.args != ("Operation unsafe at current time",):
raise e
return wrapper
port: int
property
The port of the message
HELP WANTED:
- This value always appears to be zero. How should it be used?
Note that this property is read-only.
pressure: int
property
writable
The pressure value for a channel after-touch event.
This is a shadow of the data1
property. Modifications to this will
affect all data1
derived properties.
Note that this property is inaccessible for sysex events.
progNum: int
property
writable
The instrument number for a program change event.
This is a shadow of the data1
property. Modifications to this will
affect all data1
derived properties.
Note that this property is inaccessible for sysex events.
res: float
property
writable
MIDI res
HELP WANTED:
- How is this used?
status: int
property
writable
The status byte of the event
This can be used to determine the type of MIDI event using the upper nibble, and the channel of the event using the lower nibble.
e_type = event.status & 0xF0
channel = event.status & 0xF
Note that for sysex messages, this property is 0xF0
. Other standard
event properties are inaccessible.
Event types
-
0x8
Note off (data1
is note number,data2
is release value) -
0x9
Note on (data1
is note number,data2
is velocity) -
0xA
Note after-touch (data1
is note number,data2
is pressure value) -
0xB
Control change (CC,data1
is control number as per your controller's documentation,data2
is value) -
0xC
Program change (used to assign instrument selection,data1
is instrument number) -
0xD
Channel after-touch (data1
is value,data2
is unused) -
0xE
Pitch bend (data1
anddata2
are value, as per the formuladata1 + (data2 << 7)
, yielding a range of0
-16384
)
sysex: bytes
property
writable
Data for a sysex event
Contains the full event data from sysex events.
This property is inaccessible for standard events.
timestamp: int
property
The timestamp of the event
HELP WANTED:
- This seems to only ever be zero. I can't determine what it is for. If you know how it is used, create a pull request with details.
This value is read-only.
velocity: int
property
writable
The velocity of a MIDI note on/off message.
This is a shadow of the data2
property. Modifications to this will
affect all data2
derived properties
Note that this property is inaccessible for sysex events.
__init__(status_sysex, data1=None, data2=None, pmeFlags=46)
Create an FlMidiMsg
object.
Note that this object will be incompatible with FL Studio's API, and so cannot be used as a parameter for any API functions during runtime.
Args:
-
status_sysex
(int | list[int] | bytes
): status byte or sysex data -
data1
(Optional[int]
, optional): data1 byte if applicable. Defaults toNone
. -
data2
(Optional[int]
, optional): data2 byte if applicable. Defaults toNone
. -
pmeFlags
(int
, optional): PME flags of event. Defaults toPME_System | PME_System_Safe | PME_PreviewNote | PME_FromMIDI
.
Example Usage
# Create a note on event on middle C
msg = FlMidiMsg(0x90, 0x3C, 0x7F)
# Create a CC#10 event
msg = FlMidiMsg(0xB0, 0x0A, 0x00)
# Create a sysex event for a universal device enquiry
msg = FlMidiMsg([0xF0, 0x7E, 0x7F, 0x06, 0x01, 0xF7])
__range_check(value, prop)
staticmethod
Check that the value is within the allowed range, then return it
__standard_check(value, prop)
staticmethod
Check that it's a standard event, then return the value
StandardMidiMsg
Bases: FlMidiMsg
An FlMidiMsg object which has been type narrowed to a StandardFlMidiMsg.
Note that as FL Studio events are actually of a different type to these
shadow types, you should never use the isinstance
function in order to
perform type-narrowing operations, as it will lead to very obscure bugs
when your type checks never work inside FL Studio, even if they work in
your tests.
Instead, you can type narrow to a StandardFlMidiMsg
object using the
isMidiMsgStandard()
function.
SysexMidiMsg
Bases: FlMidiMsg
An FlMidiMsg object which has been type narrowed to a SysexFlMidiMsg.
Note that as FL Studio events are actually of a different type to these
shadow types, you should never use the isinstance
function in order to
perform type-narrowing operations, as it will lead to very obscure bugs
when your type checks never work inside FL Studio, even if they work in
your tests.
Instead, you can type narrow to a SysexFlMidiMsg
object using the
isMidiMsgSysex()
function.
eventToRawData(event)
Convert event to raw data.
For standard events data is presented as little-endian, meaning that the status byte has the lowest component value in the integer.
Returns:
int | bytes
: data
isMidiMsgStandard(event)
Returns whether an event is a standard event
Args:
event
(FlMidiMsg
): event to check
Returns:
TypeGuard[SysexFlMidiMsg]
: type guarded event
isMidiMsgSysex(event)
Returns whether an event is a sysex event
Args:
event
(FlMidiMsg
): event to check
Returns:
TypeGuard[SysexFlMidiMsg]
: type guarded event