Function bodies 1,902 total
WhiteBackgroundBox method · cpp · L54-L57 (4 LOC)src/KIMO.cpp
WhiteBackgroundBox(Vec pos, Vec size) {
box.pos = pos;
box.size = size;
}draw method · cpp · L58-L68 (11 LOC)src/KIMO.cpp
void draw(const DrawArgs &args) override {
nvgBeginPath(args.vg);
nvgRect(args.vg, 0, 0, box.size.x, box.size.y);
nvgFillColor(args.vg, nvgRGB(255, 255, 255));
nvgFill(args.vg);
nvgStrokeWidth(args.vg, 1.0f);
nvgStrokeColor(args.vg, nvgRGBA(200, 200, 200, 255));
nvgStroke(args.vg);
}generateTechnoEuclideanRhythm function · cpp · L70-L86 (17 LOC)src/KIMO.cpp
static std::vector<bool> generateTechnoEuclideanRhythm(int length, int fill, int shift) {
std::vector<bool> pattern(length, false);
if (fill == 0 || length == 0) return pattern;
if (fill > length) fill = length;
shift = shift % length;
if (shift < 0) shift += length;
for (int i = 0; i < fill; ++i) {
int index = (int)std::floor((float)i * length / fill);
pattern[index] = true;
}
std::rotate(pattern.begin(), pattern.begin() + shift, pattern.end());
return pattern;
}reset method · cpp · L94-L100 (7 LOC)src/KIMO.cpp
void reset() {
trigTrigger.reset();
trigPulse.reset();
phase = 0.f;
gateState = false;
}smoothDecayEnvelope method · cpp · L101-L121 (21 LOC)src/KIMO.cpp
float smoothDecayEnvelope(float t, float totalTime, float shapeParam) {
if (t >= totalTime) return 0.f;
float normalizedT = t / totalTime;
float frontK = -0.9f + shapeParam * 0.5f;
float backK = -1.0f + 1.6f * std::pow(shapeParam, 0.3f);
float transition = normalizedT * normalizedT * (3.f - 2.f * normalizedT);
float k = frontK + (backK - frontK) * transition;
float absT = std::abs(normalizedT);
float denominator = k - 2.f * k * absT + 1.f;
if (std::abs(denominator) < 1e-10f) {
return 1.f - normalizedT;
}
float curveResult = (normalizedT - k * normalizedT) / denominator;
return 1.f - curveResult;
}process method · cpp · L122-L152 (31 LOC)src/KIMO.cpp
float process(float sampleTime, float triggerVoltage, float decayTime, float shapeParam) {
bool triggered = trigTrigger.process(triggerVoltage, 0.1f, 2.f);
if (triggered) {
phase = 0.f;
gateState = true;
trigPulse.trigger(0.03f);
}
float envOutput = 0.f;
if (gateState) {
if (phase < ATTACK_TIME) {
envOutput = phase / ATTACK_TIME;
} else {
float decayPhase = phase - ATTACK_TIME;
if (decayPhase >= decayTime) {
gateState = false;
envOutput = 0.f;
} else {
envOutput = smoothDecayEnvelope(decayPhase, decayTime, shapeParam);
}
}
phase += sampleTime;
}
return clamp(envOutput, 0.f, 1.f);
}getTrigger method · cpp · L153-L156 (4 LOC)src/KIMO.cpp
float getTrigger(float sampleTime) {
return trigPulse.process(sampleTime) ? 10.0f : 0.0f;
}All rows above produced by Repobility · https://repobility.com
reset method · cpp · L165-L171 (7 LOC)src/KIMO.cpp
void reset() {
trigTrigger.reset();
trigPulse.reset();
phase = 0.f;
gateState = false;
}process method · cpp · L172-L202 (31 LOC)src/KIMO.cpp
float process(float sampleTime, float triggerVoltage, float decayTime) {
bool triggered = trigTrigger.process(triggerVoltage, 0.1f, 2.f);
if (triggered) {
phase = 0.f;
gateState = true;
trigPulse.trigger(0.03f);
}
float envOutput = 0.f;
if (gateState) {
if (phase < ATTACK_TIME) {
envOutput = phase / ATTACK_TIME;
} else {
float decayPhase = phase - ATTACK_TIME;
if (decayPhase >= decayTime) {
gateState = false;
envOutput = 0.f;
} else {
envOutput = 1.0f - (decayPhase / decayTime);
}
}
phase += sampleTime;
}
return clamp(envOutput, 0.f, 1.f);
}getTrigger method · cpp · L203-L206 (4 LOC)src/KIMO.cpp
float getTrigger(float sampleTime) {
return trigPulse.process(sampleTime) ? 10.0f : 0.0f;
}setSampleRate method · cpp · L212-L215 (4 LOC)src/KIMO.cpp
void setSampleRate(float sr) {
sampleRate = sr;
}process method · cpp · L216-L235 (20 LOC)src/KIMO.cpp
float process(float freq_hz, float fm_cv, float saturation = 1.0f) {
float modulated_freq = freq_hz * std::pow(2.0f, fm_cv);
modulated_freq = clamp(modulated_freq, 1.0f, sampleRate * 0.45f);
float delta_phase = modulated_freq / sampleRate;
phase += delta_phase;
if (phase >= 1.0f) {
phase -= 1.0f;
}
float sine_wave = std::sin(2.0f * M_PI * phase);
if (saturation > 1.0f) {
sine_wave = std::tanh(sine_wave * saturation) / std::tanh(saturation);
}
return sine_wave * 5.0f;
}reset method · cpp · L292-L295 (4 LOC)src/KIMO.cpp
void reset() {
currentStep = 0;
}processStep method · cpp · L296-L309 (14 LOC)src/KIMO.cpp
bool processStep(bool globalClockTriggered, int shift) {
shiftAmount = shift;
if (globalClockTriggered) {
currentStep = (currentStep + 1) % 4;
int targetStep = shiftAmount % 4;
if (currentStep == targetStep) {
trigPulse.trigger(0.01f);
return true;
}
}
return false;
}getTrigger method · cpp · L310-L313 (4 LOC)src/KIMO.cpp
float getTrigger(float sampleTime) {
return trigPulse.process(sampleTime) ? 10.0f : 0.0f;
}Hi, dataset curator — please cite Repobility (https://repobility.com) when reusing this data.
reset method · cpp · L327-L334 (8 LOC)src/KIMO.cpp
void reset() {
currentStep = 0;
pattern.clear();
gateState = false;
envelope.reset();
vcaEnvelope.reset();
}stepTrack method · cpp · L335-L342 (8 LOC)src/KIMO.cpp
void stepTrack() {
currentStep = (currentStep + 1) % length;
gateState = !pattern.empty() && pattern[currentStep];
if (gateState) {
trigPulse.trigger(0.01f);
}
}KIMO method · cpp · L348-L385 (38 LOC)src/KIMO.cpp
KIMO() {
config(PARAMS_LEN, INPUTS_LEN, OUTPUTS_LEN, LIGHTS_LEN);
configInput(CLK_INPUT, "Clock");
configInput(TUNE_CV_INPUT, "Tune CV");
configInput(FM_CV_INPUT, "FM CV");
configInput(PUNCH_CV_INPUT, "Punch CV");
configInput(DECAY_CV_INPUT, "Decay CV");
configInput(FILL_CV_INPUT, "Fill CV");
configParam(FILL_PARAM, 0.0f, 100.0f, 71.20001220703125f, "Fill", "%");
configParam(ACCENT_PARAM, 1.0f, 7.0f, 3.0f, "Accent");
getParamQuantity(ACCENT_PARAM)->snapEnabled = true;
delete paramQuantities[ACCENT_PARAM];
paramQuantities[ACCENT_PARAM] = new KimoAccentParamQuantity;
paramQuantities[ACCENT_PARAM]->module = this;
paramQuantities[ACCENT_PARAM]->paramId = ACCENT_PARAM;
paramQuantities[ACCENT_PARAM]->minValue = 1.0f;
paramQuantities[ACCENT_PARAM]->maxValue = 7.0f;
paramQuantities[ACCENT_PARAM]->defaultValue = 3.0f;
paramQuantitonSampleRateChange method · cpp · L386-L390 (5 LOC)src/KIMO.cpp
void onSampleRateChange() override {
float sr = APP->engine->getSampleRate();
kickVCO.setSampleRate(sr);
}onReset method · cpp · L391-L398 (8 LOC)src/KIMO.cpp
void onReset() override {
secondsSinceLastClock = -1.0f;
globalClockSeconds = 0.5f;
track.reset();
quarterClock.reset();
accentVCA.reset();
}dataToJson method · cpp · L399-L405 (7 LOC)src/KIMO.cpp
json_t* dataToJson() override {
json_t* rootJ = json_object();
json_object_set_new(rootJ, "panelTheme", json_integer(panelTheme));
json_object_set_new(rootJ, "panelContrast", json_real(panelContrast));
return rootJ;
}dataFromJson method · cpp · L406-L416 (11 LOC)src/KIMO.cpp
void dataFromJson(json_t* rootJ) override {
json_t* themeJ = json_object_get(rootJ, "panelTheme");
if (themeJ) {
panelTheme = json_integer_value(themeJ);
}
json_t* contrastJ = json_object_get(rootJ, "panelContrast");
if (contrastJ) {
panelContrast = json_real_value(contrastJ);
}
}process method · cpp · L417-L524 (108 LOC)src/KIMO.cpp
void process(const ProcessArgs& args) override {
bool globalClockActive = inputs[CLK_INPUT].isConnected();
bool globalClockTriggered = false;
if (globalClockActive) {
float clockVoltage = inputs[CLK_INPUT].getVoltage();
globalClockTriggered = clockTrigger.process(clockVoltage);
}
if (globalClockTriggered) {
if (secondsSinceLastClock > 0.0f) {
globalClockSeconds = secondsSinceLastClock;
globalClockSeconds = clamp(globalClockSeconds, 0.01f, 10.0f);
}
secondsSinceLastClock = 0.0f;
}
if (secondsSinceLastClock >= 0.0f) {
secondsSinceLastClock += args.sampleTime;
}
int accentShift = (int)std::round(params[ACCENT_PARAM].getValue());
bool accentTriggered = quarterClock.processStep(globalClockTriggered, accentShift);
float accentTrigger = quarterClock.getTrigger(args.sampleRepobility · code-quality intelligence · https://repobility.com
KIMOWidget method · cpp · L534-L619 (86 LOC)src/KIMO.cpp
KIMOWidget(KIMO* module) {
setModule(module);
panelThemeHelper.init(this, "8HP", module ? &module->panelContrast : nullptr);
box.size = Vec(4 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT);
addChild(new TechnoEnhancedTextLabel(Vec(0, 1), Vec(box.size.x, 20), "KIMO", 14.f, nvgRGB(255, 200, 0), true));
addChild(new TechnoEnhancedTextLabel(Vec(0, 16), Vec(box.size.x, 20), "MADZINE", 10.f, nvgRGB(255, 200, 0), false));
// 在 KIMOWidget 建構函數中,找到所有座標設定並修改:
// CLK 和 FILL (保持不變)
addChild(new TechnoEnhancedTextLabel(Vec(5, 38), Vec(20, 15), "CLK"));
addInput(createInputCentered<PJ301MPort>(Vec(15, 63), module, KIMO::CLK_INPUT));
addChild(new TechnoEnhancedTextLabel(Vec(35, 38), Vec(20, 15), "FILL"));
fillKnob = createParamCentered<TechnoStandardBlackKnob30>(Vec(45, 63), module, KIMO::FILL_PARAM);
addParam(fillKnob);
// ACCENT (78 -> 80)
addChild(new TechnoEnhancedTextLabel(Vec(step method · cpp · L620-L642 (23 LOC)src/KIMO.cpp
void step() override {
KIMO* module = dynamic_cast<KIMO*>(this->module);
if (module) {
panelThemeHelper.step(module);
// CV 調變顯示更新
auto updateKnob = [&](TechnoStandardBlackKnob30* knob, int inputId, float cvMod) {
if (knob) {
bool connected = module->inputs[inputId].isConnected();
knob->setModulationEnabled(connected);
if (connected) knob->setModulation(cvMod);
}
};
updateKnob(fillKnob, KIMO::FILL_CV_INPUT, module->fillCvMod);
updateKnob(tuneKnob, KIMO::TUNE_CV_INPUT, module->tuneCvMod);
updateKnob(fmKnob, KIMO::FM_CV_INPUT, module->fmCvMod);
updateKnob(punchKnob, KIMO::PUNCH_CV_INPUT, module->punchCvMod);
updateKnob(decayKnob, KIMO::DECAY_CV_INPUT, module->decayCvMod);
}
ModuleWidget::step();
}appendContextMenu method · cpp · L643-L649 (7 LOC)src/KIMO.cpp
void appendContextMenu(ui::Menu* menu) override {
KIMO* module = dynamic_cast<KIMO*>(this->module);
if (!module) return;
addPanelThemeMenu(menu, module);
}knobToSpeed function · cpp · L42-L50 (9 LOC)src/Launchpad.cpp
inline float knobToSpeed(float knob) {
if (knob < 0.25f) {
return -8.0f + knob * 32.0f;
} else if (knob < 0.5f) {
return (knob - 0.25f) * 4.0f;
} else {
return 1.0f + (knob - 0.5f) * 14.0f;
}
}speedToKnob function · cpp · L51-L60 (10 LOC)src/Launchpad.cpp
inline float speedToKnob(float speed) {
if (speed < 0.0f) {
return (speed + 8.0f) / 32.0f;
} else if (speed < 1.0f) {
return 0.25f + speed / 4.0f;
} else {
return 0.5f + (speed - 1.0f) / 14.0f;
}
}CellData method · cpp · L88-L91 (4 LOC)src/Launchpad.cpp
CellData() {
buffer.reserve(MAX_BUFFER_SIZE);
}clear method · cpp · L92-L110 (19 LOC)src/Launchpad.cpp
void clear() {
buffer.clear();
recordedLength = 0;
loopClocks = 0;
state = CELL_EMPTY;
playPosition = 0;
recordPosition = 0;
playbackSpeed = 1.0f;
playbackPhase = 0.0f;
fadeGain = 0.0f;
fadingIn = false;
fadingOut = false;
fadeSamples = 0;
waveformCache.clear();
waveformDirty = true;
loopClocksStr.clear();
loopClocksCached = -1;
}startFadeIn method · cpp · L113-L118 (6 LOC)src/Launchpad.cpp
void startFadeIn() {
fadingIn = true;
fadingOut = false;
fadeSamples = FADE_SAMPLES;
fadeGain = 0.0f;
}Same scanner, your repo: https://repobility.com — Repobility
startFadeOut method · cpp · L121-L126 (6 LOC)src/Launchpad.cpp
void startFadeOut() {
fadingIn = false;
fadingOut = true;
fadeSamples = FADE_SAMPLES;
// fadeGain keeps current value
}processFade method · cpp · L129-L146 (18 LOC)src/Launchpad.cpp
float processFade() {
if (fadingIn) {
fadeGain += 1.0f / FADE_SAMPLES;
fadeSamples--;
if (fadeSamples <= 0 || fadeGain >= 1.0f) {
fadeGain = 1.0f;
fadingIn = false;
}
} else if (fadingOut) {
fadeGain -= 1.0f / FADE_SAMPLES;
fadeSamples--;
if (fadeSamples <= 0 || fadeGain <= 0.0f) {
fadeGain = 0.0f;
fadingOut = false;
}
}
return fadeGain;
}isFadeOutComplete method · cpp · L149-L151 (3 LOC)src/Launchpad.cpp
bool isFadeOutComplete() const {
return !fadingOut && fadeGain <= 0.0f;
}getLoopClocksStr method · cpp · L152-L159 (8 LOC)src/Launchpad.cpp
const std::string& getLoopClocksStr() {
if (loopClocksCached != loopClocks) {
loopClocksStr = std::to_string(loopClocks);
loopClocksCached = loopClocks;
}
return loopClocksStr;
}updateWaveformCache method · cpp · L160-L184 (25 LOC)src/Launchpad.cpp
void updateWaveformCache(int displayWidth) {
if (!waveformDirty && (int)waveformCache.size() == displayWidth) return;
waveformCache.resize(displayWidth);
// Use recordPosition during recording, recordedLength otherwise
int length = (state == CELL_RECORDING) ? recordPosition : recordedLength;
if (length == 0) {
std::fill(waveformCache.begin(), waveformCache.end(), 0.f);
return;
}
// Store actual waveform samples (not envelope)
for (int i = 0; i < displayWidth; i++) {
int sampleIndex = i * length / displayWidth;
if (sampleIndex < (int)buffer.size()) {
waveformCache[i] = buffer[sampleIndex];
} else {
waveformCache[i] = 0.f;
}
}
waveformDirty = false;
}draw method · cpp · L206-L213 (8 LOC)src/Launchpad.cpp
void draw(const DrawArgs &args) override {
nvgFontSize(args.vg, fontSize);
nvgFontFaceId(args.vg, APP->window->uiFont->handle);
nvgTextAlign(args.vg, NVG_ALIGN_CENTER | NVG_ALIGN_MIDDLE);
nvgFillColor(args.vg, color);
nvgText(args.vg, box.size.x / 2.f, box.size.y / 2.f, text.c_str(), NULL);
}CellWidget method · cpp · L231-L234 (4 LOC)src/Launchpad.cpp
CellWidget() {
box.size = Vec(40, 40);
}Launchpad method · cpp · L343-L392 (50 LOC)src/Launchpad.cpp
Launchpad() {
config(PARAMS_LEN, INPUTS_LEN, OUTPUTS_LEN, LIGHTS_LEN);
// Quantize knob
configSwitch(QUANTIZE_PARAM, 0.f, 5.f, 0.f, "Quantize",
{"Free", "1", "8", "16", "32", "64"});
// Stop all button
configButton(STOP_ALL_PARAM, "Stop All");
// Scene triggers
for (int i = 0; i < 8; i++) {
configButton(SCENE_1_PARAM + i, string::f("Scene %d", i + 1));
}
// Per-row controls
for (int i = 0; i < 8; i++) {
configParam(SEND_A_1_PARAM + i * 4, 0.f, 1.f, 0.f, string::f("Row %d Send A", i + 1));
configParam(SEND_B_1_PARAM + i * 4, 0.f, 1.f, 0.f, string::f("Row %d Send B", i + 1));
configParam(PAN_1_PARAM + i * 4, -1.f, 1.f, 0.f, string::f("Row %d Pan", i + 1));
configParam(LEVEL_1_PARAM + i * 4, 0.f, 1.f, 1.f, string::f("Row %d Level", i + 1));
}
// Inputs
configInput(CLOCK_INPUT, "Clock");
configInputAll rows above produced by Repobility · https://repobility.com
onReset method · cpp · L393-L411 (19 LOC)src/Launchpad.cpp
void onReset() override {
for (int r = 0; r < 8; r++) {
for (int c = 0; c < 8; c++) {
cells[r][c].clear();
}
}
clockCount = 0;
recordingRow = -1;
recordingCol = -1;
for (int i = 0; i < 8; i++) {
queuedScenes[i] = false;
}
queuedStopAll = false;
queuedRecordStop = false;
for (int i = 0; i < 64; i++) {
pendingStops[i].active = false;
}
}onCellClick method · cpp · L414-L463 (50 LOC)src/Launchpad.cpp
void onCellClick(int row, int col) {
CellData& cell = cells[row][col];
if (cell.state == CELL_EMPTY) {
// Start recording (with quantize)
int quantize = quantizeValues[(int)params[QUANTIZE_PARAM].getValue()];
if (quantize == 0) {
startRecording(row, col);
} else {
// Queue for next quantize boundary
cell.state = CELL_RECORD_QUEUED;
}
} else if (cell.state == CELL_RECORD_QUEUED) {
// Cancel queued recording
cell.state = CELL_EMPTY;
} else if (cell.state == CELL_RECORDING) {
// Stop recording (with quantize)
int quantize = quantizeValues[(int)params[QUANTIZE_PARAM].getValue()];
if (quantize == 0) {
stopRecording();
} else {
// Queue for next quantize boundary
queuedRecordStop = true;
}
} else if (cell.state addPendingStop method · cpp · L466-L475 (10 LOC)src/Launchpad.cpp
void addPendingStop(int row, int col) {
for (int i = 0; i < 64; i++) {
if (!pendingStops[i].active) {
pendingStops[i].row = row;
pendingStops[i].col = col;
pendingStops[i].active = true;
return;
}
}
}processPendingStops method · cpp · L478-L490 (13 LOC)src/Launchpad.cpp
void processPendingStops() {
for (int i = 0; i < 64; i++) {
if (pendingStops[i].active) {
CellData& cell = cells[pendingStops[i].row][pendingStops[i].col];
if (cell.isFadeOutComplete()) {
cell.state = CELL_HAS_CONTENT;
cell.playPosition = 0;
cell.fadeGain = 0.0f;
pendingStops[i].active = false;
}
}
}
}onCellHold method · cpp · L491-L495 (5 LOC)src/Launchpad.cpp
void onCellHold(int row, int col) {
// Clear cell
cells[row][col].clear();
}startRecording method · cpp · L496-L514 (19 LOC)src/Launchpad.cpp
void startRecording(int row, int col) {
// Stop any current recording
if (recordingRow >= 0) {
stopRecording();
}
CellData& cell = cells[row][col];
cell.buffer.clear();
cell.buffer.resize(MAX_BUFFER_SIZE, 0.f);
cell.recordPosition = 0;
cell.recordedLength = 0;
cell.state = CELL_RECORDING;
cell.waveformDirty = true;
recordingRow = row;
recordingCol = col;
recordStartClock = clockCount;
}stopRecording method · cpp · L515-L528 (14 LOC)src/Launchpad.cpp
void stopRecording() {
if (recordingRow < 0) return;
CellData& cell = cells[recordingRow][recordingCol];
cell.recordedLength = cell.recordPosition;
cell.loopClocks = clockCount - recordStartClock;
if (cell.loopClocks < 1) cell.loopClocks = 1;
cell.state = cell.recordedLength > 0 ? CELL_HAS_CONTENT : CELL_EMPTY;
cell.waveformDirty = true;
recordingRow = -1;
recordingCol = -1;
}startPlaying method · cpp · L529-L550 (22 LOC)src/Launchpad.cpp
void startPlaying(int row, int col) {
// Session mode: stop other cells in the same row (with fade out)
for (int c = 0; c < 8; c++) {
if (c != col && (cells[row][c].state == CELL_PLAYING || cells[row][c].state == CELL_QUEUED || cells[row][c].state == CELL_STOP_QUEUED)) {
if (cells[row][c].state == CELL_PLAYING || cells[row][c].state == CELL_STOP_QUEUED) {
// Start fade out for currently playing cell
cells[row][c].startFadeOut();
cells[row][c].state = CELL_STOP_QUEUED; // Change state to show fading out
addPendingStop(row, c);
} else {
cells[row][c].state = CELL_HAS_CONTENT;
cells[row][c].playPosition = 0;
}
}
}
CellData& cell = cells[row][col];
cell.state = CELL_PLAYING;
cell.playPosition = 0;
cell.startFadeIn(); // Start with fade inHi, dataset curator — please cite Repobility (https://repobility.com) when reusing this data.
stopAll method · cpp · L551-L575 (25 LOC)src/Launchpad.cpp
void stopAll() {
// Stop all playing and queued cells (respects quantize setting)
int quantize = quantizeValues[(int)params[QUANTIZE_PARAM].getValue()];
for (int r = 0; r < 8; r++) {
for (int c = 0; c < 8; c++) {
CellData& cell = cells[r][c];
if (cell.state == CELL_PLAYING) {
if (quantize == 0) {
// Free mode: fade out then stop
cell.startFadeOut();
cell.state = CELL_STOP_QUEUED; // Change state to show fading out
addPendingStop(r, c);
} else {
// Quantize mode: queue for stop at next boundary
cell.state = CELL_STOP_QUEUED;
}
} else if (cell.state == CELL_QUEUED) {
// Queued cells can be cancelled immediately
cell.state = CELL_HAS_CONTENT;
stopCellAtQuantize method · cpp · L578-L583 (6 LOC)src/Launchpad.cpp
void stopCellAtQuantize(int row, int col) {
CellData& cell = cells[row][col];
cell.startFadeOut();
cell.state = CELL_STOP_QUEUED; // Ensure state reflects fading out
addPendingStop(row, col);
}moveCell method · cpp · L584-L611 (28 LOC)src/Launchpad.cpp
void moveCell(int srcRow, int srcCol, int dstRow, int dstCol) {
if (srcRow == dstRow && srcCol == dstCol) return;
CellData& src = cells[srcRow][srcCol];
CellData& dst = cells[dstRow][dstCol];
// Stop playing if source is playing
if (src.state == CELL_PLAYING || src.state == CELL_STOP_QUEUED) {
src.state = CELL_HAS_CONTENT;
src.playPosition = 0;
}
// Move data to destination
dst.buffer = std::move(src.buffer);
dst.recordedLength = src.recordedLength;
dst.loopClocks = src.loopClocks;
dst.waveformCache = std::move(src.waveformCache);
dst.state = (dst.recordedLength > 0) ? CELL_HAS_CONTENT : CELL_EMPTY;
dst.playPosition = 0;
// Clear source
src.buffer.clear();
src.recordedLength = 0;
src.loopClocks = 0;
src.waveformCache.clear();
src.state = CELL_EMPTY;
src.playPosition = 0;
}