2026-07-21 02:06:45 +02:00
|
|
|
#pragma once
|
|
|
|
|
#include <juce_audio_processors/juce_audio_processors.h>
|
|
|
|
|
#include <juce_dsp/juce_dsp.h>
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
#include <cmath>
|
|
|
|
|
|
|
|
|
|
class SliceManager
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
struct Slice
|
|
|
|
|
{
|
|
|
|
|
int startSample;
|
|
|
|
|
int endSample;
|
2026-07-21 15:20:49 +02:00
|
|
|
int midiNote; // pitch class (0 = C, 1 = C#, ..., 11 = B)
|
2026-07-21 02:06:45 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
SliceManager();
|
|
|
|
|
|
|
|
|
|
void setSampleBuffer(juce::AudioBuffer<float>* buffer, double sampleRate);
|
|
|
|
|
void setSensitivity(float s);
|
|
|
|
|
void setBassGain(float g);
|
|
|
|
|
void setTrebleGain(float g);
|
|
|
|
|
|
|
|
|
|
void autoSlice();
|
|
|
|
|
void clearSlices();
|
|
|
|
|
void addSliceManual(int samplePos);
|
|
|
|
|
void removeSliceAt(int samplePos, int tolerance = 5);
|
|
|
|
|
void moveSlice(int fromSample, int toSample);
|
|
|
|
|
|
|
|
|
|
void trimStart(int sample);
|
|
|
|
|
void trimEnd(int sample);
|
|
|
|
|
|
|
|
|
|
void undo();
|
|
|
|
|
void redo();
|
|
|
|
|
bool canUndo() const;
|
|
|
|
|
bool canRedo() const;
|
|
|
|
|
|
2026-07-21 23:15:37 +02:00
|
|
|
std::vector<Slice> getSlices() const;
|
|
|
|
|
int getNumSlices() const;
|
|
|
|
|
Slice getSlice(int index) const;
|
|
|
|
|
|
|
|
|
|
void setSlices(const std::vector<Slice>& newSlices);
|
2026-07-21 02:06:45 +02:00
|
|
|
|
|
|
|
|
int findSliceIndexForSample(int samplePos) const;
|
|
|
|
|
|
|
|
|
|
juce::AudioBuffer<float>* getMutableBuffer() { return sampleBuffer; }
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
void sortSlices();
|
|
|
|
|
void assignMidiNotes();
|
|
|
|
|
void pushHistory();
|
|
|
|
|
void truncateHistory();
|
|
|
|
|
|
2026-07-21 23:15:37 +02:00
|
|
|
mutable juce::CriticalSection mutex;
|
2026-07-21 02:06:45 +02:00
|
|
|
std::vector<Slice> slices;
|
|
|
|
|
std::vector<std::vector<Slice>> undoStack;
|
|
|
|
|
std::vector<std::vector<Slice>> redoStack;
|
|
|
|
|
static constexpr size_t maxHistory = 50;
|
|
|
|
|
juce::AudioBuffer<float>* sampleBuffer = nullptr;
|
|
|
|
|
double currentSampleRate = 44100.0;
|
|
|
|
|
|
|
|
|
|
float sensitivity = 0.5f;
|
|
|
|
|
float bassGain = 1.0f;
|
|
|
|
|
float trebleGain = 1.0f;
|
|
|
|
|
|
|
|
|
|
std::vector<float> computeEnvelope(const float* channelData, int numSamples);
|
|
|
|
|
std::vector<float> lowpassFilter(const std::vector<float>& input, float cutoffHz);
|
|
|
|
|
std::vector<float> highpassFilter(const std::vector<float>& input, float cutoffHz);
|
|
|
|
|
std::vector<float> detectOnsets(const std::vector<float>& envelope, float threshold);
|
|
|
|
|
};
|