feat(bank_panel): docked bank grid with LICE waveform thumbnails (M5 Wave A)
Docked SWELL window toggled by a new action, drawing the current bank as per-sample min/max thumbnails (PCM_source + peaks) with an in-memory cache. Pure grid-layout/cache-key math in bank_grid (tested). Renames peaks::Sample -> AudioSample to avoid colliding with bank_model::Sample.
This commit is contained in:
+14
-9
@@ -13,18 +13,23 @@
|
||||
|
||||
namespace reasampler {
|
||||
|
||||
// Canonical in-memory sample type. `float` is REAPER's native audio buffer format
|
||||
// (its render/PCM_source callbacks hand back interleaved 32-bit float), so peaks
|
||||
// consumes that directly with no lossy conversion. If a capture ever lands as a
|
||||
// different depth, the caller converts to float at the boundary — the thumbnail
|
||||
// core stays single-typed.
|
||||
using Sample = float;
|
||||
// Canonical in-memory audio-sample type. `float` is REAPER's native audio buffer
|
||||
// format (its render/PCM_source callbacks hand back interleaved 32-bit float), so
|
||||
// peaks consumes that directly with no lossy conversion. If a capture ever lands
|
||||
// as a different depth, the caller converts to float at the boundary — the
|
||||
// thumbnail core stays single-typed.
|
||||
//
|
||||
// NAMED AudioSample, not `Sample`: `reasampler::Sample` is already bank_model's
|
||||
// metadata struct. A `using Sample = float` here would collide at namespace scope
|
||||
// wherever both headers are visible (the bank_panel module includes both). The
|
||||
// audio-domain name also reads more precisely — this is one PCM sample value.
|
||||
using AudioSample = float;
|
||||
|
||||
// One bin of a channel's envelope: the extremes of every sample that fell in it.
|
||||
// min <= max always. For an empty bin (more bins than frames), both are 0.
|
||||
struct MinMax {
|
||||
Sample min = 0.0f;
|
||||
Sample max = 0.0f;
|
||||
AudioSample min = 0.0f;
|
||||
AudioSample max = 0.0f;
|
||||
|
||||
bool operator==(const MinMax& o) const { return min == o.min && max == o.max; }
|
||||
};
|
||||
@@ -56,7 +61,7 @@ using Envelope = std::vector<ChannelEnvelope>;
|
||||
// binCount == 0 -> per channel: an empty bin vector.
|
||||
// channelCount == 0 -> an empty envelope (no channels).
|
||||
// frameCount == 0 -> per channel: binCount bins, all {0, 0}.
|
||||
Envelope computeEnvelope(const std::vector<Sample>& interleaved,
|
||||
Envelope computeEnvelope(const std::vector<AudioSample>& interleaved,
|
||||
std::size_t channelCount,
|
||||
std::size_t frameCount,
|
||||
std::size_t binCount);
|
||||
|
||||
Reference in New Issue
Block a user