Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Peaks fix #56

Open
wants to merge 3 commits into
base: v0.6
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 74 additions & 46 deletions src/Peaks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include "dsp/samplerate.hpp"
#include "dsp/ringbuffer.hpp"

#include "peaks/io_buffer.h"
#include "peaks/processors.h"

#include "AudibleInstruments.hpp"
Expand Down Expand Up @@ -47,38 +46,15 @@ struct Settings {
};


static const size_t kNumBlocks = 2;
static const size_t kNumChannels = 2;
static const size_t kBlockSize = 4;
static const int32_t kLongPressDuration = 600;
static const uint8_t kNumAdcChannels = 4;
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,
Expand Down Expand Up @@ -128,9 +104,12 @@ struct Peaks : Module {
int32_t adc_threshold_[kNumAdcChannels] = {0, 0, 0, 0};
long long press_time_[2] = {0, 0};

SchmittTrigger switches_[2];
peaks::Processors processors[2];

int16_t output[kBlockSize];
int16_t brightness[kNumChannels] = {0, 0};

peaks::IOBuffer ioBuffer;
SchmittTrigger switches_[2];

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

Expand All @@ -139,7 +118,21 @@ struct Peaks : Module {

bool initNumberStation = false;

peaks::Processors processors[2];
struct Block {
peaks::GateFlags input[kNumChannels][kBlockSize];
uint16_t output[kNumChannels][kBlockSize];
};

struct Slice {
Block* block;
size_t frame_index;
};

Block block_[kNumBlocks];
size_t io_frame_ = 0;
size_t io_block_ = 0;
size_t render_block_ = kNumBlocks / 2;


Peaks() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {
settings_.edit_mode = EDIT_MODE_TWIN;
Expand All @@ -148,10 +141,8 @@ struct Peaks : Module {
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);
}
Expand All @@ -163,7 +154,7 @@ struct Peaks : Module {
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(&brightness[0], &brightness[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);
Expand Down Expand Up @@ -261,7 +252,11 @@ struct Peaks : Module {
}

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

while (render_block_ != io_block_) {
process(&block_[render_block_], kBlockSize);
render_block_ = (render_block_ + 1) % kNumBlocks;
}

uint32_t external_gate_inputs = 0;
external_gate_inputs |= (inputs[GATE_1_INPUT].value ? 1 : 0);
Expand All @@ -276,16 +271,16 @@ struct Peaks : Module {
// Prepare sample rate conversion.
// Peaks is sampling at 48kHZ.
outputSrc.setRates(48000, engineGetSampleRate());
int inLen = peaks::kBlockSize;
int inLen = kBlockSize;
int outLen = outputBuffer.capacity();
Frame<2> f[peaks::kBlockSize];
Frame<2> f[kBlockSize];

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

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

for (size_t i = 0; i < peaks::kNumChannels; ++i) {
for (size_t i = 0; i < kNumChannels; ++i) {
gate_flags[i] = peaks::ExtractGateFlags(
gate_flags[i],
gate_inputs & (1 << i));
Expand Down Expand Up @@ -315,10 +310,39 @@ struct Peaks : Module {
}
}

inline Slice NextSlice(size_t size) {
Slice s;
s.block = &block_[io_block_];
s.frame_index = io_frame_;
io_frame_ += size;
if (io_frame_ >= kBlockSize) {
io_frame_ -= kBlockSize;
io_block_ = (io_block_ + 1) % kNumBlocks;
}
return s;
}

inline Function function() const {
return edit_mode_ == EDIT_MODE_SECOND ? function_[1] : function_[0];
}

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

inline void process(Block* block, size_t size) {
for (size_t i = 0; i < kNumChannels; ++i) {
processors[i].Process(block->input[i], output, size);
set_led_brightness(i, output[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>(output[j]);
CONSTRAIN(shifted_value, 0, 65535);
block->output[i][j] = static_cast<uint16_t>(shifted_value);
}
}
}

void changeControlMode();
void setFunction(uint8_t index, Function f);
void onPotChanged(uint16_t id, uint16_t value);
Expand Down Expand Up @@ -564,21 +588,21 @@ void Peaks::refreshLeds() {
switch (function_[i]) {
case FUNCTION_DRUM_GENERATOR:
case FUNCTION_FM_DRUM_GENERATOR:
b[i] = (int16_t) std::abs(gBrightness[i]) >> 8;
b[i] = (int16_t) abs(brightness[i]) >> 8;
b[i] = b[i] >= 255 ? 255 : b[i];
break;
case FUNCTION_LFO:
case FUNCTION_TAP_LFO:
case FUNCTION_MINI_SEQUENCER: {
int32_t brightness = int32_t(gBrightness[i]) * 409 >> 8;
brightness += 32768;
brightness >>= 8;
CONSTRAIN(brightness, 0, 255);
b[i] = brightness;
int32_t brightnessVal = int32_t(brightness[i]) * 409 >> 8;
brightnessVal += 32768;
brightnessVal >>= 8;
CONSTRAIN(brightnessVal, 0, 255);
b[i] = brightnessVal;
}
break;
default:
b[i] = gBrightness[i] >> 7;
b[i] = brightness[i] >> 7;
break;
}
}
Expand Down Expand Up @@ -651,6 +675,10 @@ struct PeaksWidget : ModuleWidget {
void onAction(EventAction &e) override {
peaks->initNumberStation = true;
}
void step() override {
rightText = (peaks->processors[0].function() == peaks::PROCESSOR_FUNCTION_NUMBER_STATION) ? "✔" : "";
MenuItem::step();
}
};

menu->addChild(construct<MenuLabel>());
Expand Down