Skip to content

Commit

Permalink
Finish BLLT loading from wav files
Browse files Browse the repository at this point in the history
  • Loading branch information
FigBug committed Aug 21, 2023
1 parent 44c8c45 commit d7d361b
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 5 deletions.
84 changes: 83 additions & 1 deletion examples/Demo/Source/MainComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1657,7 +1657,7 @@ struct WavetableDemo : public juce::Component
if (int size = gin::getWavetableSize (mb); size > 0)
{
auto is = new juce::MemoryInputStream (mb.getData(), mb.getSize(), false);
auto reader = juce::WavAudioFormat().createReaderFor (is, true);
auto reader = std::unique_ptr<juce::AudioFormatReader> (juce::WavAudioFormat().createReaderFor (is, true));

if (reader)
{
Expand Down Expand Up @@ -1716,9 +1716,91 @@ struct WavetableDemo : public juce::Component
std::unique_ptr<gin::WTOscillator> osc;
};

//==============================================================================
struct BLLTDemo : public juce::Component
{
BLLTDemo()
{
setName ("BLLT");

juce::AudioSampleBuffer buf (1, 2048);

auto w = buf.getWritePointer (0);
for (auto i = 0; i < 2048; i++)
w[i] = tables.processSquare (0.0f, i / 2048.0f);

bllt.loadFromBuffer (buf, 44100, 12);
}

void paint (juce::Graphics& g) override
{

//
// From formula
//
{
auto area = getLocalBounds();
auto note = 0.5f;
for (int i = 0; i < bllt.tables.size(); i++)
{
auto rc = area.removeFromTop (getHeight() / bllt.tables.size()).reduced (3);

juce::Path p;

for (auto x = 0; x < 2048; x++)
{
auto fx = x / 2048.0f * rc.getWidth() + rc.getX();
auto fy = tables.processSquare (note, x / 2048.0f) * rc.getHeight() / 2.0f + rc.getCentreY();

if (x == 0)
p.startNewSubPath (fx, fy);
else
p.lineTo (fx, fy);
}

g.setColour (juce::Colours::green);
g.strokePath (p, juce::PathStrokeType (1.0f));

note += 12.0f;
}
}

//
// From wavefile
//
{
auto area = getLocalBounds();
for (int i = 0; i < bllt.tables.size(); i++)
{
auto& t = *bllt.tables[i];
auto rc = area.removeFromTop (getHeight() / bllt.tables.size()).reduced (3);

juce::Path p;

for (auto x = 0; x < 2048; x++)
{
auto fx = x / 2048.0f * rc.getWidth() + rc.getX();
auto fy = t.processSample (x / 2048.0f) * rc.getHeight() / 2.0f + rc.getCentreY();

if (x == 0)
p.startNewSubPath (fx, fy);
else
p.lineTo (fx, fy);
}
g.setColour (juce::Colours::yellow);
g.strokePath (p, juce::PathStrokeType (1.0f));
}
}
}

gin::BandLimitedLookupTables tables {44100, 12, 2048};
gin::BandLimitedLookupTable bllt;
};

//==============================================================================
MainContentComponent::MainContentComponent()
{
demoComponents.add (new BLLTDemo());
demoComponents.add (new WavetableDemo());
demoComponents.add (new CatenaryDemo());
demoComponents.add (new EllipseDemo());
Expand Down
31 changes: 29 additions & 2 deletions modules/gin_dsp/dsp/gin_bandlimitedlookuptable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ void BandLimitedLookupTable::loadFromBuffer (juce::AudioSampleBuffer& buffer, do

notesPerTable = notesPerTable_;

juce::dsp::FFT fft (juce::roundToInt (std::log2 (sz)));
jassert (fft.getSize() == sz);

for (double note = notesPerTable + 0.5; note < 127.0; note += notesPerTable)
{
auto noteFreq = getMidiNoteInHertz (note);
Expand All @@ -133,10 +136,34 @@ void BandLimitedLookupTable::loadFromBuffer (juce::AudioSampleBuffer& buffer, do
}
else
{
auto index2Freq = [&] (int i)
{
return float (i * (sampleRate / sz));
};

auto d = buffer.getReadPointer (0);
auto ratio = noteFreq / baseFreq;

std::vector<juce::dsp::Complex<float>> time;
std::vector<juce::dsp::Complex<float>> freq;

time.resize (sz);
freq.resize (sz);

for (auto i = 0; i < sz; i++)
time[i] = { d[i], 0.0f };

fft.perform (time.data(), freq.data(), false);

for (auto i = 0; i < sz; i++)
if (index2Freq (i) * ratio > sampleRate / 2)
freq[i] = {0.0f, 0.0f};

fft.perform (freq.data(), time.data(), true);

auto func = [&] (float phase)
{
auto data = buffer.getReadPointer (0);
return data[int (phase * float(sz)) % sz];
return time[int (phase * float(sz)) % sz].real();
};

tables.add (new juce::dsp::LookupTableTransform<float> (func, 0.0f, 1.0f, (size_t) sz + 1));
Expand Down
4 changes: 2 additions & 2 deletions modules/gin_dsp/dsp/gin_wtoscillators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void WTOscillator::process (float noteL, float noteR, const Params& params, juce
void WTOscillator::processAdding (float note, const Params& params, juce::AudioSampleBuffer& buffer)
{
if (bllt.size() == 0) return;
int ti = std::min (bllt.size() - 1, int (float ( bllt.size() ) * params.pw));
int ti = std::min (bllt.size() - 1, int (float (bllt.size()) * params.pw));

float freq = float (std::min (sampleRate / 2.0, 440.0 * std::pow (2.0, (note - 69.0) / 12.0)));
float delta = 1.0f / (float ((1.0f / freq) * sampleRate));
Expand All @@ -96,7 +96,7 @@ void WTOscillator::processAdding (float note, const Params& params, juce::AudioS
void WTOscillator::processAdding (float noteL, float noteR, const Params& params, juce::AudioSampleBuffer& buffer)
{
if (bllt.size() == 0) return;
int ti = std::min (bllt.size() - 1, int (float ( bllt.size() ) * params.pw));
int ti = std::min (bllt.size() - 1, int (float (bllt.size()) * params.pw));

float freqL = float (std::min (sampleRate / 2.0, 440.0 * std::pow (2.0, (noteL - 69.0) / 12.0)));
float freqR = float (std::min (sampleRate / 2.0, 440.0 * std::pow (2.0, (noteR - 69.0) / 12.0)));
Expand Down

0 comments on commit d7d361b

Please sign in to comment.