Merge pull request #354 from jpcima/host-time
Plugin-level support for host time
This commit is contained in:
commit
6076f17173
9 changed files with 345 additions and 11 deletions
168
lv2/sfizz.c
168
lv2/sfizz.c
|
|
@ -131,7 +131,9 @@ typedef struct
|
|||
LV2_URID sample_rate_uri;
|
||||
LV2_URID atom_object_uri;
|
||||
LV2_URID atom_float_uri;
|
||||
LV2_URID atom_double_uri;
|
||||
LV2_URID atom_int_uri;
|
||||
LV2_URID atom_long_uri;
|
||||
LV2_URID atom_urid_uri;
|
||||
LV2_URID atom_path_uri;
|
||||
LV2_URID patch_set_uri;
|
||||
|
|
@ -150,6 +152,12 @@ typedef struct
|
|||
LV2_URID sfizz_check_modification_uri;
|
||||
LV2_URID sfizz_active_voices_uri;
|
||||
LV2_URID time_position_uri;
|
||||
LV2_URID time_bar_uri;
|
||||
LV2_URID time_bar_beat_uri;
|
||||
LV2_URID time_beat_unit_uri;
|
||||
LV2_URID time_beats_per_bar_uri;
|
||||
LV2_URID time_beats_per_minute_uri;
|
||||
LV2_URID time_speed_uri;
|
||||
|
||||
// Sfizz related data
|
||||
sfizz_synth_t *synth;
|
||||
|
|
@ -166,6 +174,14 @@ typedef struct
|
|||
float sample_rate;
|
||||
atomic_int must_update_midnam;
|
||||
|
||||
// Timing data
|
||||
int bar;
|
||||
float bar_beat;
|
||||
int beats_per_bar;
|
||||
int beat_unit;
|
||||
float bpm_tempo;
|
||||
float speed;
|
||||
|
||||
// Paths
|
||||
char bundle_path[MAX_BUNDLE_PATH_SIZE];
|
||||
} sfizz_plugin_t;
|
||||
|
|
@ -187,6 +203,14 @@ enum
|
|||
SFIZZ_ACTIVE_VOICES = 12,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
SFIZZ_TIMEINFO_POSITION = 1 << 0,
|
||||
SFIZZ_TIMEINFO_SIGNATURE = 1 << 1,
|
||||
SFIZZ_TIMEINFO_TEMPO = 1 << 2,
|
||||
SFIZZ_TIMEINFO_SPEED = 1 << 3,
|
||||
};
|
||||
|
||||
static void
|
||||
sfizz_lv2_state_free_path(LV2_State_Free_Path_Handle handle,
|
||||
char *path)
|
||||
|
|
@ -210,7 +234,9 @@ sfizz_lv2_map_required_uris(sfizz_plugin_t *self)
|
|||
self->nominal_block_length_uri = map->map(map->handle, LV2_BUF_SIZE__nominalBlockLength);
|
||||
self->sample_rate_uri = map->map(map->handle, LV2_PARAMETERS__sampleRate);
|
||||
self->atom_float_uri = map->map(map->handle, LV2_ATOM__Float);
|
||||
self->atom_double_uri = map->map(map->handle, LV2_ATOM__Double);
|
||||
self->atom_int_uri = map->map(map->handle, LV2_ATOM__Int);
|
||||
self->atom_long_uri = map->map(map->handle, LV2_ATOM__Long);
|
||||
self->atom_path_uri = map->map(map->handle, LV2_ATOM__Path);
|
||||
self->atom_urid_uri = map->map(map->handle, LV2_ATOM__URID);
|
||||
self->atom_object_uri = map->map(map->handle, LV2_ATOM__Object);
|
||||
|
|
@ -230,6 +256,68 @@ sfizz_lv2_map_required_uris(sfizz_plugin_t *self)
|
|||
self->sfizz_log_status_uri = map->map(map->handle, SFIZZ__logStatus);
|
||||
self->sfizz_check_modification_uri = map->map(map->handle, SFIZZ__checkModification);
|
||||
self->time_position_uri = map->map(map->handle, LV2_TIME__Position);
|
||||
self->time_bar_uri = map->map(map->handle, LV2_TIME__bar);
|
||||
self->time_bar_beat_uri = map->map(map->handle, LV2_TIME__barBeat);
|
||||
self->time_beat_unit_uri = map->map(map->handle, LV2_TIME__beatUnit);
|
||||
self->time_beats_per_bar_uri = map->map(map->handle, LV2_TIME__beatsPerBar);
|
||||
self->time_beats_per_minute_uri = map->map(map->handle, LV2_TIME__beatsPerMinute);
|
||||
self->time_speed_uri = map->map(map->handle, LV2_TIME__speed);
|
||||
}
|
||||
|
||||
static bool
|
||||
sfizz_atom_extract_real(sfizz_plugin_t *self, const LV2_Atom *atom, double *real)
|
||||
{
|
||||
if (!atom)
|
||||
return false;
|
||||
|
||||
const LV2_URID type = atom->type;
|
||||
|
||||
if (type == self->atom_int_uri && atom->size >= sizeof(int32_t)) {
|
||||
*real = ((const LV2_Atom_Int *)atom)->body;
|
||||
return true;
|
||||
}
|
||||
if (type == self->atom_long_uri && atom->size >= sizeof(int64_t)) {
|
||||
*real = ((const LV2_Atom_Long *)atom)->body;
|
||||
return true;
|
||||
}
|
||||
if (type == self->atom_float_uri && atom->size >= sizeof(float)) {
|
||||
*real = ((const LV2_Atom_Float *)atom)->body;
|
||||
return true;
|
||||
}
|
||||
if (type == self->atom_double_uri && atom->size >= sizeof(double)) {
|
||||
*real = ((const LV2_Atom_Double *)atom)->body;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
sfizz_atom_extract_integer(sfizz_plugin_t *self, const LV2_Atom *atom, int64_t *integer)
|
||||
{
|
||||
if (!atom)
|
||||
return false;
|
||||
|
||||
const LV2_URID type = atom->type;
|
||||
|
||||
if (type == self->atom_int_uri && atom->size >= sizeof(int32_t)) {
|
||||
*integer = ((const LV2_Atom_Int *)atom)->body;
|
||||
return true;
|
||||
}
|
||||
if (type == self->atom_long_uri && atom->size >= sizeof(int64_t)) {
|
||||
*integer = ((const LV2_Atom_Long *)atom)->body;
|
||||
return true;
|
||||
}
|
||||
if (type == self->atom_float_uri && atom->size >= sizeof(float)) {
|
||||
*integer = (int64_t)((const LV2_Atom_Float *)atom)->body;
|
||||
return true;
|
||||
}
|
||||
if (type == self->atom_double_uri && atom->size >= sizeof(double)) {
|
||||
*integer = (int64_t)((const LV2_Atom_Double *)atom)->body;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -326,6 +414,19 @@ sfizz_lv2_get_default_scala_path(LV2_Handle instance, char *path, size_t size)
|
|||
snprintf(path, size, "%s/%s", self->bundle_path, DEFAULT_SCALA_FILE);
|
||||
}
|
||||
|
||||
static void
|
||||
sfizz_lv2_update_timeinfo(sfizz_plugin_t *self, int delay, int updates)
|
||||
{
|
||||
if (updates & SFIZZ_TIMEINFO_POSITION)
|
||||
sfizz_send_time_position(self->synth, delay, self->bar, self->bar_beat);
|
||||
if (updates & SFIZZ_TIMEINFO_SIGNATURE)
|
||||
sfizz_send_time_signature(self->synth, delay, self->beats_per_bar, self->beat_unit);
|
||||
if (updates & SFIZZ_TIMEINFO_TEMPO)
|
||||
sfizz_send_tempo(self->synth, delay, 60.0f / self->bpm_tempo);
|
||||
if (updates & SFIZZ_TIMEINFO_SPEED)
|
||||
sfizz_send_playback_state(self->synth, delay, self->speed > 0);
|
||||
}
|
||||
|
||||
static LV2_Handle
|
||||
instantiate(const LV2_Descriptor *descriptor,
|
||||
double rate,
|
||||
|
|
@ -361,6 +462,14 @@ instantiate(const LV2_Descriptor *descriptor,
|
|||
self->check_modification = false;
|
||||
self->sample_counter = 0;
|
||||
|
||||
// Initial timing
|
||||
self->bar = 0;
|
||||
self->bar_beat = 0;
|
||||
self->beats_per_bar = 4;
|
||||
self->beat_unit = 4;
|
||||
self->bpm_tempo = 120;
|
||||
self->speed = 1;
|
||||
|
||||
// Get the features from the host and populate the structure
|
||||
for (const LV2_Feature *const *f = features; *f; f++)
|
||||
{
|
||||
|
|
@ -472,6 +581,8 @@ instantiate(const LV2_Descriptor *descriptor,
|
|||
sfizz_load_file(self->synth, self->sfz_file_path);
|
||||
sfizz_load_scala_file(self->synth, self->scala_file_path);
|
||||
|
||||
sfizz_lv2_update_timeinfo(self, 0, ~0);
|
||||
|
||||
return (LV2_Handle)self;
|
||||
}
|
||||
|
||||
|
|
@ -751,6 +862,8 @@ run(LV2_Handle instance, uint32_t sample_count)
|
|||
|
||||
LV2_ATOM_SEQUENCE_FOREACH(self->control_port, ev)
|
||||
{
|
||||
const int delay = (int)ev->time.frames;
|
||||
|
||||
// If the received atom is an object/patch message
|
||||
if (ev->body.type == self->atom_object_uri)
|
||||
{
|
||||
|
|
@ -779,7 +892,60 @@ run(LV2_Handle instance, uint32_t sample_count)
|
|||
}
|
||||
else if (obj->body.otype == self->time_position_uri)
|
||||
{
|
||||
// TODO: Handle time position atom
|
||||
const LV2_Atom *bar_atom = NULL;
|
||||
const LV2_Atom *bar_beat_atom = NULL;
|
||||
const LV2_Atom *beat_unit_atom = NULL;
|
||||
const LV2_Atom *beats_per_bar_atom = NULL;
|
||||
const LV2_Atom *beats_per_minute_atom = NULL;
|
||||
const LV2_Atom *speed_atom = NULL;
|
||||
|
||||
lv2_atom_object_get(
|
||||
obj,
|
||||
self->time_bar_uri, &bar_atom,
|
||||
self->time_bar_beat_uri, &bar_beat_atom,
|
||||
self->time_beats_per_bar_uri, &beats_per_bar_atom,
|
||||
self->time_beats_per_minute_uri, &beats_per_minute_atom,
|
||||
self->time_beat_unit_uri, &beat_unit_atom,
|
||||
self->time_speed_uri, &speed_atom,
|
||||
0);
|
||||
|
||||
int updates = 0;
|
||||
|
||||
int64_t bar;
|
||||
double bar_beat;
|
||||
if (sfizz_atom_extract_integer(self, bar_atom, &bar)) {
|
||||
self->bar = (int)bar;
|
||||
updates |= SFIZZ_TIMEINFO_POSITION;
|
||||
}
|
||||
if (sfizz_atom_extract_real(self, bar_beat_atom, &bar_beat)) {
|
||||
self->bar_beat = (float)bar_beat;
|
||||
updates |= SFIZZ_TIMEINFO_POSITION;
|
||||
}
|
||||
|
||||
double beats_per_bar;
|
||||
int64_t beat_unit;
|
||||
if (sfizz_atom_extract_real(self, beats_per_bar_atom, &beats_per_bar)) {
|
||||
self->beats_per_bar = (int)beats_per_bar;
|
||||
updates |= SFIZZ_TIMEINFO_SIGNATURE;
|
||||
}
|
||||
if (sfizz_atom_extract_integer(self, beat_unit_atom, &beat_unit)) {
|
||||
self->beat_unit = (int)beat_unit;
|
||||
updates |= SFIZZ_TIMEINFO_SIGNATURE;
|
||||
}
|
||||
|
||||
double tempo;
|
||||
if (sfizz_atom_extract_real(self, beats_per_minute_atom, &tempo)) {
|
||||
self->bpm_tempo = (float)tempo;
|
||||
updates |= SFIZZ_TIMEINFO_TEMPO;
|
||||
}
|
||||
|
||||
double speed;
|
||||
if (sfizz_atom_extract_real(self, speed_atom, &speed)) {
|
||||
self->speed = (float)speed;
|
||||
updates |= SFIZZ_TIMEINFO_SPEED;
|
||||
}
|
||||
|
||||
sfizz_lv2_update_timeinfo(self, delay, updates);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
36
src/sfizz.h
36
src/sfizz.h
|
|
@ -302,13 +302,43 @@ SFIZZ_EXPORTED_API void sfizz_send_pitch_wheel(sfizz_synth_t* synth, int delay,
|
|||
SFIZZ_EXPORTED_API void sfizz_send_aftertouch(sfizz_synth_t* synth, int delay, char aftertouch);
|
||||
|
||||
/**
|
||||
* @brief Send a tempo event. (CURRENTLY UNIMPLEMENTED)
|
||||
* @brief Send a tempo event.
|
||||
*
|
||||
* @param synth The synth.
|
||||
* @param delay The delay.
|
||||
* @param seconds_per_quarter The seconds per quarter.
|
||||
* @param seconds_per_beat The seconds per beat.
|
||||
*/
|
||||
SFIZZ_EXPORTED_API void sfizz_send_tempo(sfizz_synth_t* synth, int delay, float seconds_per_quarter);
|
||||
SFIZZ_EXPORTED_API void sfizz_send_tempo(sfizz_synth_t* synth, int delay, float seconds_per_beat);
|
||||
|
||||
/**
|
||||
* @brief Send the time signature.
|
||||
*
|
||||
* @param synth The synth.
|
||||
* @param delay The delay.
|
||||
* @param beats_per_bar The number of beats per bar, or time signature numerator.
|
||||
* @param beat_unit The note corresponding to one beat, or time signature denominator.
|
||||
*/
|
||||
SFIZZ_EXPORTED_API void sfizz_send_time_signature(sfizz_synth_t* synth, int delay, int beats_per_bar, int beat_unit);
|
||||
|
||||
/**
|
||||
* @brief Send the time position.
|
||||
*
|
||||
* @param synth The synth.
|
||||
* @param delay The delay.
|
||||
* @param bar The current bar.
|
||||
* @param bar_beat The fractional position of the current beat within the bar.
|
||||
*/
|
||||
SFIZZ_EXPORTED_API void sfizz_send_time_position(sfizz_synth_t* synth, int delay, int bar, float bar_beat);
|
||||
|
||||
/**
|
||||
* @brief Send the playback state.
|
||||
*
|
||||
* @param synth The synth.
|
||||
* @param delay The delay.
|
||||
* @param playback_state The playback state, 1 if playing, 0 if stopped.
|
||||
*/
|
||||
SFIZZ_EXPORTED_API void sfizz_send_playback_state(sfizz_synth_t* synth, int delay, int playback_state);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Render a block audio data into a stereo channel. No other channel
|
||||
|
|
|
|||
|
|
@ -291,13 +291,39 @@ public:
|
|||
void aftertouch(int delay, uint8_t aftertouch) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Send a tempo event to the synth. (CURRENTLY UNIMPLEMENTED)
|
||||
* @brief Send a tempo event 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 secondsPerQuarter the new period of the quarter note.
|
||||
* @param secondsPerBeat the new period of the beat.
|
||||
*/
|
||||
void tempo(int delay, float secondsPerQuarter) noexcept;
|
||||
void tempo(int delay, float secondsPerBeat) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Send the time signature.
|
||||
*
|
||||
* @param delay The delay.
|
||||
* @param beats_per_bar The number of beats per bar, or time signature numerator.
|
||||
* @param beat_unit The note corresponding to one beat, or time signature denominator.
|
||||
*/
|
||||
void timeSignature(int delay, int beatsPerBar, int beatUnit);
|
||||
|
||||
/**
|
||||
* @brief Send the time position.
|
||||
*
|
||||
* @param delay The delay.
|
||||
* @param bar The current bar.
|
||||
* @param bar_beat The fractional position of the current beat within the bar.
|
||||
*/
|
||||
void timePosition(int delay, int bar, float barBeat);
|
||||
|
||||
/**
|
||||
* @brief Send the playback state.
|
||||
*
|
||||
* @param delay The delay.
|
||||
* @param playback_state The playback state, 1 if playing, 0 if stopped.
|
||||
*/
|
||||
void playbackState(int delay, int playbackState);
|
||||
|
||||
/**
|
||||
* @brief Render an block of audio data in the buffer. This call will reset
|
||||
|
|
|
|||
|
|
@ -1116,6 +1116,29 @@ void sfz::Synth::tempo(int /* delay */, float /* secondsPerQuarter */) noexcept
|
|||
{
|
||||
ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration };
|
||||
}
|
||||
void sfz::Synth::timeSignature(int delay, int beatsPerBar, int beatUnit)
|
||||
{
|
||||
ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration };
|
||||
|
||||
(void)delay;
|
||||
(void)beatsPerBar;
|
||||
(void)beatUnit;
|
||||
}
|
||||
void sfz::Synth::timePosition(int delay, int bar, float barBeat)
|
||||
{
|
||||
ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration };
|
||||
|
||||
(void)delay;
|
||||
(void)bar;
|
||||
(void)barBeat;
|
||||
}
|
||||
void sfz::Synth::playbackState(int delay, int playbackState)
|
||||
{
|
||||
ScopedTiming logger { dispatchDuration, ScopedTiming::Operation::addToDuration };
|
||||
|
||||
(void)delay;
|
||||
(void)playbackState;
|
||||
}
|
||||
|
||||
int sfz::Synth::getNumRegions() const noexcept
|
||||
{
|
||||
|
|
|
|||
|
|
@ -392,6 +392,29 @@ public:
|
|||
* @param secondsPerQuarter the new period of the quarter note
|
||||
*/
|
||||
void tempo(int delay, float secondsPerQuarter) noexcept;
|
||||
/**
|
||||
* @brief Send the time signature.
|
||||
*
|
||||
* @param delay The delay.
|
||||
* @param beats_per_bar The number of beats per bar, or time signature numerator.
|
||||
* @param beat_unit The note corresponding to one beat, or time signature denominator.
|
||||
*/
|
||||
void timeSignature(int delay, int beatsPerBar, int beatUnit);
|
||||
/**
|
||||
* @brief Send the time position.
|
||||
*
|
||||
* @param delay The delay.
|
||||
* @param bar The current bar.
|
||||
* @param bar_beat The fractional position of the current beat within the bar.
|
||||
*/
|
||||
void timePosition(int delay, int bar, float barBeat);
|
||||
/**
|
||||
* @brief Send the playback state.
|
||||
*
|
||||
* @param delay The delay.
|
||||
* @param playback_state The playback state, 1 if playing, 0 if stopped.
|
||||
*/
|
||||
void playbackState(int delay, int playbackState);
|
||||
/**
|
||||
* @brief Render an block of audio data in the buffer. This call will reset
|
||||
* the synth in its waiting state for the next batch of events. The size of
|
||||
|
|
|
|||
|
|
@ -153,9 +153,24 @@ void sfz::Sfizz::aftertouch(int delay, uint8_t aftertouch) noexcept
|
|||
synth->aftertouch(delay, aftertouch);
|
||||
}
|
||||
|
||||
void sfz::Sfizz::tempo(int delay, float secondsPerQuarter) noexcept
|
||||
void sfz::Sfizz::tempo(int delay, float secondsPerBeat) noexcept
|
||||
{
|
||||
synth->tempo(delay, secondsPerQuarter);
|
||||
synth->tempo(delay, secondsPerBeat);
|
||||
}
|
||||
|
||||
void sfz::Sfizz::timeSignature(int delay, int beatsPerBar, int beatUnit)
|
||||
{
|
||||
synth->timeSignature(delay, beatsPerBar, beatUnit);
|
||||
}
|
||||
|
||||
void sfz::Sfizz::timePosition(int delay, int bar, float barBeat)
|
||||
{
|
||||
synth->timePosition(delay, bar, barBeat);
|
||||
}
|
||||
|
||||
void sfz::Sfizz::playbackState(int delay, int playbackState)
|
||||
{
|
||||
synth->playbackState(delay, playbackState);
|
||||
}
|
||||
|
||||
void sfz::Sfizz::renderBlock(float** buffers, size_t numSamples, int /*numOutputs*/) noexcept
|
||||
|
|
|
|||
|
|
@ -160,6 +160,21 @@ void sfizz_send_tempo(sfizz_synth_t* synth, int delay, float seconds_per_quarter
|
|||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
||||
self->tempo(delay, seconds_per_quarter);
|
||||
}
|
||||
void sfizz_send_time_signature(sfizz_synth_t* synth, int delay, int beats_per_bar, int beat_unit)
|
||||
{
|
||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
||||
self->timeSignature(delay, beats_per_bar, beat_unit);
|
||||
}
|
||||
void sfizz_send_time_position(sfizz_synth_t* synth, int delay, int bar, float bar_beat)
|
||||
{
|
||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
||||
self->timePosition(delay, bar, bar_beat);
|
||||
}
|
||||
void sfizz_send_playback_state(sfizz_synth_t* synth, int delay, int playback_state)
|
||||
{
|
||||
auto self = reinterpret_cast<sfz::Synth*>(synth);
|
||||
self->playbackState(delay, playback_state);
|
||||
}
|
||||
|
||||
void sfizz_render_block(sfizz_synth_t* synth, float** channels, int num_channels, int num_frames)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@
|
|||
#include "pluginterfaces/vst/ivstparameterchanges.h"
|
||||
#include <cstring>
|
||||
|
||||
#pragma message("TODO: send tempo") // NOLINT
|
||||
|
||||
template<class T>
|
||||
constexpr int fastRound(T x)
|
||||
{
|
||||
|
|
@ -55,6 +53,13 @@ tresult PLUGIN_API SfizzVstProcessor::initialize(FUnknown* context)
|
|||
_currentStretchedTuning = 0.0;
|
||||
loadSfzFileOrDefault(*_synth, {});
|
||||
|
||||
_synth->tempo(0, 0.5);
|
||||
_timeSigNumerator = 4;
|
||||
_timeSigDenominator = 4;
|
||||
_synth->timeSignature(0, _timeSigNumerator, _timeSigDenominator);
|
||||
_synth->timePosition(0, 0, 0);
|
||||
_synth->playbackState(0, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -143,6 +148,9 @@ tresult PLUGIN_API SfizzVstProcessor::process(Vst::ProcessData& data)
|
|||
{
|
||||
sfz::Sfizz& synth = *_synth;
|
||||
|
||||
if (data.processContext)
|
||||
updateTimeInfo(*data.processContext);
|
||||
|
||||
if (Vst::IParameterChanges* pc = data.inputParameterChanges)
|
||||
processParameterChanges(*pc);
|
||||
|
||||
|
|
@ -198,6 +206,29 @@ tresult PLUGIN_API SfizzVstProcessor::process(Vst::ProcessData& data)
|
|||
return kResultTrue;
|
||||
}
|
||||
|
||||
void SfizzVstProcessor::updateTimeInfo(const Vst::ProcessContext& context)
|
||||
{
|
||||
sfz::Sfizz& synth = *_synth;
|
||||
|
||||
if (context.state & context.kTempoValid)
|
||||
synth.tempo(0, 60.0f / context.tempo);
|
||||
|
||||
if (context.state & context.kTimeSigValid) {
|
||||
_timeSigNumerator = context.timeSigNumerator;
|
||||
_timeSigDenominator = context.timeSigDenominator;
|
||||
synth.timeSignature(0, _timeSigNumerator, _timeSigDenominator);
|
||||
}
|
||||
|
||||
if (context.state & context.kProjectTimeMusicValid) {
|
||||
double beats = context.projectTimeMusic * 0.25 * _timeSigDenominator;
|
||||
double bars = beats / _timeSigNumerator;
|
||||
beats -= int(bars) * _timeSigNumerator;
|
||||
synth.timePosition(0, int(bars), float(beats));
|
||||
}
|
||||
|
||||
synth.playbackState(0, (context.state & context.kPlaying) != 0);
|
||||
}
|
||||
|
||||
void SfizzVstProcessor::processParameterChanges(Vst::IParameterChanges& pc)
|
||||
{
|
||||
uint32 paramCount = pc.getParameterCount();
|
||||
|
|
|
|||
|
|
@ -64,6 +64,11 @@ private:
|
|||
uint32 _fileChangeCounter = 0;
|
||||
uint32 _fileChangePeriod = 0;
|
||||
|
||||
// time info
|
||||
int _timeSigNumerator = 0;
|
||||
int _timeSigDenominator = 0;
|
||||
void updateTimeInfo(const Vst::ProcessContext& context);
|
||||
|
||||
// messaging
|
||||
struct RTMessage {
|
||||
const char* type;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue