Extra samples in the wavetables, to help interpolations
This commit is contained in:
parent
62ba2113c7
commit
c57ab54c24
2 changed files with 42 additions and 7 deletions
|
|
@ -143,17 +143,18 @@ WavetableRange WavetableRange::getRangeForFrequency(float f)
|
|||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
constexpr unsigned WavetableMulti::_tableExtra;
|
||||
|
||||
WavetableMulti WavetableMulti::createForHarmonicProfile(
|
||||
const HarmonicProfile& hp, unsigned tableSize, double refSampleRate)
|
||||
{
|
||||
WavetableMulti wm;
|
||||
constexpr unsigned multiSize = wm.multiSize();
|
||||
constexpr unsigned multiSize = WavetableMulti::multiSize();
|
||||
|
||||
// amplitude to match ARIA's default generator output
|
||||
constexpr double amplitude = 0.25;
|
||||
|
||||
wm._tableSize = tableSize;
|
||||
wm._multiData.reset(new float[tableSize * multiSize]);
|
||||
wm.allocateStorage(tableSize);
|
||||
|
||||
for (unsigned m = 0; m < multiSize; ++m) {
|
||||
WavetableRange range = WavetableRange::getRangeForOctave(m);
|
||||
|
|
@ -165,13 +166,34 @@ WavetableMulti WavetableMulti::createForHarmonicProfile(
|
|||
// Therefore it's desired to cut harmonics at C=0.5*Fs/Fs'=0.5*Fs/(F*N).
|
||||
double cutoff = (0.5 * refSampleRate / tableSize) / freq;
|
||||
|
||||
float* ptr = &wm._multiData[m * tableSize];
|
||||
float* ptr = const_cast<float*>(wm.getTablePointer(m));
|
||||
absl::Span<float> table(ptr, tableSize);
|
||||
|
||||
hp.generate(table, amplitude, cutoff);
|
||||
}
|
||||
|
||||
wm.fillExtra();
|
||||
|
||||
return wm;
|
||||
}
|
||||
|
||||
void WavetableMulti::allocateStorage(unsigned tableSize)
|
||||
{
|
||||
_multiData.reset(new float[(tableSize + _tableExtra) * multiSize()]());
|
||||
_tableSize = tableSize;
|
||||
}
|
||||
|
||||
void WavetableMulti::fillExtra()
|
||||
{
|
||||
unsigned tableSize = _tableSize;
|
||||
constexpr unsigned tableExtra = _tableExtra;
|
||||
constexpr unsigned multiSize = WavetableMulti::multiSize();
|
||||
|
||||
for (unsigned m = 0; m < multiSize; ++m) {
|
||||
float* ptr = const_cast<float*>(getTablePointer(m));
|
||||
for (unsigned i = 0; i < tableExtra; ++i)
|
||||
ptr[tableSize + i] = ptr[i % tableSize];
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace sfz
|
||||
|
|
|
|||
|
|
@ -86,9 +86,7 @@ public:
|
|||
// get the N-th table in the multisample
|
||||
absl::Span<const float> getTable(unsigned index) const
|
||||
{
|
||||
unsigned size = _tableSize;
|
||||
const float* ptr = &_multiData[index * _tableSize];
|
||||
return { ptr, size };
|
||||
return { getTablePointer(index), _tableSize };
|
||||
}
|
||||
|
||||
// get the table which is adequate for a given playback frequency
|
||||
|
|
@ -104,9 +102,24 @@ public:
|
|||
const HarmonicProfile& hp, unsigned tableSize, double refSampleRate = 44100.0);
|
||||
|
||||
private:
|
||||
// get a pointer to the beginning of the N-th table
|
||||
const float* getTablePointer(unsigned index) const
|
||||
{
|
||||
return &_multiData[index * (_tableSize + _tableExtra)];
|
||||
}
|
||||
|
||||
// allocate the internal data for tables of the given size
|
||||
void allocateStorage(unsigned tableSize);
|
||||
|
||||
// fill extra data at table ends with repetitions of the first samples
|
||||
void fillExtra();
|
||||
|
||||
// length of each individual table of the multisample
|
||||
unsigned _tableSize = 0;
|
||||
|
||||
// number X of extra elements, for safe interpolations up to X-th order.
|
||||
static constexpr unsigned _tableExtra = 4;
|
||||
|
||||
// internal storage, having `multiSize` rows and `tableSize` columns.
|
||||
std::unique_ptr<float[]> _multiData;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue