Browse Source

Refactor Peaks, disable Peaks

tags/v0.6.0
Andrew Belt 7 years ago
parent
commit
ba6b22e5e3
2 changed files with 196 additions and 206 deletions
  1. +1
    -1
      src/AudibleInstruments.cpp
  2. +195
    -205
      src/Peaks.cpp

+ 1
- 1
src/AudibleInstruments.cpp View File

@@ -21,5 +21,5 @@ void init(rack::Plugin *p) {
p->addModel(modelBlinds);
p->addModel(modelVeils);
p->addModel(modelFrames);
p->addModel(modelPeaks);
// p->addModel(modelPeaks);
}

+ 195
- 205
src/Peaks.cpp View File

@@ -53,6 +53,32 @@ static const uint16_t kAdcThresholdUnlocked = 1 << (16 - 10); // 10 bits
static const uint16_t kAdcThresholdLocked = 1 << (16 - 8); // 8 bits


// Global scope, so variables can be accessed by process() function.
int16_t gOutputBuffer[peaks::kBlockSize];
int16_t gBrightness[2] = {0, 0};


static void set_led_brightness(int channel, int16_t value) {
gBrightness[channel] = value;
}

// File scope because of IOBuffer function signature.
// It cannot refer to a member function of class Peaks().
static void process(peaks::IOBuffer::Block* block, size_t size) {
for (size_t i = 0; i < peaks::kNumChannels; ++i) {
// TODO
// processors[i].Process(block->input[i], gOutputBuffer, size);
set_led_brightness(i, gOutputBuffer[0]);
for (size_t j = 0; j < size; ++j) {
// From calibration_data.h, shifting signed to unsigned values.
int32_t shifted_value = 32767 + static_cast<int32_t>(gOutputBuffer[j]);
CONSTRAIN(shifted_value, 0, 65535);
block->output[i][j] = static_cast<uint16_t>(shifted_value);
}
}
}


struct Peaks : Module {
enum ParamIds {
KNOB_1_PARAM,
@@ -86,15 +112,154 @@ struct Peaks : Module {
NUM_LIGHTS
};

Peaks();
~Peaks();
static const peaks::ProcessorFunction function_table_[FUNCTION_LAST][2];

EditMode edit_mode_ = EDIT_MODE_TWIN;
Function function_[2] = {FUNCTION_ENVELOPE, FUNCTION_ENVELOPE};
Settings settings_;

uint8_t pot_value_[8] = {0, 0, 0, 0, 0, 0, 0, 0};

bool snap_mode_ = false;
bool snapped_[4] = {false, false, false, false};

int32_t adc_lp_[kNumAdcChannels] = {0, 0, 0, 0};
int32_t adc_value_[kNumAdcChannels] = {0, 0, 0, 0};
int32_t adc_threshold_[kNumAdcChannels] = {0, 0, 0, 0};
long long press_time_[2] = {0, 0};

SchmittTrigger switches_[2];

peaks::IOBuffer ioBuffer;

peaks::GateFlags gate_flags[2] = {0, 0};

SampleRateConverter<2> outputSrc;
DoubleRingBuffer<Frame<2>, 256> outputBuffer;

bool initNumberStation = false;

peaks::Processors processors[2];

Peaks() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
settings_.edit_mode = EDIT_MODE_TWIN;
settings_.function[0] = FUNCTION_ENVELOPE;
settings_.function[1] = FUNCTION_ENVELOPE;
settings_.snap_mode = false;
std::fill(&settings_.pot_value[0], &settings_.pot_value[8], 0);

memset(&ioBuffer, 0, sizeof(ioBuffer));
memset(&processors[0], 0, sizeof(processors[0]));
memset(&processors[1], 0, sizeof(processors[1]));
ioBuffer.Init();
processors[0].Init(0);
processors[1].Init(1);
}

void step() override;
void onReset() override {
init();
}

void init();
void init() {
std::fill(&pot_value_[0], &pot_value_[8], 0);
std::fill(&press_time_[0], &press_time_[1], 0);
std::fill(&gBrightness[0], &gBrightness[1], 0);
std::fill(&adc_lp_[0], &adc_lp_[kNumAdcChannels], 0);
std::fill(&adc_value_[0], &adc_value_[kNumAdcChannels], 0);
std::fill(&adc_threshold_[0], &adc_threshold_[kNumAdcChannels], 0);
std::fill(&snapped_[0], &snapped_[kNumAdcChannels], false);

edit_mode_ = static_cast<EditMode>(settings_.edit_mode);
function_[0] = static_cast<Function>(settings_.function[0]);
function_[1] = static_cast<Function>(settings_.function[1]);
std::copy(&settings_.pot_value[0], &settings_.pot_value[8], &pot_value_[0]);

if (edit_mode_ == EDIT_MODE_FIRST || edit_mode_ == EDIT_MODE_SECOND) {
lockPots();
for (uint8_t i = 0; i < 4; ++i) {
processors[0].set_parameter(
i,
static_cast<uint16_t>(pot_value_[i]) << 8);
processors[1].set_parameter(
i,
static_cast<uint16_t>(pot_value_[i + 4]) << 8);
}
}

snap_mode_ = settings_.snap_mode;

changeControlMode();
setFunction(0, function_[0]);
setFunction(1, function_[1]);
}

void step() override {
poll();
pollPots();

// Initialize "secret" number station mode.
if (initNumberStation) {
processors[0].set_function(peaks::PROCESSOR_FUNCTION_NUMBER_STATION);
processors[1].set_function(peaks::PROCESSOR_FUNCTION_NUMBER_STATION);
initNumberStation = false;
}

if (outputBuffer.empty()) {
ioBuffer.Process(process);

uint32_t external_gate_inputs = 0;
external_gate_inputs |= (inputs[GATE_1_INPUT].value ? 1 : 0);
external_gate_inputs |= (inputs[GATE_2_INPUT].value ? 2 : 0);

uint32_t buttons = 0;
buttons |= (params[TRIG_1_PARAM].value ? 1 : 0);
buttons |= (params[TRIG_2_PARAM].value ? 2 : 0);

uint32_t gate_inputs = external_gate_inputs | buttons;

// Prepare sample rate conversion.
// Peaks is sampling at 48kHZ.
outputSrc.setRates(48000, engineGetSampleRate());
int inLen = peaks::kBlockSize;
int outLen = outputBuffer.capacity();
Frame<2> f[peaks::kBlockSize];

// Process an entire block of data from the IOBuffer.
for (size_t k = 0; k < peaks::kBlockSize; ++k) {

peaks::IOBuffer::Slice slice = ioBuffer.NextSlice(1);

for (size_t i = 0; i < peaks::kNumChannels; ++i) {
gate_flags[i] = peaks::ExtractGateFlags(
gate_flags[i],
gate_inputs & (1 << i));

f[k].samples[i] = slice.block->output[i][slice.frame_index];
}

// A hack to make channel 1 aware of what's going on in channel 2. Used to
// reset the sequencer.
slice.block->input[0][slice.frame_index] = gate_flags[0] | (gate_flags[1] << 4) | (buttons & 8 ? peaks::GATE_FLAG_FROM_BUTTON : 0);

slice.block->input[1][slice.frame_index] = gate_flags[1] | (buttons & 2 ? peaks::GATE_FLAG_FROM_BUTTON : 0);
}

outputSrc.process(f, &inLen, outputBuffer.endData(), &outLen);
outputBuffer.endIncr(outLen);
}

// Update outputs.
if (!outputBuffer.empty()) {
Frame<2> f = outputBuffer.shift();

// Peaks manual says output spec is 0..8V for envelopes and 10Vpp for audio/CV.
// TODO Check the output values against an actual device.
outputs[OUT_1_OUTPUT].value = rescale(static_cast<float>(f.samples[0]), 0.0f, 65535.f, -8.0f, 8.0f);
outputs[OUT_2_OUTPUT].value = rescale(static_cast<float>(f.samples[1]), 0.0f, 65535.f, -8.0f, 8.0f);
}
}



json_t *toJson() override {

@@ -167,33 +332,6 @@ struct Peaks : Module {
void refreshLeds();

long long getSystemTimeMs();

static const peaks::ProcessorFunction function_table_[FUNCTION_LAST][2];

EditMode edit_mode_ = EDIT_MODE_TWIN;
Function function_[2] = {FUNCTION_ENVELOPE, FUNCTION_ENVELOPE};
Settings settings_;

uint8_t pot_value_[8] = {0, 0, 0, 0, 0, 0, 0, 0};

bool snap_mode_ = false;
bool snapped_[4] = {false, false, false, false};

int32_t adc_lp_[kNumAdcChannels] = {0, 0, 0, 0};
int32_t adc_value_[kNumAdcChannels] = {0, 0, 0, 0};
int32_t adc_threshold_[kNumAdcChannels] = {0, 0, 0, 0};
long long press_time_[2] = {0, 0};

SchmittTrigger switches_[2];

std::shared_ptr<peaks::IOBuffer> ioBuffer;

peaks::GateFlags gate_flags[2] = {0, 0};

SampleRateConverter<2> outputSrc;
DoubleRingBuffer<Frame<2>, 256> outputBuffer;

bool initNumberStation = false;
};

const peaks::ProcessorFunction Peaks::function_table_[FUNCTION_LAST][2] = {
@@ -208,153 +346,6 @@ const peaks::ProcessorFunction Peaks::function_table_[FUNCTION_LAST][2] = {
{ peaks::PROCESSOR_FUNCTION_FM_DRUM, peaks::PROCESSOR_FUNCTION_FM_DRUM },
};

Peaks::Peaks() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
ioBuffer = std::make_shared<peaks::IOBuffer>();

settings_.edit_mode = EDIT_MODE_TWIN;
settings_.function[0] = FUNCTION_ENVELOPE;
settings_.function[1] = FUNCTION_ENVELOPE;
settings_.snap_mode = false;
std::fill(&settings_.pot_value[0], &settings_.pot_value[8], 0);

ioBuffer->Init();
peaks::processors[0].Init(0);
peaks::processors[1].Init(1);
}

Peaks::~Peaks() {
}


// Global scope, so variables can be accessed by process() function.
int16_t gOutputBuffer[peaks::kBlockSize];
int16_t gBrightness[2] = {0, 0};

void set_led_brightness(int channel, int16_t value) {
gBrightness[channel] = value;
}

// File scope because of IOBuffer function signature.
// It cannot refer to a member function of class Peaks().
void process(peaks::IOBuffer::Block* block, size_t size) {
for (size_t i = 0; i < peaks::kNumChannels; ++i) {
peaks::processors[i].Process(block->input[i], gOutputBuffer, size);
set_led_brightness(i, gOutputBuffer[0]);
for (size_t j = 0; j < size; ++j) {
// From calibration_data.h, shifting signed to unsigned values.
int32_t shifted_value = 32767 + static_cast<int32_t>(gOutputBuffer[j]);
CONSTRAIN(shifted_value, 0, 65535);
block->output[i][j] = static_cast<uint16_t>(shifted_value);
}
}
}

void Peaks::init() {
std::fill(&pot_value_[0], &pot_value_[8], 0);
std::fill(&press_time_[0], &press_time_[1], 0);
std::fill(&gBrightness[0], &gBrightness[1], 0);
std::fill(&adc_lp_[0], &adc_lp_[kNumAdcChannels], 0);
std::fill(&adc_value_[0], &adc_value_[kNumAdcChannels], 0);
std::fill(&adc_threshold_[0], &adc_threshold_[kNumAdcChannels], 0);
std::fill(&snapped_[0], &snapped_[kNumAdcChannels], false);

edit_mode_ = static_cast<EditMode>(settings_.edit_mode);
function_[0] = static_cast<Function>(settings_.function[0]);
function_[1] = static_cast<Function>(settings_.function[1]);
std::copy(&settings_.pot_value[0], &settings_.pot_value[8], &pot_value_[0]);

if (edit_mode_ == EDIT_MODE_FIRST || edit_mode_ == EDIT_MODE_SECOND) {
lockPots();
for (uint8_t i = 0; i < 4; ++i) {
peaks::processors[0].set_parameter(
i,
static_cast<uint16_t>(pot_value_[i]) << 8);
peaks::processors[1].set_parameter(
i,
static_cast<uint16_t>(pot_value_[i + 4]) << 8);
}
}

snap_mode_ = settings_.snap_mode;

changeControlMode();
setFunction(0, function_[0]);
setFunction(1, function_[1]);
}

void Peaks::step() {

poll();
pollPots();

// Initialize "secret" number station mode.
if (initNumberStation) {
peaks::processors[0].set_function(peaks::PROCESSOR_FUNCTION_NUMBER_STATION);
peaks::processors[1].set_function(peaks::PROCESSOR_FUNCTION_NUMBER_STATION);
initNumberStation = false;
}

if (outputBuffer.empty()) {

ioBuffer->Process(process);

uint32_t external_gate_inputs = 0;
external_gate_inputs |= (inputs[GATE_1_INPUT].value ? 1 : 0);
external_gate_inputs |= (inputs[GATE_2_INPUT].value ? 2 : 0);

uint32_t buttons = 0;
buttons |= (params[TRIG_1_PARAM].value ? 1 : 0);
buttons |= (params[TRIG_2_PARAM].value ? 2 : 0);

uint32_t gate_inputs = external_gate_inputs | buttons;

// Prepare sample rate conversion.
// Peaks is sampling at 48kHZ.
outputSrc.setRates(48000, engineGetSampleRate());
int inLen = peaks::kBlockSize;
int outLen = outputBuffer.capacity();
Frame<2> f[peaks::kBlockSize];

// Process an entire block of data from the IOBuffer.
for (size_t k = 0; k < peaks::kBlockSize; ++k) {

peaks::IOBuffer::Slice slice = ioBuffer->NextSlice(1);

for (size_t i = 0; i < peaks::kNumChannels; ++i) {
gate_flags[i] = peaks::ExtractGateFlags(
gate_flags[i],
gate_inputs & (1 << i));

f[k].samples[i] = slice.block->output[i][slice.frame_index];
}

// A hack to make channel 1 aware of what's going on in channel 2. Used to
// reset the sequencer.
slice.block->input[0][slice.frame_index] = gate_flags[0] \
| (gate_flags[1] << 4) \
| (buttons & 8 ? peaks::GATE_FLAG_FROM_BUTTON : 0);

slice.block->input[1][slice.frame_index] = gate_flags[1] \
| (buttons & 2 ? peaks::GATE_FLAG_FROM_BUTTON : 0);

}

outputSrc.process(f, &inLen, outputBuffer.endData(), &outLen);
outputBuffer.endIncr(outLen);
}

// Update outputs.
if (!outputBuffer.empty()) {
Frame<2> f = outputBuffer.shift();

// Peaks manual says output spec is 0..8V for envelopes and 10Vpp for audio/CV.
// TODO Check the output values against an actual device.
outputs[OUT_1_OUTPUT].value = \
rescale(static_cast<float>(f.samples[0]), 0.0f, 65535.f, -8.0f, 8.0f);
outputs[OUT_2_OUTPUT].value = \
rescale(static_cast<float>(f.samples[1]), 0.0f, 65535.f, -8.0f, 8.0f);
}
}

void Peaks::changeControlMode() {
uint16_t parameters[4];
@@ -363,32 +354,32 @@ void Peaks::changeControlMode() {
}

if (edit_mode_ == EDIT_MODE_SPLIT) {
peaks::processors[0].CopyParameters(&parameters[0], 2);
peaks::processors[1].CopyParameters(&parameters[2], 2);
peaks::processors[0].set_control_mode(peaks::CONTROL_MODE_HALF);
peaks::processors[1].set_control_mode(peaks::CONTROL_MODE_HALF);
processors[0].CopyParameters(&parameters[0], 2);
processors[1].CopyParameters(&parameters[2], 2);
processors[0].set_control_mode(peaks::CONTROL_MODE_HALF);
processors[1].set_control_mode(peaks::CONTROL_MODE_HALF);
}
else if (edit_mode_ == EDIT_MODE_TWIN) {
peaks::processors[0].CopyParameters(&parameters[0], 4);
peaks::processors[1].CopyParameters(&parameters[0], 4);
peaks::processors[0].set_control_mode(peaks::CONTROL_MODE_FULL);
peaks::processors[1].set_control_mode(peaks::CONTROL_MODE_FULL);
processors[0].CopyParameters(&parameters[0], 4);
processors[1].CopyParameters(&parameters[0], 4);
processors[0].set_control_mode(peaks::CONTROL_MODE_FULL);
processors[1].set_control_mode(peaks::CONTROL_MODE_FULL);
}
else {
peaks::processors[0].set_control_mode(peaks::CONTROL_MODE_FULL);
peaks::processors[1].set_control_mode(peaks::CONTROL_MODE_FULL);
processors[0].set_control_mode(peaks::CONTROL_MODE_FULL);
processors[1].set_control_mode(peaks::CONTROL_MODE_FULL);
}
}

void Peaks::setFunction(uint8_t index, Function f) {
if (edit_mode_ == EDIT_MODE_SPLIT || edit_mode_ == EDIT_MODE_TWIN) {
function_[0] = function_[1] = f;
peaks::processors[0].set_function(function_table_[f][0]);
peaks::processors[1].set_function(function_table_[f][1]);
processors[0].set_function(function_table_[f][0]);
processors[1].set_function(function_table_[f][1]);
}
else {
function_[index] = f;
peaks::processors[index].set_function(function_table_[f][index]);
processors[index].set_function(function_table_[f][index]);
}
}

@@ -399,8 +390,8 @@ void Peaks::onSwitchReleased(uint16_t id, uint16_t data) {
edit_mode_ = static_cast<EditMode>(
(edit_mode_ + EDIT_MODE_FIRST) % EDIT_MODE_LAST);
function_[0] = function_[1];
peaks::processors[0].set_function(function_table_[function_[0]][0]);
peaks::processors[1].set_function(function_table_[function_[0]][1]);
processors[0].set_function(function_table_[function_[0]][0]);
processors[1].set_function(function_table_[function_[0]][1]);
lockPots();
}
else {
@@ -470,17 +461,17 @@ void Peaks::pollPots() {
void Peaks::onPotChanged(uint16_t id, uint16_t value) {
switch (edit_mode_) {
case EDIT_MODE_TWIN:
peaks::processors[0].set_parameter(id, value);
peaks::processors[1].set_parameter(id, value);
processors[0].set_parameter(id, value);
processors[1].set_parameter(id, value);
pot_value_[id] = value >> 8;
break;

case EDIT_MODE_SPLIT:
if (id < 2) {
peaks::processors[0].set_parameter(id, value);
processors[0].set_parameter(id, value);
}
else {
peaks::processors[1].set_parameter(id - 2, value);
processors[1].set_parameter(id - 2, value);
}
pot_value_[id] = value >> 8;
break;
@@ -488,7 +479,7 @@ void Peaks::onPotChanged(uint16_t id, uint16_t value) {
case EDIT_MODE_FIRST:
case EDIT_MODE_SECOND: {
uint8_t index = id + (edit_mode_ - EDIT_MODE_FIRST) * 4;
peaks::Processors* p = &peaks::processors[edit_mode_ - EDIT_MODE_FIRST];
peaks::Processors* p = &processors[edit_mode_ - EDIT_MODE_FIRST];

int16_t delta = static_cast<int16_t>(pot_value_[index]) - \
static_cast<int16_t>(value >> 8);
@@ -594,16 +585,15 @@ void Peaks::refreshLeds() {
}
}

if (peaks::processors[0].function() == peaks::PROCESSOR_FUNCTION_NUMBER_STATION) {
uint8_t pattern = \
peaks::processors[0].number_station().digit() ^ \
peaks::processors[1].number_station().digit();
if (processors[0].function() == peaks::PROCESSOR_FUNCTION_NUMBER_STATION) {
uint8_t pattern = processors[0].number_station().digit()
^ processors[1].number_station().digit();
for (size_t i = 0; i < 4; ++i) {
lights[FUNC_1_LIGHT + i].value = (pattern & 1) ? 1.0f : 0.0f;
pattern = pattern >> 1;
}
b[0] = peaks::processors[0].number_station().gate() ? 255 : 0;
b[1] = peaks::processors[1].number_station().gate() ? 255 : 0;
b[0] = processors[0].number_station().gate() ? 255 : 0;
b[1] = processors[1].number_station().gate() ? 255 : 0;
}

lights[TRIG_1_LIGHT].value = rescale(static_cast<float>(b[0]), 0.0f, 255.0f, 0.0f, 1.0f);
@@ -685,4 +675,4 @@ struct PeaksWidget : ModuleWidget {



Model *modelPeaks = Model::create<Peaks, PeaksWidget>("Audible Instruments", "Peaks", "Percussive Synthesizer", UTILITY_TAG, LFO_TAG, DRUM_TAG);
Model *modelPeaks = Model::create<Peaks, PeaksWidget>("Audible Instruments", "Peaks", "Percussive Synthesizer", UTILITY_TAG, LFO_TAG, DRUM_TAG);

Loading…
Cancel
Save