mirror of
https://github.com/jhbruhn/eurorack.git
synced 2025-03-15 02:55:49 +00:00
Implement settings storage for stereo_mix
This commit is contained in:
parent
f9dd6af68a
commit
0b59c9edb1
8 changed files with 160 additions and 22 deletions
4
stereo_mix/config.h
Normal file
4
stereo_mix/config.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
#define CHANNEL_COUNT (4)
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
#include "stm32f0xx_hal_gpio.h"
|
||||
#include <stm32f0xx_hal.h>
|
||||
#include <math.h>
|
||||
#include "../config.h"
|
||||
|
||||
using namespace stereo_mix;
|
||||
using namespace stmlib;
|
||||
|
@ -21,8 +22,6 @@ enum LedColor {
|
|||
LED_COLOR_ORANGE
|
||||
};
|
||||
|
||||
const uint8_t kNumChannels = 4;
|
||||
|
||||
static GPIO_TypeDef* kGpioPorts[] = { GPIOA, GPIOA, GPIOA, GPIOA };
|
||||
static const uint16_t kGpioPins[] = { GPIO_PIN_8, GPIO_PIN_9, GPIO_PIN_10, GPIO_PIN_11 };
|
||||
|
||||
|
@ -41,7 +40,7 @@ class Leds {
|
|||
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||
|
||||
GPIO_InitTypeDef gpioInit;
|
||||
for (size_t i = 0; i < kNumChannels; i++) {
|
||||
for (size_t i = 0; i < CHANNEL_COUNT; i++) {
|
||||
gpioInit.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
gpioInit.Pin = kGpioColorPins[i];
|
||||
gpioInit.Pull = GPIO_NOPULL;
|
||||
|
@ -71,7 +70,7 @@ class Leds {
|
|||
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
|
||||
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
|
||||
|
||||
for(size_t i = 0; i < kNumChannels; i++) {
|
||||
for(size_t i = 0; i < CHANNEL_COUNT; i++) {
|
||||
HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, timer_channel[i]);
|
||||
gpioInit.Mode = GPIO_MODE_AF_PP;
|
||||
gpioInit.Pin = kGpioPins[i];
|
||||
|
@ -86,7 +85,7 @@ class Leds {
|
|||
|
||||
void Write()
|
||||
{
|
||||
for(size_t i = 0; i < kNumChannels; i++) {
|
||||
for(size_t i = 0; i < CHANNEL_COUNT; i++) {
|
||||
LedColor targetColor = colors[i];
|
||||
uint16_t intensity = intensities[i];
|
||||
if(colors[i] == LED_COLOR_ORANGE) {
|
||||
|
@ -108,7 +107,7 @@ class Leds {
|
|||
}
|
||||
|
||||
void set_intensity_signed(uint8_t channel, int16_t intensity) {
|
||||
if(channel >= kNumChannels) return;
|
||||
if(channel >= CHANNEL_COUNT) return;
|
||||
|
||||
if(intensity < 0) {
|
||||
colors[channel] = LED_COLOR_RED;
|
||||
|
@ -122,7 +121,7 @@ class Leds {
|
|||
|
||||
void set_intensity_unsigned(uint8_t channel, uint16_t intensity, LedColor color)
|
||||
{
|
||||
if (channel >= kNumChannels)
|
||||
if (channel >= CHANNEL_COUNT)
|
||||
return;
|
||||
|
||||
intensities[channel] = intensity;
|
||||
|
@ -130,7 +129,7 @@ class Leds {
|
|||
}
|
||||
|
||||
private:
|
||||
uint16_t intensities[kNumChannels];
|
||||
bool toggle[kNumChannels];
|
||||
LedColor colors[kNumChannels];
|
||||
uint16_t intensities[CHANNEL_COUNT];
|
||||
bool toggle[CHANNEL_COUNT];
|
||||
LedColor colors[CHANNEL_COUNT];
|
||||
};
|
||||
|
|
21
stereo_mix/settings.cc
Normal file
21
stereo_mix/settings.cc
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include "stmlib/system/page_storage.h"
|
||||
|
||||
#include "settings.h"
|
||||
#include "midi2cv/part.h"
|
||||
|
||||
Settings::Settings() : first_start(false)
|
||||
{
|
||||
persistent_data_.honor = 1;
|
||||
|
||||
first_start = !chunk_storage_.Init(&persistent_data_, &state_);
|
||||
}
|
||||
|
||||
void Settings::SavePersistentData()
|
||||
{
|
||||
chunk_storage_.SavePersistentData();
|
||||
}
|
||||
|
||||
void Settings::SaveState()
|
||||
{
|
||||
chunk_storage_.SaveState();
|
||||
}
|
75
stereo_mix/settings.h
Normal file
75
stereo_mix/settings.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
#pragma once
|
||||
|
||||
#include "stmlib/stmlib.h"
|
||||
#include "stmlib/system/storage.h"
|
||||
#include "config.h"
|
||||
|
||||
#define SETTINGS_START (0x08001800)
|
||||
#define SETTINGS_END (0x08002000)
|
||||
|
||||
struct ChannelData {
|
||||
bool mute;
|
||||
int16_t vol_att;
|
||||
int16_t pan_att;
|
||||
uint8_t padding[3];
|
||||
};
|
||||
|
||||
struct PersistentData {
|
||||
uint8_t honor;
|
||||
uint8_t padding[7];
|
||||
enum { tag = 0x494C4143 }; // CALI
|
||||
};
|
||||
|
||||
struct State {
|
||||
ChannelData channel_datas[CHANNEL_COUNT];
|
||||
//uint8_t padding[4];
|
||||
enum { tag = 0x54415453 }; // STAT
|
||||
};
|
||||
|
||||
class Settings {
|
||||
public:
|
||||
Settings();
|
||||
~Settings() {}
|
||||
|
||||
void SavePersistentData();
|
||||
void SaveState();
|
||||
|
||||
inline const State& state() const
|
||||
{
|
||||
return state_;
|
||||
}
|
||||
|
||||
inline State* mutable_state()
|
||||
{
|
||||
return &state_;
|
||||
}
|
||||
|
||||
inline const ChannelData& channel(int i) const
|
||||
{
|
||||
return state_.channel_datas[i];
|
||||
}
|
||||
|
||||
inline ChannelData* mutable_channel(int i)
|
||||
{
|
||||
return &state_.channel_datas[i];
|
||||
}
|
||||
|
||||
inline bool is_first_start() {
|
||||
return this->first_start;
|
||||
}
|
||||
|
||||
private:
|
||||
bool first_start;
|
||||
PersistentData persistent_data_;
|
||||
State state_;
|
||||
|
||||
stmlib::ChunkStorage<
|
||||
SETTINGS_START,
|
||||
SETTINGS_END,
|
||||
PersistentData,
|
||||
State>
|
||||
chunk_storage_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(Settings);
|
||||
};
|
||||
|
|
@ -19,7 +19,8 @@ Adc adc;
|
|||
Leds leds;
|
||||
Switches switches;
|
||||
Processor processors[kNumChannels];
|
||||
UI ui(&adc, &switches, &leds, processors);
|
||||
Settings settings;
|
||||
UI ui(&adc, &switches, &leds, processors, &settings);
|
||||
|
||||
bool mute[4];
|
||||
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
#include "ui.h"
|
||||
#include "pot_controller.h"
|
||||
#include "settings.h"
|
||||
#include <stm32f0xx_hal.h>
|
||||
|
||||
const int kLongPressDuration = 2000;
|
||||
const int kShowChangedValueMilliseconds = 600;
|
||||
static const int kLongPressDuration = 2000;
|
||||
static const int kShowChangedValueMilliseconds = 600;
|
||||
|
||||
void UI::Poll()
|
||||
{
|
||||
|
@ -40,8 +41,10 @@ void UI::Poll()
|
|||
system_clock.milliseconds() - press_time[i] + 1);
|
||||
ignore_release[i] = true;
|
||||
}
|
||||
for (size_t j = 0; j < kNumChannels * 2; j++)
|
||||
for (size_t j = 0; j < kNumChannels * 2; j++) {
|
||||
potControllers[j].Unlock();
|
||||
SaveState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,6 +56,7 @@ void UI::Poll()
|
|||
if (i < kNumChannels) {
|
||||
processors[i].set_pan_offset(pan_pots[i] - 32767);
|
||||
processors[i].set_volume_offset(volume_pots[i]);
|
||||
processors[i].set_muted(mute[i]);
|
||||
}
|
||||
if (abs(previous_pot_values[i] - adc->value(ADC_GROUP_POT + i)) > 1900) {
|
||||
previous_pot_values[i] = adc->value(ADC_GROUP_POT + i);
|
||||
|
@ -61,6 +65,33 @@ void UI::Poll()
|
|||
}
|
||||
}
|
||||
|
||||
void UI::LoadState() {
|
||||
if(!settings->is_first_start()) {
|
||||
for(size_t i = 0; i < kNumChannels; i++) {
|
||||
ChannelData c = settings->channel(i);
|
||||
mute[i] = c.mute;
|
||||
this->pan_att_pots[i] = c.pan_att + 32767;
|
||||
this->volume_att_pots[i] = c.vol_att + 32767;
|
||||
}
|
||||
} else {
|
||||
for(size_t i = 0; i < kNumChannels; i++) {
|
||||
mute[i] = false;
|
||||
this->pan_att_pots[i] = this->volume_att_pots[i] = 32767 + (32767 / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UI::SaveState() {
|
||||
for(size_t i = 0; i < kNumChannels; i++) {
|
||||
ChannelData* c = settings->mutable_channel(i);
|
||||
c->mute = this->mute[i];
|
||||
c->pan_att = this->pan_att_pots[i] - 32767;
|
||||
c->vol_att = this->volume_att_pots[i] - 32767;
|
||||
}
|
||||
|
||||
settings->SaveState();
|
||||
}
|
||||
|
||||
void UI::OnSwitchPressed(const Event& e)
|
||||
{
|
||||
}
|
||||
|
@ -79,13 +110,12 @@ void UI::OnPotChanged(const Event& e)
|
|||
void UI::OnSwitchReleased(const Event& e)
|
||||
{
|
||||
mute[e.control_id] = !mute[e.control_id];
|
||||
processors[e.control_id].set_muted(mute[e.control_id]);
|
||||
|
||||
for (size_t i = 0; i < kNumChannels; i++) {
|
||||
last_pan_pot_touch[i] = last_vol_pot_touch[i] = 0;
|
||||
}
|
||||
|
||||
// todo: save state
|
||||
SaveState();
|
||||
}
|
||||
|
||||
void UI::TaskProcessPotControllers()
|
||||
|
|
|
@ -6,30 +6,33 @@
|
|||
#include "pot_controller.h"
|
||||
#include "processor.h"
|
||||
#include "stmlib/ui/event_queue.h"
|
||||
#include "config.h"
|
||||
#include "settings.h"
|
||||
|
||||
using namespace stmlib;
|
||||
|
||||
extern const uint8_t kNumChannels; // TODO
|
||||
const uint8_t kNumChannels = CHANNEL_COUNT;
|
||||
|
||||
class UI {
|
||||
public:
|
||||
UI(Adc* adc_, Switches* switches_, Leds* leds_, Processor* processors_)
|
||||
UI(Adc* adc_, Switches* switches_, Leds* leds_, Processor* processors_, Settings* settings)
|
||||
: adc(adc_)
|
||||
, switches(switches_)
|
||||
, leds(leds_)
|
||||
, processors(processors_)
|
||||
, settings(settings)
|
||||
{
|
||||
queue.Init();
|
||||
|
||||
};
|
||||
|
||||
void Init() {
|
||||
LoadState();
|
||||
|
||||
for (size_t i = 0; i < kNumChannels; i++) {
|
||||
uint16_t* volume_hidden_params[] = {&volume_att_pots[i], &volume_att_pots[i], &volume_att_pots[i], &volume_att_pots[i]};
|
||||
potControllers[i].Init(&volume_pots[i], volume_hidden_params);
|
||||
uint16_t* pan_hidden_params[] = {&pan_att_pots[i], &pan_att_pots[i], &pan_att_pots[i], &pan_att_pots[i]};
|
||||
potControllers[i + kNumChannels].Init(&pan_pots[i], pan_hidden_params);
|
||||
|
||||
volume_att_pots[i] = pan_att_pots[i] = 32767 + (32767 / 2);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -45,6 +48,9 @@ class UI {
|
|||
void TaskDrawLeds(void);
|
||||
void TaskProcessPotControllers(void);
|
||||
|
||||
void LoadState();
|
||||
void SaveState();
|
||||
|
||||
uint8_t ui_task = 0;
|
||||
|
||||
EventQueue<> queue;
|
||||
|
@ -56,6 +62,8 @@ class UI {
|
|||
|
||||
Processor* processors;
|
||||
|
||||
Settings* settings;
|
||||
|
||||
uint16_t previous_pot_values[kNumChannels * 2];
|
||||
|
||||
uint16_t volume_pots[kNumChannels];
|
||||
|
|
2
stmlib
2
stmlib
|
@ -1 +1 @@
|
|||
Subproject commit 727d85a263af4ee4c2d8dd75191e2611383b9d29
|
||||
Subproject commit ed353ae21927643acffb86c96b69eec43879754d
|
Loading…
Reference in a new issue