(close-midi-sequencer! audio-ctx)
Closes the MIDI sequencer in the audio context.
Closes the MIDI sequencer in the audio context.
(close-midi-synth! audio-ctx)
Closes the MIDI synth in the audio context.
Closes the MIDI synth in the audio context.
(get-midi-sequencer! audio-ctx)
If there isn't already a :midi-sequencer in the audio context, creates a MIDI sequencer and adds it.
IMPORTANT: get-midi-synth!
must be called on the context before
get-midi-sequencer!
, because get-midi-sequencer!
also needs to hook up
the sequencer's transmitter to the synthesizer's receiver.
If there isn't already a :midi-sequencer in the audio context, creates a MIDI sequencer and adds it. IMPORTANT: `get-midi-synth!` must be called on the context before `get-midi-sequencer!`, because `get-midi-sequencer!` also needs to hook up the sequencer's transmitter to the synthesizer's receiver.
(get-midi-synth)
If the global midi-synth has been initialized, then that's the synth you get whenever you call this function.
Otherwise, takes a MIDI synth instance from the pool and makes sure the pool is more-or-less topped off.
If the global *midi-synth* has been initialized, then that's the synth you get whenever you call this function. Otherwise, takes a MIDI synth instance from the pool and makes sure the pool is more-or-less topped off.
(get-midi-synth! audio-ctx)
If there isn't already a :midi-synth in the audio context, finds an available MIDI synth and adds it.
If there isn't already a :midi-synth in the audio context, finds an available MIDI synth and adds it.
(ids->channels {:keys [instruments] :as score})
Inspects a score and generates a map of instrument IDs to MIDI channels. The channel values are maps with keys :channel (the channel number) and :patch (the General MIDI patch number).
Inspects a score and generates a map of instrument IDs to MIDI channels. The channel values are maps with keys :channel (the channel number) and :patch (the General MIDI patch number).
(map-instruments-to-channels! audio-ctx score)
Sets aside one MIDI channel per instrument in the score.
Stores the result (a map of instrument IDs to channel numbers) in the audio context as :midi-channels.
Also returns the result.
Sets aside one MIDI channel per instrument in the score. Stores the result (a map of instrument IDs to channel numbers) in the audio context as :midi-channels. Also returns the result.
(ms->ticks-fn tempo-itinerary division-type resolution)
Returns a function that will convert an offset in ms into ticks, based on the history of tempo changes in the score and the desired javax.midi.Sequence division type and resolution.
When the division type is SMPTE, the conversion is simple math, and we don't need to consider the tempo itinerary at all.
When the division type is PPQ, however, the logic is more complicated because the physical duration of a tick varies depending on the tempo, and this has a cascading effect when it comes to scheduling an event. We must consider not only the current tempo, but the entire history of tempo changes in the score.
Returns a function that will convert an offset in ms into ticks, based on the history of tempo changes in the score and the desired javax.midi.Sequence division type and resolution. When the division type is SMPTE, the conversion is simple math, and we don't need to consider the tempo itinerary at all. When the division type is PPQ, however, the logic is more complicated because the physical duration of a tick varies depending on the tempo, and this has a cascading effect when it comes to scheduling an event. We must consider not only the current tempo, but the entire history of tempo changes in the score.
(play-sequence! audio-ctx done-fn)
Plays the sequence currently loaded into the MIDI sequencer.
Calls done-fn
when the sequence is done playing.
Plays the sequence currently loaded into the MIDI sequencer. Calls `done-fn` when the sequence is done playing.
(ppq-ms->ticks tempo-itinerary offset-ms resolution)
Converts an offset in ms into ticks.
NB: the length of a tick varies depending on the current tempo. Therefore, an offset expressed in ticks is influenced by the history of tempos up to that moment in time.
Converts an offset in ms into ticks. NB: the length of a tick varies depending on the current tempo. Therefore, an offset expressed in ticks is influenced by the history of tempos up to that moment in time.
(set-tempo-message tempo)
In a "set tempo" metamessage, the desired tempo is expressed not in beats per minute (BPM), but in microseconds per quarter note (I'll abbreviate this as "uspq").
There are 60 million microseconds in a minute, therefore the formula to convert BPM => uspq is 60,000,000 / BPM.
Example conversion: 120 BPM / 60,000,000 = 500,000 uspq.
The slower the tempo, the lower the BPM and the higher the uspq.
For some reason, the MIDI spec limits the number of bytes available to express this number to a maximum of 3 bytes, even though there are extremely slow tempos (<4 BPM) that, when expressed in uspq, are numbers too large to fit into 3 bytes. Effectively, this means that the slowest supported tempo is about 3.58 BPM. That's extremely slow, so it probably won't cause any problems in practice, but this function will throw an assertion error below that tempo, so it's worth mentioning.
ref: https://www.recordingblogs.com/wiki/midi-set-tempo-meta-message https://www.programcreek.com/java-api-examples/?api=javax.sound.midi.MetaMessage https://docs.oracle.com/javase/7/docs/api/javax/sound/midi/MetaMessage.html https://stackoverflow.com/a/22798636/2338327
In a "set tempo" metamessage, the desired tempo is expressed not in beats per minute (BPM), but in microseconds per quarter note (I'll abbreviate this as "uspq"). There are 60 million microseconds in a minute, therefore the formula to convert BPM => uspq is 60,000,000 / BPM. Example conversion: 120 BPM / 60,000,000 = 500,000 uspq. The slower the tempo, the lower the BPM and the higher the uspq. For some reason, the MIDI spec limits the number of bytes available to express this number to a maximum of 3 bytes, even though there are extremely slow tempos (<4 BPM) that, when expressed in uspq, are numbers too large to fit into 3 bytes. Effectively, this means that the slowest supported tempo is about 3.58 BPM. That's extremely slow, so it probably won't cause any problems in practice, but this function will throw an assertion error below that tempo, so it's worth mentioning. ref: https://www.recordingblogs.com/wiki/midi-set-tempo-meta-message https://www.programcreek.com/java-api-examples/?api=javax.sound.midi.MetaMessage https://docs.oracle.com/javase/7/docs/api/javax/sound/midi/MetaMessage.html https://stackoverflow.com/a/22798636/2338327
(tempo-itinerary score resolution)
Returns a sequence of maps, each of which represents a tempo value at a point in time. The tempo is expressed in BPM, and the point in time is expressed both in ms and in ticks.
Returns a sequence of maps, each of which represents a tempo value at a point in time. The tempo is expressed in BPM, and the point in time is expressed both in ms and in ticks.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close