Merge pull request #226 from paulfd/stack-smash
Residual tiny quality of life changes in the LV2 plugin
This commit is contained in:
commit
3ed3bc1754
6 changed files with 119 additions and 47 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -34,3 +34,5 @@ node_modules/
|
||||||
*.lock
|
*.lock
|
||||||
*.sublime-*
|
*.sublime-*
|
||||||
*.code-*
|
*.code-*
|
||||||
|
.kak.tags.namecache
|
||||||
|
.clangd
|
||||||
|
|
|
||||||
84
lv2/sfizz.c
84
lv2/sfizz.c
|
|
@ -534,23 +534,41 @@ sfizz_lv2_status_log(sfizz_plugin_t *self)
|
||||||
// lv2_log_note(&self->logger, "[sfizz] Active voices: %d\n", sfizz_get_num_active_voices(self->synth));
|
// lv2_log_note(&self->logger, "[sfizz] Active voices: %d\n", sfizz_get_num_active_voices(self->synth));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int next_pow_2(int v)
|
||||||
|
{
|
||||||
|
if (v < 1)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
// Bit twiddling hack
|
||||||
|
v--;
|
||||||
|
v |= v >> 1;
|
||||||
|
v |= v >> 2;
|
||||||
|
v |= v >> 4;
|
||||||
|
v |= v >> 8;
|
||||||
|
v |= v >> 16;
|
||||||
|
v++;
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sfizz_lv2_check_oversampling(sfizz_plugin_t* self)
|
sfizz_lv2_check_oversampling(sfizz_plugin_t* self)
|
||||||
{
|
{
|
||||||
sfizz_oversampling_factor_t oversampling = (sfizz_oversampling_factor_t)*self->oversampling_port;
|
int port_value = next_pow_2((int)*self->oversampling_port);
|
||||||
if (oversampling != self->oversampling)
|
if (port_value == (int)self->oversampling)
|
||||||
|
return;
|
||||||
|
|
||||||
|
self->oversampling = (sfizz_oversampling_factor_t)port_value;
|
||||||
|
|
||||||
|
LV2_Atom_Int atom = {
|
||||||
|
.atom.type = self->sfizz_oversampling_uri,
|
||||||
|
.atom.size = sizeof(int),
|
||||||
|
.body = self->oversampling
|
||||||
|
};
|
||||||
|
if (self->worker->schedule_work(self->worker->handle,
|
||||||
|
lv2_atom_total_size((LV2_Atom *)&atom),
|
||||||
|
&atom) != LV2_WORKER_SUCCESS)
|
||||||
{
|
{
|
||||||
LV2_Atom_Int atom;
|
lv2_log_error(&self->logger, "[sfizz] There was an issue changing the oversampling factor\n");
|
||||||
atom.atom.type = self->sfizz_oversampling_uri;
|
|
||||||
atom.atom.size = sizeof(int);
|
|
||||||
atom.body = oversampling;
|
|
||||||
if (self->worker->schedule_work(self->worker->handle,
|
|
||||||
lv2_atom_total_size((LV2_Atom *)&atom),
|
|
||||||
&atom) != LV2_WORKER_SUCCESS)
|
|
||||||
{
|
|
||||||
lv2_log_error(&self->logger, "[sfizz] There was an issue changing the oversampling factor\n");
|
|
||||||
}
|
|
||||||
self->oversampling = oversampling;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -560,10 +578,11 @@ sfizz_lv2_check_preload_size(sfizz_plugin_t* self)
|
||||||
unsigned int preload_size = (int)*self->preload_port;
|
unsigned int preload_size = (int)*self->preload_port;
|
||||||
if (preload_size != self->preload_size)
|
if (preload_size != self->preload_size)
|
||||||
{
|
{
|
||||||
LV2_Atom_Int atom;
|
LV2_Atom_Int atom = {
|
||||||
atom.atom.type = self->sfizz_preload_size_uri;
|
.atom.type = self->sfizz_preload_size_uri,
|
||||||
atom.atom.size = sizeof(int);
|
.atom.size = sizeof(int),
|
||||||
atom.body = preload_size;
|
.body = preload_size
|
||||||
|
};
|
||||||
if (self->worker->schedule_work(self->worker->handle,
|
if (self->worker->schedule_work(self->worker->handle,
|
||||||
lv2_atom_total_size((LV2_Atom *)&atom),
|
lv2_atom_total_size((LV2_Atom *)&atom),
|
||||||
&atom) != LV2_WORKER_SUCCESS)
|
&atom) != LV2_WORKER_SUCCESS)
|
||||||
|
|
@ -580,13 +599,14 @@ sfizz_lv2_check_num_voices(sfizz_plugin_t* self)
|
||||||
int num_voices = (int)*self->polyphony_port;
|
int num_voices = (int)*self->polyphony_port;
|
||||||
if (num_voices != self->num_voices)
|
if (num_voices != self->num_voices)
|
||||||
{
|
{
|
||||||
LV2_Atom_Int num_voices_atom;
|
LV2_Atom_Int atom = {
|
||||||
num_voices_atom.atom.type = self->sfizz_num_voices_uri;
|
.atom.type = self->sfizz_num_voices_uri,
|
||||||
num_voices_atom.atom.size = sizeof(int);
|
.atom.size = sizeof(int),
|
||||||
num_voices_atom.body = num_voices;
|
.body = num_voices
|
||||||
|
};
|
||||||
if (self->worker->schedule_work(self->worker->handle,
|
if (self->worker->schedule_work(self->worker->handle,
|
||||||
lv2_atom_total_size((LV2_Atom *)&num_voices_atom),
|
lv2_atom_total_size((LV2_Atom *)&atom),
|
||||||
&num_voices_atom) != LV2_WORKER_SUCCESS)
|
&atom) != LV2_WORKER_SUCCESS)
|
||||||
{
|
{
|
||||||
lv2_log_error(&self->logger, "[sfizz] There was an issue changing the number of voices\n");
|
lv2_log_error(&self->logger, "[sfizz] There was an issue changing the number of voices\n");
|
||||||
}
|
}
|
||||||
|
|
@ -926,18 +946,15 @@ work(LV2_Handle instance,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reactivate checking for file changes
|
// Reactivate checking for file changes
|
||||||
LV2_Atom check_modification_atom;
|
LV2_Atom check_modification_atom = {
|
||||||
check_modification_atom.size = 0;
|
.size = 0,
|
||||||
check_modification_atom.type = self->sfizz_check_modification_uri;
|
.type = self->sfizz_check_modification_uri
|
||||||
|
};
|
||||||
respond(handle, lv2_atom_total_size(&check_modification_atom), &check_modification_atom);
|
respond(handle, lv2_atom_total_size(&check_modification_atom), &check_modification_atom);
|
||||||
}
|
}
|
||||||
else if (atom->type == self->sfizz_num_voices_uri)
|
else if (atom->type == self->sfizz_num_voices_uri)
|
||||||
{
|
{
|
||||||
const int num_voices = *(const int *)LV2_ATOM_BODY_CONST(atom);
|
const int num_voices = *(const int *)LV2_ATOM_BODY_CONST(atom);
|
||||||
if (sfizz_get_num_voices(self->synth) == num_voices) {
|
|
||||||
return LV2_WORKER_SUCCESS; // Nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
sfizz_set_num_voices(self->synth, num_voices);
|
sfizz_set_num_voices(self->synth, num_voices);
|
||||||
if (sfizz_get_num_voices(self->synth) == num_voices) {
|
if (sfizz_get_num_voices(self->synth) == num_voices) {
|
||||||
lv2_log_note(&self->logger, "[sfizz] Number of voices changed to: %d\n", num_voices);
|
lv2_log_note(&self->logger, "[sfizz] Number of voices changed to: %d\n", num_voices);
|
||||||
|
|
@ -948,9 +965,6 @@ work(LV2_Handle instance,
|
||||||
else if (atom->type == self->sfizz_preload_size_uri)
|
else if (atom->type == self->sfizz_preload_size_uri)
|
||||||
{
|
{
|
||||||
const unsigned int preload_size = *(const unsigned int *)LV2_ATOM_BODY_CONST(atom);
|
const unsigned int preload_size = *(const unsigned int *)LV2_ATOM_BODY_CONST(atom);
|
||||||
if (sfizz_get_preload_size(self->synth) == preload_size)
|
|
||||||
return LV2_WORKER_SUCCESS; // Nothing to do
|
|
||||||
|
|
||||||
sfizz_set_preload_size(self->synth, preload_size);
|
sfizz_set_preload_size(self->synth, preload_size);
|
||||||
if (sfizz_get_preload_size(self->synth) == preload_size) {
|
if (sfizz_get_preload_size(self->synth) == preload_size) {
|
||||||
lv2_log_note(&self->logger, "[sfizz] Preload size changed to: %d\n", preload_size);
|
lv2_log_note(&self->logger, "[sfizz] Preload size changed to: %d\n", preload_size);
|
||||||
|
|
@ -962,10 +976,6 @@ work(LV2_Handle instance,
|
||||||
{
|
{
|
||||||
const sfizz_oversampling_factor_t oversampling =
|
const sfizz_oversampling_factor_t oversampling =
|
||||||
*(const sfizz_oversampling_factor_t *)LV2_ATOM_BODY_CONST(atom);
|
*(const sfizz_oversampling_factor_t *)LV2_ATOM_BODY_CONST(atom);
|
||||||
if (sfizz_get_oversampling_factor(self->synth) == oversampling) {
|
|
||||||
return LV2_WORKER_SUCCESS; // Nothing to do
|
|
||||||
}
|
|
||||||
|
|
||||||
sfizz_set_oversampling_factor(self->synth, oversampling);
|
sfizz_set_oversampling_factor(self->synth, oversampling);
|
||||||
if (sfizz_get_oversampling_factor(self->synth) == oversampling) {
|
if (sfizz_get_oversampling_factor(self->synth) == oversampling) {
|
||||||
lv2_log_note(&self->logger, "[sfizz] Oversampling changed to: %d\n", oversampling);
|
lv2_log_note(&self->logger, "[sfizz] Oversampling changed to: %d\n", oversampling);
|
||||||
|
|
|
||||||
14
src/sfizz.h
14
src/sfizz.h
|
|
@ -247,7 +247,10 @@ SFIZZ_EXPORTED_API unsigned int sfizz_get_preload_size(sfizz_synth_t* synth);
|
||||||
/**
|
/**
|
||||||
* @brief Set the size of the preloaded data in number of floats (not
|
* @brief Set the size of the preloaded data in number of floats (not
|
||||||
* bytes). This will disable the callbacks for the duration of the
|
* bytes). This will disable the callbacks for the duration of the
|
||||||
* load.
|
* load. This function takes a lock ; prefer calling
|
||||||
|
* it out of the RT thread. It can also take a long time to return.
|
||||||
|
* If the new preload size is the same as the current one, it will
|
||||||
|
* release the lock immediately and exit.
|
||||||
*
|
*
|
||||||
* @param synth The synth.
|
* @param synth The synth.
|
||||||
* @param[in] preload_size The preload size.
|
* @param[in] preload_size The preload size.
|
||||||
|
|
@ -277,6 +280,11 @@ SFIZZ_EXPORTED_API sfizz_oversampling_factor_t sfizz_get_oversampling_factor(sfi
|
||||||
* to compensate for the memory increase, but the full loading will
|
* to compensate for the memory increase, but the full loading will
|
||||||
* need to take place anyway.
|
* need to take place anyway.
|
||||||
*
|
*
|
||||||
|
* This function takes a lock and disables the callback; prefer calling
|
||||||
|
* it out of the RT thread. It can also take a long time to return.
|
||||||
|
* If the new oversampling factor is the same as the current one, it will
|
||||||
|
* release the lock immediately and exit.
|
||||||
|
*
|
||||||
* @param synth The synth.
|
* @param synth The synth.
|
||||||
* @param[in] oversampling The oversampling factor.
|
* @param[in] oversampling The oversampling factor.
|
||||||
*
|
*
|
||||||
|
|
@ -301,6 +309,10 @@ SFIZZ_EXPORTED_API float sfizz_get_volume(sfizz_synth_t* synth);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the number of voices used by the synth.
|
* @brief Set the number of voices used by the synth.
|
||||||
|
* This function takes a lock and disables the callback; prefer calling
|
||||||
|
* it out of the RT thread. It can also take a long time to return.
|
||||||
|
* If the new number of voices is the same as the current one, it will
|
||||||
|
* release the lock immediately and exit.
|
||||||
*
|
*
|
||||||
* @param synth The synth.
|
* @param synth The synth.
|
||||||
* @param num_voices The number of voices.
|
* @param num_voices The number of voices.
|
||||||
|
|
|
||||||
|
|
@ -214,15 +214,34 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Change the number of voices (the polyphony).
|
* @brief Change the number of voices (the polyphony).
|
||||||
|
* This function takes a lock and disables the callback; prefer calling
|
||||||
|
* it out of the RT thread. It can also take a long time to return.
|
||||||
|
* If the new number of voices is the same as the current one, it will
|
||||||
|
* release the lock immediately and exit.
|
||||||
*
|
*
|
||||||
* @param numVoices The number of voices.
|
* @param numVoices The number of voices.
|
||||||
*/
|
*/
|
||||||
void setNumVoices(int numVoices) noexcept;
|
void setNumVoices(int numVoices) noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the oversampling factor to a new value. This will disable all callbacks
|
* @brief Set the oversampling factor to a new value.
|
||||||
* kill all the voices, and trigger a reloading of every file in the FilePool under
|
* It will kill all the voices, and trigger a reloading of every file in
|
||||||
* the new oversampling.
|
* the FilePool under the new oversampling.
|
||||||
|
*
|
||||||
|
* Increasing this value (up to x8 oversampling) improves the
|
||||||
|
* quality of the output at the expense of memory consumption and
|
||||||
|
* background loading speed. The main render path still uses the
|
||||||
|
* same linear interpolation algorithm and should not see its
|
||||||
|
* performance decrease, but the files are oversampled upon loading
|
||||||
|
* which increases the stress on the background loader and reduce
|
||||||
|
* the loading speed. You can tweak the size of the preloaded data
|
||||||
|
* to compensate for the memory increase, but the full loading will
|
||||||
|
* need to take place anyway.
|
||||||
|
*
|
||||||
|
* This function takes a lock and disables the callback; prefer calling
|
||||||
|
* it out of the RT thread. It can also take a long time to return.
|
||||||
|
* If the new oversampling factor is the same as the current one, it will
|
||||||
|
* release the lock immediately and exit.
|
||||||
*
|
*
|
||||||
* @param factor The oversampling factor.
|
* @param factor The oversampling factor.
|
||||||
*
|
*
|
||||||
|
|
@ -236,7 +255,11 @@ public:
|
||||||
int getOversamplingFactor() const noexcept;
|
int getOversamplingFactor() const noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the preloaded file size. This will disable the callback.
|
* @brief Set the preloaded file size.
|
||||||
|
* This function takes a lock and disables the callback; prefer calling
|
||||||
|
* it out of the RT thread. It can also take a long time to return.
|
||||||
|
* If the new preload size is the same as the current one, it will
|
||||||
|
* release the lock immediately and exit.
|
||||||
*
|
*
|
||||||
* @param preloadSize The preload size.
|
* @param preloadSize The preload size.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1054,6 +1054,11 @@ void sfz::Synth::setNumVoices(int numVoices) noexcept
|
||||||
{
|
{
|
||||||
ASSERT(numVoices > 0);
|
ASSERT(numVoices > 0);
|
||||||
const std::lock_guard<std::mutex> disableCallback { callbackGuard };
|
const std::lock_guard<std::mutex> disableCallback { callbackGuard };
|
||||||
|
|
||||||
|
// fast path
|
||||||
|
if (numVoices == this->numVoices)
|
||||||
|
return;
|
||||||
|
|
||||||
resetVoices(numVoices);
|
resetVoices(numVoices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1077,6 +1082,10 @@ void sfz::Synth::setOversamplingFactor(sfz::Oversampling factor) noexcept
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> disableCallback { callbackGuard };
|
const std::lock_guard<std::mutex> disableCallback { callbackGuard };
|
||||||
|
|
||||||
|
// fast path
|
||||||
|
if (factor == oversamplingFactor)
|
||||||
|
return;
|
||||||
|
|
||||||
for (auto& voice : voices)
|
for (auto& voice : voices)
|
||||||
voice->reset();
|
voice->reset();
|
||||||
|
|
||||||
|
|
@ -1094,6 +1103,10 @@ void sfz::Synth::setPreloadSize(uint32_t preloadSize) noexcept
|
||||||
{
|
{
|
||||||
const std::lock_guard<std::mutex> disableCallback { callbackGuard };
|
const std::lock_guard<std::mutex> disableCallback { callbackGuard };
|
||||||
|
|
||||||
|
// fast path
|
||||||
|
if (preloadSize == resources.filePool.getPreloadSize())
|
||||||
|
return;
|
||||||
|
|
||||||
resources.filePool.setPreloadSize(preloadSize);
|
resources.filePool.setPreloadSize(preloadSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -286,7 +286,11 @@ public:
|
||||||
*/
|
*/
|
||||||
int getNumVoices() const noexcept;
|
int getNumVoices() const noexcept;
|
||||||
/**
|
/**
|
||||||
* @brief Change the number of voices (the polyphony)
|
* @brief Change the number of voices (the polyphony).
|
||||||
|
* This function takes a lock and disables the callback; prefer calling
|
||||||
|
* it out of the RT thread. It can also take a long time to return.
|
||||||
|
* If the new number of voices is the same as the current one, it will
|
||||||
|
* release the lock immediately and exit.
|
||||||
*
|
*
|
||||||
* @param numVoices
|
* @param numVoices
|
||||||
*/
|
*/
|
||||||
|
|
@ -302,9 +306,13 @@ public:
|
||||||
void garbageCollect() noexcept;
|
void garbageCollect() noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the oversampling factor to a new value. This will disable all callbacks
|
* @brief Set the oversampling factor to a new value.
|
||||||
* kill all the voices, and trigger a reloading of every file in the FilePool under
|
* It will kill all the voices, and trigger a reloading of every file in
|
||||||
* the new oversampling.
|
* the FilePool under the new oversampling.
|
||||||
|
* This function takes a lock and disables the callback; prefer calling
|
||||||
|
* it out of the RT thread. It can also take a long time to return.
|
||||||
|
* If the new oversampling factor is the same as the current one, it will
|
||||||
|
* release the lock immediately and exit.
|
||||||
*
|
*
|
||||||
* @param factor
|
* @param factor
|
||||||
*/
|
*/
|
||||||
|
|
@ -318,7 +326,11 @@ public:
|
||||||
Oversampling getOversamplingFactor() const noexcept;
|
Oversampling getOversamplingFactor() const noexcept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set the preloaded file size. This will disable the callback.
|
* @brief Set the preloaded file size.
|
||||||
|
* This function takes a lock and disables the callback; prefer calling
|
||||||
|
* it out of the RT thread. It can also take a long time to return.
|
||||||
|
* If the new preload size is the same as the current one, it will
|
||||||
|
* release the lock immediately and exit.
|
||||||
*
|
*
|
||||||
* @param factor
|
* @param factor
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue