Skip to content

Commit ef8171f

Browse files
tucktuckg00seclaude
andcommitted
v0.8.2: Fix null pointer crash on sample load, remove unused theme colours, click-to-cycle choices
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent cefddad commit ef8171f

8 files changed

Lines changed: 57 additions & 103 deletions

File tree

README.md

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -103,30 +103,6 @@ To create a custom theme:
103103
4. Place the file in the themes folder listed above
104104
5. Restart the plugin — your theme will appear in the theme selector (right-click the header bar)
105105

106-
**Theme properties:**
107-
108-
| Key | Purpose |
109-
|-----|---------|
110-
| `background` | Window background |
111-
| `waveformBg` | Waveform area background |
112-
| `darkBar` | Slice control bar / action panel background |
113-
| `header` | Header bar background |
114-
| `foreground` | Primary text colour |
115-
| `gridLine` | Waveform grid lines |
116-
| `separator` | Horizontal separator lines |
117-
| `waveform` | Waveform draw colour |
118-
| `sliceRegion` | Slice region fill |
119-
| `sliceRegionSelected` | Selected slice region fill |
120-
| `selectionOverlay` | Selected slice translucent overlay |
121-
| `accent` | Accent colour (labels, highlights) |
122-
| `lockActive` | Locked/overridden parameter indicator |
123-
| `lockInactive` | Unlocked/inherited parameter indicator |
124-
| `button` | Button background |
125-
| `buttonHover` | Button hover background |
126-
| `slice1``slice16` | Slice colour palette (assigned to new slices in order) |
127-
128-
Any missing key falls back to the dark theme default. Lines starting with `#` are comments.
129-
130106
## Install
131107

132108
Download the latest release zip for your platform from the [Releases](https://github.com/tucktuckg00se/INTERSECT/releases) page and extract it.

src/audio/SampleData.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ float SampleData::getInterpolatedSample (double pos, int channel) const
7777
return 0.0f;
7878

7979
auto* data = buffer.getReadPointer (channel);
80+
if (data == nullptr)
81+
return 0.0f;
8082
return data[ipos] + (data[ipos + 1] - data[ipos]) * frac;
8183
}
8284

@@ -94,9 +96,15 @@ void SampleData::buildMipmaps()
9496
return;
9597
}
9698

99+
if (buffer.getNumChannels() < 1)
100+
return;
101+
97102
const float* dataL = buffer.getReadPointer (0);
98103
const float* dataR = buffer.getNumChannels() > 1 ? buffer.getReadPointer (1) : dataL;
99104

105+
if (dataL == nullptr)
106+
return;
107+
100108
static constexpr int kBlockSizes[kNumMipmapLevels] = { 64, 512, 4096 };
101109

102110
for (int level = 0; level < kNumMipmapLevels; ++level)

src/ui/HeaderBar.cpp

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -457,41 +457,17 @@ void HeaderBar::mouseDown (const juce::MouseEvent& e)
457457
return;
458458
}
459459

460-
// Choice popup (Algorithm or Grain Mode)
460+
// Choice: click to cycle
461461
if (cell.isChoice)
462462
{
463-
juce::PopupMenu menu;
464-
if (cell.paramId == ParamIds::defaultGrainMode)
465-
{
466-
menu.addItem (1, "Fast");
467-
menu.addItem (2, "Normal");
468-
menu.addItem (3, "Smooth");
469-
}
470-
else if (cell.paramId == ParamIds::defaultLoop)
471-
{
472-
menu.addItem (1, "OFF");
473-
menu.addItem (2, "LOOP");
474-
menu.addItem (3, "PING-PONG");
475-
}
476-
else
463+
if (auto* p = processor.apvts.getParameter (cell.paramId))
477464
{
478-
menu.addItem (1, "Repitch");
479-
menu.addItem (2, "Stretch");
480-
menu.addItem (3, "Bungee");
465+
int current = (int) processor.apvts.getRawParameterValue (cell.paramId)->load();
466+
int maxVal = (int) cell.maxVal;
467+
int next = (current + 1) > maxVal ? 0 : current + 1;
468+
p->setValueNotifyingHost (p->convertTo0to1 ((float) next));
481469
}
482-
auto* topLvl = getTopLevelComponent();
483-
float ms = IntersectLookAndFeel::getMenuScale();
484-
menu.showMenuAsync (juce::PopupMenu::Options().withTargetComponent (this)
485-
.withParentComponent (topLvl)
486-
.withStandardItemHeight ((int) (24 * ms)),
487-
[this, paramId = cell.paramId] (int result) {
488-
if (result > 0)
489-
{
490-
if (auto* p = processor.apvts.getParameter (paramId))
491-
p->setValueNotifyingHost (p->convertTo0to1 ((float) (result - 1)));
492-
repaint();
493-
}
494-
});
470+
repaint();
495471
return;
496472
}
497473

src/ui/SliceControlBar.cpp

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -399,44 +399,40 @@ void SliceControlBar::mouseDown (const juce::MouseEvent& e)
399399
return;
400400
}
401401

402-
// Choice popup (Algorithm or Grain Mode)
402+
// Choice: click to cycle
403403
if (cell.isChoice)
404404
{
405-
juce::PopupMenu menu;
406-
if (cell.fieldId == IntersectProcessor::FieldGrainMode)
407-
{
408-
menu.addItem (1, "Fast");
409-
menu.addItem (2, "Normal");
410-
menu.addItem (3, "Smooth");
411-
}
412-
else if (cell.fieldId == IntersectProcessor::FieldLoop)
413-
{
414-
menu.addItem (1, "OFF");
415-
menu.addItem (2, "LOOP");
416-
menu.addItem (3, "PING-PONG");
417-
}
418-
else
405+
int idx = processor.sliceManager.selectedSlice;
406+
if (idx >= 0 && idx < processor.sliceManager.getNumSlices())
419407
{
420-
menu.addItem (1, "Repitch");
421-
menu.addItem (2, "Stretch");
422-
menu.addItem (3, "Bungee");
408+
const auto& s = processor.sliceManager.getSlice (idx);
409+
int current = 0;
410+
int maxVal = (int) cell.maxVal;
411+
412+
if (cell.fieldId == IntersectProcessor::FieldAlgorithm)
413+
{
414+
int gAlgo = (int) processor.apvts.getRawParameterValue (ParamIds::defaultAlgorithm)->load();
415+
current = (s.lockMask & kLockAlgorithm) ? s.algorithm : gAlgo;
416+
}
417+
else if (cell.fieldId == IntersectProcessor::FieldGrainMode)
418+
{
419+
int gGM = (int) processor.apvts.getRawParameterValue (ParamIds::defaultGrainMode)->load();
420+
current = (s.lockMask & kLockGrainMode) ? s.grainMode : gGM;
421+
}
422+
else if (cell.fieldId == IntersectProcessor::FieldLoop)
423+
{
424+
int gLM = (int) processor.apvts.getRawParameterValue (ParamIds::defaultLoop)->load();
425+
current = (s.lockMask & kLockLoop) ? s.loopMode : gLM;
426+
}
427+
428+
int next = (current + 1) > maxVal ? 0 : current + 1;
429+
IntersectProcessor::Command cmd;
430+
cmd.type = IntersectProcessor::CmdSetSliceParam;
431+
cmd.intParam1 = cell.fieldId;
432+
cmd.floatParam1 = (float) next;
433+
processor.pushCommand (cmd);
434+
repaint();
423435
}
424-
auto* topLvl = getTopLevelComponent();
425-
float ms = IntersectLookAndFeel::getMenuScale();
426-
menu.showMenuAsync (juce::PopupMenu::Options().withTargetComponent (this)
427-
.withParentComponent (topLvl)
428-
.withStandardItemHeight ((int) (24 * ms)),
429-
[this, fieldId = cell.fieldId] (int result) {
430-
if (result > 0)
431-
{
432-
IntersectProcessor::Command cmd;
433-
cmd.type = IntersectProcessor::CmdSetSliceParam;
434-
cmd.intParam1 = fieldId;
435-
cmd.floatParam1 = (float) (result - 1);
436-
processor.pushCommand (cmd);
437-
repaint();
438-
}
439-
});
440436
return;
441437
}
442438

src/ui/ThemeData.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ struct ThemeData
1111
juce::Colour foreground;
1212
juce::Colour header;
1313
juce::Colour waveform;
14-
juce::Colour sliceRegion;
15-
juce::Colour sliceRegionSelected;
1614
juce::Colour selectionOverlay;
1715
juce::Colour lockActive;
1816
juce::Colour lockInactive;
@@ -34,8 +32,6 @@ struct ThemeData
3432
t.foreground = juce::Colour (0xFFCCD0D8);
3533
t.header = juce::Colour (0xFF0D0D14);
3634
t.waveform = juce::Colour::fromFloatRGBA (0.70f, 0.78f, 0.85f, 1.0f);
37-
t.sliceRegion = juce::Colour (0xFF2A2A35);
38-
t.sliceRegionSelected = juce::Colour (0xFF3A3A50);
3935
t.selectionOverlay = juce::Colour::fromFloatRGBA (0.25f, 0.35f, 0.55f, 1.0f);
4036
t.lockActive = juce::Colour::fromFloatRGBA (0.90f, 0.35f, 0.22f, 1.0f);
4137
t.lockInactive = juce::Colour::fromFloatRGBA (0.30f, 0.30f, 0.34f, 1.0f);
@@ -73,8 +69,6 @@ struct ThemeData
7369
t.foreground = juce::Colour (0xFF1A1A2E);
7470
t.header = juce::Colour (0xFFE0E0EC);
7571
t.waveform = juce::Colour (0xFF2A4060);
76-
t.sliceRegion = juce::Colour (0xFFD0D0DD);
77-
t.sliceRegionSelected = juce::Colour (0xFFB8B8CC);
7872
t.selectionOverlay = juce::Colour (0xFF8090B8);
7973
t.lockActive = juce::Colour (0xFFCC4422);
8074
t.lockInactive = juce::Colour (0xFF9999A8);
@@ -136,8 +130,6 @@ struct ThemeData
136130
else if (key == "foreground") t.foreground = parseHex (val);
137131
else if (key == "header") t.header = parseHex (val);
138132
else if (key == "waveform") t.waveform = parseHex (val);
139-
else if (key == "sliceRegion") t.sliceRegion = parseHex (val);
140-
else if (key == "sliceRegionSelected") t.sliceRegionSelected = parseHex (val);
141133
else if (key == "selectionOverlay") t.selectionOverlay = parseHex (val);
142134
else if (key == "lockActive") t.lockActive = parseHex (val);
143135
else if (key == "lockInactive") t.lockInactive = parseHex (val);
@@ -171,8 +163,6 @@ struct ThemeData
171163
s << "foreground: " << colourToHex (foreground) << "\n";
172164
s << "header: " << colourToHex (header) << "\n";
173165
s << "waveform: " << colourToHex (waveform) << "\n";
174-
s << "sliceRegion: " << colourToHex (sliceRegion) << "\n";
175-
s << "sliceRegionSelected: " << colourToHex (sliceRegionSelected) << "\n";
176166
s << "selectionOverlay: " << colourToHex (selectionOverlay) << "\n";
177167
s << "lockActive: " << colourToHex (lockActive) << "\n";
178168
s << "lockInactive: " << colourToHex (lockInactive) << "\n";

src/ui/WaveformCache.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,21 @@ void WaveformCache::rebuild (const juce::AudioBuffer<float>& buffer,
1919
peaks.resize ((size_t) widthPixels);
2020
float samplesPerPixel = (float) visibleLen / (float) widthPixels;
2121

22+
if (buffer.getNumChannels() < 1)
23+
{
24+
peaks.clear();
25+
return;
26+
}
27+
2228
const float* dataL = buffer.getReadPointer (0);
2329
const float* dataR = buffer.getNumChannels() > 1 ? buffer.getReadPointer (1) : dataL;
2430

31+
if (dataL == nullptr)
32+
{
33+
peaks.clear();
34+
return;
35+
}
36+
2537
if (samplesPerPixel < 1.0f)
2638
{
2739
// Sub-sample zoom: interpolate at exact fractional positions

themes/dark.intersectstyle

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ separator: 33333f # horizontal separator lines
2525

2626
# Waveform & slices
2727
waveform: b2c6d8 # waveform draw colour
28-
sliceRegion: 2a2a35 # slice region fill
29-
sliceRegionSelected: 3a3a50 # selected slice region fill
3028
selectionOverlay: 3f598c # selected slice translucent overlay
3129

3230
# Controls

themes/light.intersectstyle

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ separator: c0c0cc # horizontal separator lines
2525

2626
# Waveform & slices
2727
waveform: 2a4060 # waveform draw colour
28-
sliceRegion: d0d0dd # slice region fill
29-
sliceRegionSelected: b8b8cc # selected slice region fill
3028
selectionOverlay: 8090b8 # selected slice translucent overlay
3129

3230
# Controls

0 commit comments

Comments
 (0)