Add API to process CC events received by automation
This commit is contained in:
parent
9ef7a60984
commit
95d3343341
7 changed files with 90 additions and 16 deletions
17
src/sfizz.h
17
src/sfizz.h
|
|
@ -321,6 +321,23 @@ SFIZZ_EXPORTED_API void sfizz_send_cc(sfizz_synth_t* synth, int delay, int cc_nu
|
||||||
*/
|
*/
|
||||||
SFIZZ_EXPORTED_API void sfizz_send_hdcc(sfizz_synth_t* synth, int delay, int cc_number, float norm_value);
|
SFIZZ_EXPORTED_API void sfizz_send_hdcc(sfizz_synth_t* synth, int delay, int cc_number, float norm_value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send a high precision CC automation to the synth.
|
||||||
|
*
|
||||||
|
* This updates the CC value known to the synth, but without performing
|
||||||
|
* additional MIDI-specific interpretations. (eg. the CC 120 and up)
|
||||||
|
*
|
||||||
|
* As with all MIDI events, this needs to happen before the call to
|
||||||
|
* sfizz_render_block() in each block and should appear in order of the delays.
|
||||||
|
* @since 0.6.0
|
||||||
|
*
|
||||||
|
* @param synth The synth.
|
||||||
|
* @param delay The delay of the event in the block, in samples.
|
||||||
|
* @param cc_number The MIDI CC number.
|
||||||
|
* @param norm_value The normalized CC value, in domain 0 to 1.
|
||||||
|
*/
|
||||||
|
SFIZZ_EXPORTED_API void sfizz_automate_hdcc(sfizz_synth_t* synth, int delay, int cc_number, float norm_value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send a pitch wheel event.
|
* @brief Send a pitch wheel event.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -296,6 +296,21 @@ public:
|
||||||
*/
|
*/
|
||||||
void hdcc(int delay, int ccNumber, float normValue) noexcept;
|
void hdcc(int delay, int ccNumber, float normValue) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send a high precision CC automation to the synth
|
||||||
|
*
|
||||||
|
* This updates the CC value known to the synth, but without performing
|
||||||
|
* additional MIDI-specific interpretations. (eg. the CC 120 and up)
|
||||||
|
*
|
||||||
|
* @since 0.6.0
|
||||||
|
*
|
||||||
|
* @param delay the delay at which the event occurs; this should be lower
|
||||||
|
* than the size of the block in the next call to renderBlock().
|
||||||
|
* @param ccNumber the cc number.
|
||||||
|
* @param normValue the normalized cc value, in domain 0 to 1.
|
||||||
|
*/
|
||||||
|
void automateHdcc(int delay, int ccNumber, float normValue) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send a pitch bend event to the synth
|
* @brief Send a pitch bend event to the synth
|
||||||
* @since 0.2.0
|
* @since 0.2.0
|
||||||
|
|
|
||||||
|
|
@ -1090,34 +1090,47 @@ void Synth::Impl::ccDispatch(int delay, int ccNumber, float value) noexcept
|
||||||
}
|
}
|
||||||
|
|
||||||
void Synth::hdcc(int delay, int ccNumber, float normValue) noexcept
|
void Synth::hdcc(int delay, int ccNumber, float normValue) noexcept
|
||||||
|
{
|
||||||
|
Impl& impl = *impl_;
|
||||||
|
impl.performHdcc(delay, ccNumber, normValue, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Synth::automateHdcc(int delay, int ccNumber, float normValue) noexcept
|
||||||
|
{
|
||||||
|
Impl& impl = *impl_;
|
||||||
|
impl.performHdcc(delay, ccNumber, normValue, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Synth::Impl::performHdcc(int delay, int ccNumber, float normValue, bool asMidi) noexcept
|
||||||
{
|
{
|
||||||
ASSERT(ccNumber < config::numCCs);
|
ASSERT(ccNumber < config::numCCs);
|
||||||
ASSERT(ccNumber >= 0);
|
ASSERT(ccNumber >= 0);
|
||||||
|
|
||||||
Impl& impl = *impl_;
|
ScopedTiming logger { dispatchDuration_, ScopedTiming::Operation::addToDuration };
|
||||||
ScopedTiming logger { impl.dispatchDuration_, ScopedTiming::Operation::addToDuration };
|
resources_.midiState.ccEvent(delay, ccNumber, normValue);
|
||||||
impl.resources_.midiState.ccEvent(delay, ccNumber, normValue);
|
|
||||||
|
|
||||||
const std::unique_lock<SpinMutex> lock { impl.callbackGuard_, std::try_to_lock };
|
const std::unique_lock<SpinMutex> lock { callbackGuard_, std::try_to_lock };
|
||||||
if (!lock.owns_lock())
|
if (!lock.owns_lock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ccNumber == config::resetCC) {
|
if (asMidi) {
|
||||||
impl.resetAllControllers(delay);
|
if (ccNumber == config::resetCC) {
|
||||||
return;
|
resetAllControllers(delay);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ccNumber == config::allNotesOffCC || ccNumber == config::allSoundOffCC) {
|
||||||
|
for (auto& voice : voiceManager_)
|
||||||
|
voice.reset();
|
||||||
|
resources_.midiState.allNotesOff(delay);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ccNumber == config::allNotesOffCC || ccNumber == config::allSoundOffCC) {
|
for (auto& voice : voiceManager_)
|
||||||
for (auto& voice : impl.voiceManager_)
|
|
||||||
voice.reset();
|
|
||||||
impl.resources_.midiState.allNotesOff(delay);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& voice : impl.voiceManager_)
|
|
||||||
voice.registerCC(delay, ccNumber, normValue);
|
voice.registerCC(delay, ccNumber, normValue);
|
||||||
|
|
||||||
impl.ccDispatch(delay, ccNumber, normValue);
|
ccDispatch(delay, ccNumber, normValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Synth::Impl::setDefaultHdcc(int ccNumber, float value)
|
void Synth::Impl::setDefaultHdcc(int ccNumber, float value)
|
||||||
|
|
|
||||||
|
|
@ -342,6 +342,15 @@ public:
|
||||||
* @param normValue the normalized cc value, in domain 0 to 1
|
* @param normValue the normalized cc value, in domain 0 to 1
|
||||||
*/
|
*/
|
||||||
void hdcc(int delay, int ccNumber, float normValue) noexcept;
|
void hdcc(int delay, int ccNumber, float normValue) noexcept;
|
||||||
|
/**
|
||||||
|
* @brief Send a high precision CC automation to the synth
|
||||||
|
*
|
||||||
|
* @param delay the delay at which the event occurs; this should be lower
|
||||||
|
* than the size of the block in the next call to renderBlock().
|
||||||
|
* @param ccNumber the cc number.
|
||||||
|
* @param normValue the normalized cc value, in domain 0 to 1.
|
||||||
|
*/
|
||||||
|
void automateHdcc(int delay, int ccNumber, float normValue) noexcept;
|
||||||
/**
|
/**
|
||||||
* @brief Get the current value of a controller under the current instrument
|
* @brief Get the current value of a controller under the current instrument
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,16 @@ struct Synth::Impl final: public Parser::Listener {
|
||||||
|
|
||||||
std::bitset<config::numCCs> collectAllUsedCCs();
|
std::bitset<config::numCCs> collectAllUsedCCs();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Perform a CC event
|
||||||
|
*
|
||||||
|
* @param delay The delay
|
||||||
|
* @param ccNumber The CC number
|
||||||
|
* @param normValue The normalized value
|
||||||
|
* @param asMidi Whether to process as a MIDI event
|
||||||
|
*/
|
||||||
|
void performHdcc(int delay, int ccNumber, float normValue, bool asMidi) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the default value for a CC
|
* @brief Set the default value for a CC
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,11 @@ void sfz::Sfizz::hdcc(int delay, int ccNumber, float normValue) noexcept
|
||||||
synth->hdcc(delay, ccNumber, normValue);
|
synth->hdcc(delay, ccNumber, normValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sfz::Sfizz::automateHdcc(int delay, int ccNumber, float normValue) noexcept
|
||||||
|
{
|
||||||
|
synth->automateHdcc(delay, ccNumber, normValue);
|
||||||
|
}
|
||||||
|
|
||||||
void sfz::Sfizz::pitchWheel(int delay, int pitch) noexcept
|
void sfz::Sfizz::pitchWheel(int delay, int pitch) noexcept
|
||||||
{
|
{
|
||||||
synth->pitchWheel(delay, pitch);
|
synth->pitchWheel(delay, pitch);
|
||||||
|
|
|
||||||
|
|
@ -146,6 +146,11 @@ void sfizz_send_hdcc(sfizz_synth_t* synth, int delay, int cc_number, float norm_
|
||||||
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
self->hdcc(delay, cc_number, norm_value);
|
self->hdcc(delay, cc_number, norm_value);
|
||||||
}
|
}
|
||||||
|
void sfizz_automate_hdcc(sfizz_synth_t* synth, int delay, int cc_number, float norm_value)
|
||||||
|
{
|
||||||
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
|
self->automateHdcc(delay, cc_number, norm_value);
|
||||||
|
}
|
||||||
void sfizz_send_pitch_wheel(sfizz_synth_t* synth, int delay, int pitch)
|
void sfizz_send_pitch_wheel(sfizz_synth_t* synth, int delay, int pitch)
|
||||||
{
|
{
|
||||||
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
auto* self = reinterpret_cast<sfz::Synth*>(synth);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue