-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Concepts Usage, Exploration One (#101)
Add some code concepts for types and strategies we've used throughout the codebase for common APIs like sample rate, ote to pitch, db to linear. rather than using this commit to consilidate all the names of all the clients, use this to enumerate all of them into a concept and start using that concept. Once we've propagated that, we can quickly and easily see where we need to consolidate names with the compiler.
- Loading branch information
Showing
5 changed files
with
388 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
include/sst/basic-blocks/concepts/envelope_modulator_rate.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* sst-basic-blocks - an open source library of core audio utilities | ||
* built by Surge Synth Team. | ||
* | ||
* Provides a collection of tools useful on the audio thread for blocks, | ||
* modulation, etc... or useful for adapting code to multiple environments. | ||
* | ||
* Copyright 2023, various authors, as described in the GitHub | ||
* transaction log. Parts of this code are derived from similar | ||
* functions original in Surge or ShortCircuit. | ||
* | ||
* sst-basic-blocks is released under the GNU General Public Licence v3 | ||
* or later (GPL-3.0-or-later). The license is found in the "LICENSE" | ||
* file in the root of this repository, or at | ||
* https://www.gnu.org/licenses/gpl-3.0.en.html. | ||
* | ||
* A very small number of explicitly chosen header files can also be | ||
* used in an MIT/BSD context. Please see the README.md file in this | ||
* repo or the comments in the individual files. Only headers with an | ||
* explicit mention that they are dual licensed may be copied and reused | ||
* outside the GPL3 terms. | ||
* | ||
* All source in sst-basic-blocks available at | ||
* https://github.com/surge-synthesizer/sst-basic-blocks | ||
*/ | ||
|
||
#ifndef INCLUDE_SST_BASIC_BLOCKS_CONCEPTS_ENVELOPE_MODULATOR_RATE_H | ||
#define INCLUDE_SST_BASIC_BLOCKS_CONCEPTS_ENVELOPE_MODULATOR_RATE_H | ||
|
||
#include <concepts> | ||
#include <type_traits> | ||
|
||
namespace sst::basic_blocks::concepts | ||
{ | ||
|
||
/* | ||
* Envelope Rate Linear No-Wrap is defined as | ||
* block size * 2^f / sample rate | ||
*/ | ||
template <typename T> | ||
concept has_envelope_rate_linear_nowrap = requires(T *t, float f) { | ||
{ | ||
t->envelope_rate_linear_nowrap(f) | ||
} -> std::convertible_to<float>; | ||
}; | ||
|
||
template <typename T> | ||
concept providesModulatorDPhase = has_envelope_rate_linear_nowrap<T>; | ||
|
||
template <typename T> | ||
requires(providesModulatorDPhase<T>) | ||
inline double getModulatorDPhase(T *t, float f) | ||
{ | ||
return t->envelope_rate_linear_nowrap(f); | ||
} | ||
} // namespace sst::basic_blocks::concepts | ||
|
||
#endif // SHORTCIRCUITXT_ENVELOPE_MODULATOR_RATE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
/* | ||
* sst-basic-blocks - an open source library of core audio utilities | ||
* built by Surge Synth Team. | ||
* | ||
* Provides a collection of tools useful on the audio thread for blocks, | ||
* modulation, etc... or useful for adapting code to multiple environments. | ||
* | ||
* Copyright 2023, various authors, as described in the GitHub | ||
* transaction log. Parts of this code are derived from similar | ||
* functions original in Surge or ShortCircuit. | ||
* | ||
* sst-basic-blocks is released under the GNU General Public Licence v3 | ||
* or later (GPL-3.0-or-later). The license is found in the "LICENSE" | ||
* file in the root of this repository, or at | ||
* https://www.gnu.org/licenses/gpl-3.0.en.html. | ||
* | ||
* A very small number of explicitly chosen header files can also be | ||
* used in an MIT/BSD context. Please see the README.md file in this | ||
* repo or the comments in the individual files. Only headers with an | ||
* explicit mention that they are dual licensed may be copied and reused | ||
* outside the GPL3 terms. | ||
* | ||
* All source in sst-basic-blocks available at | ||
* https://github.com/surge-synthesizer/sst-basic-blocks | ||
*/ | ||
|
||
#ifndef INCLUDE_SST_BASIC_BLOCKS_CONCEPTS_SAMPLE_RATE_H | ||
#define INCLUDE_SST_BASIC_BLOCKS_CONCEPTS_SAMPLE_RATE_H | ||
|
||
#include <concepts> | ||
#include <type_traits> | ||
|
||
namespace sst::basic_blocks::concepts | ||
{ | ||
template <typename T> | ||
concept has_samplerate_member = requires(T *t) { | ||
{ | ||
t->samplerate | ||
} -> std::convertible_to<float>; | ||
}; | ||
|
||
template <typename T> | ||
concept has_sampleRate_member = requires(T *t) { | ||
{ | ||
t->sampleRate | ||
} -> std::convertible_to<float>; | ||
}; | ||
|
||
template <typename T> | ||
concept has_getSampleRate_method = requires(T *t) { | ||
{ | ||
t->getSampleRate() | ||
} -> std::convertible_to<float>; | ||
}; | ||
|
||
template <typename T> | ||
concept has_staticGetSampleRate_method = requires(T *t) { | ||
{ | ||
T::getSampleRate(t) | ||
} -> std::convertible_to<float>; | ||
}; | ||
|
||
template <typename T> | ||
concept has_dsamplerate_member = requires(T *t) { | ||
{ | ||
t->dsamplerate | ||
} -> std::same_as<double>; | ||
}; | ||
|
||
template <typename T> | ||
concept has_samplerate_inv_member = requires(T *t) { | ||
{ | ||
t->samplerate_inv | ||
} -> std::convertible_to<float>; | ||
}; | ||
|
||
template <typename T> | ||
concept has_sampleRateInv_member = requires(T *t) { | ||
{ | ||
t->sampleRateInv | ||
} -> std::convertible_to<float>; | ||
}; | ||
|
||
template <typename T> | ||
concept has_getSampleRateInv_method = requires(T *t) { | ||
{ | ||
t->getSampleRateInv() | ||
} -> std::convertible_to<float>; | ||
}; | ||
|
||
template <typename T> | ||
concept has_dsamplerate_inv_member = requires(T *t) { | ||
{ | ||
t->dsamplerate_inv | ||
} -> std::same_as<double>; | ||
}; | ||
|
||
template <typename T> | ||
concept has_staticGetSampleRateInv_method = requires(T *s) { | ||
{ | ||
T::getSampleRateInv(s) | ||
} -> std::floating_point; | ||
}; | ||
|
||
template <typename T> | ||
concept has_staticSampleRateInv_method = requires(T *s) { | ||
{ | ||
T::sampleRateInv(s) | ||
} -> std::floating_point; | ||
}; | ||
template <typename T> | ||
concept supportsSampleRate = has_samplerate_member<T> || has_sampleRate_member<T> || | ||
has_getSampleRate_method<T> || has_staticGetSampleRate_method<T>; | ||
|
||
template <typename T> | ||
concept supportsSampleRateInv = | ||
has_samplerate_inv_member<T> || has_sampleRateInv_member<T> || has_getSampleRateInv_method<T> || | ||
has_staticGetSampleRateInv_method<T> || has_staticSampleRateInv_method<T>; | ||
|
||
template <typename T> | ||
concept supportsDoubleSampleRate = has_dsamplerate_member<T> && has_dsamplerate_inv_member<T>; | ||
|
||
template <typename T> | ||
inline float getSampleRate(T *t) | ||
requires(supportsSampleRate<T>) | ||
{ | ||
if constexpr (has_samplerate_member<T>) | ||
return t->samplerate; | ||
else if constexpr (has_sampleRate_member<T>) | ||
return t->sampleRate; | ||
else if constexpr (has_getSampleRate_method<T>) | ||
return t->getSampleRate(); | ||
else if constexpr (has_staticGetSampleRate_method<T>) | ||
return T::getSampleRate(t); | ||
} | ||
|
||
template <typename T> | ||
inline float getSampleRateInv(T *t) | ||
requires(supportsSampleRateInv<T>) | ||
{ | ||
if constexpr (has_samplerate_inv_member<T>) | ||
return t->samplerate_inv; | ||
else if constexpr (has_sampleRateInv_member<T>) | ||
return t->sampleRateInv; | ||
else if constexpr (has_getSampleRateInv_method<T>) | ||
return t->getSampleRateInv(); | ||
else if constexpr (has_staticGetSampleRateInv_method<T>) | ||
return T::getSampleRateInv(t); | ||
else if constexpr (has_staticSampleRateInv_method<T>) | ||
return T::sampleRateInv(t); | ||
} | ||
|
||
} // namespace sst::basic_blocks::concepts | ||
|
||
#endif // SHORTCIRCUITXT_SAMPLE_RATE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,157 @@ | ||
/* | ||
* sst-basic-blocks - an open source library of core audio utilities | ||
* built by Surge Synth Team. | ||
* | ||
* Provides a collection of tools useful on the audio thread for blocks, | ||
* modulation, etc... or useful for adapting code to multiple environments. | ||
* | ||
* Copyright 2023, various authors, as described in the GitHub | ||
* transaction log. Parts of this code are derived from similar | ||
* functions original in Surge or ShortCircuit. | ||
* | ||
* sst-basic-blocks is released under the GNU General Public Licence v3 | ||
* or later (GPL-3.0-or-later). The license is found in the "LICENSE" | ||
* file in the root of this repository, or at | ||
* https://www.gnu.org/licenses/gpl-3.0.en.html. | ||
* | ||
* A very small number of explicitly chosen header files can also be | ||
* used in an MIT/BSD context. Please see the README.md file in this | ||
* repo or the comments in the individual files. Only headers with an | ||
* explicit mention that they are dual licensed may be copied and reused | ||
* outside the GPL3 terms. | ||
* | ||
* All source in sst-basic-blocks available at | ||
* https://github.com/surge-synthesizer/sst-basic-blocks | ||
*/ | ||
|
||
#ifndef INCLUDE_SST_BASIC_BLOCKS_CONCEPTS_UNIT_CONVERSIONS_H | ||
#define INCLUDE_SST_BASIC_BLOCKS_CONCEPTS_UNIT_CONVERSIONS_H | ||
|
||
#include <concepts> | ||
#include <type_traits> | ||
#include <cassert> | ||
|
||
/* | ||
* All the names and flavorts we evern given these are here. | ||
* We obviously need to trim these down once we have everything | ||
* going. That's tedious but doable because we can just | ||
* remove the constraint from the concept and the if once we | ||
* are there. | ||
*/ | ||
namespace sst::basic_blocks::concepts | ||
{ | ||
template <typename T> | ||
concept has_note_to_pitch_ignoring_tuning = requires(T *s, float f) { | ||
{ | ||
s->note_to_pitch_ignoring_tuning(f) | ||
} -> std::floating_point; | ||
}; | ||
|
||
template <typename T> | ||
concept has_noteToPitchIgnoringTuning = requires(T *s, float f) { | ||
{ | ||
s->noteToPitchIgnoringTuning(f) | ||
} -> std::floating_point; | ||
}; | ||
|
||
template <typename T> | ||
concept has_noteToPitch = requires(T *s, float f) { | ||
{ | ||
s->noteToPitch(f) | ||
} -> std::floating_point; | ||
}; | ||
|
||
template <typename T> | ||
concept has_staticNoteToPitchIgnoringTuning = requires(T *s, float f) { | ||
{ | ||
T::noteToPitchIgnoringTuning(s, f) | ||
} -> std::floating_point; | ||
}; | ||
|
||
template <typename T> | ||
concept has_staticEqualNoteToPitch = requires(T *s, float f) { | ||
{ | ||
T::equalNoteToPitch(s, f) | ||
} -> std::floating_point; | ||
}; | ||
|
||
template <typename T> | ||
concept providesNoteToPitch = | ||
has_noteToPitchIgnoringTuning<T> || has_note_to_pitch_ignoring_tuning<T> || | ||
has_noteToPitch<T> || has_staticNoteToPitchIgnoringTuning<T> || has_staticEqualNoteToPitch<T>; | ||
|
||
template <typename T> | ||
requires(providesNoteToPitch<T>) | ||
inline float convertNoteToPitch(T *t, float n) | ||
{ | ||
if constexpr (has_note_to_pitch_ignoring_tuning<T>) | ||
{ | ||
return t->note_to_pitch_ignoring_tuning(n); | ||
} | ||
else if constexpr (has_noteToPitchIgnoringTuning<T>) | ||
{ | ||
return t->noteToPitchIgnoringTuning(n); | ||
} | ||
else if constexpr (has_noteToPitch<T>) | ||
{ | ||
return t->noteToPitch(n); | ||
} | ||
else if constexpr (has_staticNoteToPitchIgnoringTuning<T>) | ||
{ | ||
return T::noteToPitchIgnoringTuning(t, n); | ||
} | ||
else if constexpr (has_staticEqualNoteToPitch<T>) | ||
{ | ||
return T::equalNoteToPitch(t, n); | ||
} | ||
|
||
assert(false); | ||
return 0; | ||
} | ||
|
||
template <typename T> | ||
concept has_db_to_linear = requires(T *s, float f) { | ||
{ | ||
s->db_to_linear(f) | ||
} -> std::floating_point; | ||
}; | ||
|
||
template <typename T> | ||
concept has_dbToLinear = requires(T *s, float f) { | ||
{ | ||
s->dbToLinear(f) | ||
} -> std::floating_point; | ||
}; | ||
|
||
template <typename T> | ||
concept has_staticDbToLinear = requires(T *s, float f) { | ||
{ | ||
T::dbToLinear(s, f) | ||
} -> std::floating_point; | ||
}; | ||
|
||
template <typename T> | ||
concept providesDbToLinear = has_dbToLinear<T> || has_db_to_linear<T> || has_staticDbToLinear<T>; | ||
|
||
template <typename T> | ||
requires(providesDbToLinear<T>) | ||
inline float convertDbToLinear(T *t, float n) | ||
{ | ||
if constexpr (has_db_to_linear<T>) | ||
{ | ||
return t->db_to_linear(n); | ||
} | ||
else if constexpr (has_dbToLinear<T>) | ||
{ | ||
return t->dbToLinear(n); | ||
} | ||
else if constexpr (has_staticDbToLinear<T>) | ||
{ | ||
return T::dbToLinear(t, n); | ||
} | ||
assert(false); | ||
return 0; | ||
} | ||
|
||
} // namespace sst::basic_blocks::concepts | ||
#endif // SHORTCIRCUITXT_UNIT_CONVERSIONS_H |
Oops, something went wrong.