diff --git a/Appli/Core/Inc/audio_effects.h b/Appli/Core/Inc/audio_effects.h index d5264be..57183ee 100644 --- a/Appli/Core/Inc/audio_effects.h +++ b/Appli/Core/Inc/audio_effects.h @@ -2,6 +2,7 @@ #define AUDIO_EFFECTS_H #include +#include "fx_octaver.h" #include "fx_equalizer.h" #include "fx_overdrive.h" #include "fx_saturation.h" @@ -14,10 +15,11 @@ extern "C" { /* Structure regroupant les parametres de tous les effets. Modifiable directement * (ex: depuis l'IHM) via AudioEffects_GetParams(). L'ordre de traitement fixe est : - * egaliseur -> overdrive -> saturation -> echo -> reverberation. */ + * octaveur -> egaliseur -> overdrive -> saturation -> echo -> reverberation. */ typedef struct { bool audio_on_off; + FxOctaverParams octaver; FxEqualizerParams equalizer; FxOverdriveParams overdrive; FxSaturationParams saturation; diff --git a/Appli/Core/Inc/fx_octaver.h b/Appli/Core/Inc/fx_octaver.h new file mode 100644 index 0000000..48a5463 --- /dev/null +++ b/Appli/Core/Inc/fx_octaver.h @@ -0,0 +1,44 @@ +#ifndef FX_OCTAVER_H +#define FX_OCTAVER_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define FX_OCTAVER_BUFFER_SIZE 2048U /* buffer circulaire (puissance de 2) */ +#define FX_OCTAVER_GRAIN_SIZE 1024U /* taille de grain, en echantillons (~21ms a 48kHz) */ +#define FX_OCTAVER_NUM_VOICES 4U /* -2oct, -1oct, +1oct, +2oct (la voie seche est geree a part) */ + +typedef struct +{ + bool enabled; + float level_down2; /* niveau voix -2 octaves, 0.0 a 1.0 */ + float level_down1; /* niveau voix -1 octave, 0.0 a 1.0 */ + float level_dry; /* niveau voix originale, 0.0 a 1.0 */ + float level_up1; /* niveau voix +1 octave, 0.0 a 1.0 */ + float level_up2; /* niveau voix +2 octaves, 0.0 a 1.0 */ +} FxOctaverParams; + +typedef struct +{ + float delay[2]; /* decalage courant (en echantillons) des deux grains en fondu croise */ +} FxOctaverVoiceState; + +typedef struct +{ + float buffer[FX_OCTAVER_BUFFER_SIZE]; + uint32_t write_idx; + FxOctaverVoiceState voices[FX_OCTAVER_NUM_VOICES]; +} FxOctaverState; + +void FxOctaver_Init(FxOctaverState *state, FxOctaverParams *params); +float FxOctaver_Process(FxOctaverState *state, const FxOctaverParams *params, float input); + +#ifdef __cplusplus +} +#endif + +#endif /* FX_OCTAVER_H */ diff --git a/Appli/Core/Src/audio_effects.c b/Appli/Core/Src/audio_effects.c index 4df9a24..ec30df1 100644 --- a/Appli/Core/Src/audio_effects.c +++ b/Appli/Core/Src/audio_effects.c @@ -2,6 +2,7 @@ static AudioEffectsParams g_params; +static FxOctaverState g_octaverState; static FxEqualizerState g_eqState; static FxOverdriveState g_overdriveState; static FxSaturationState g_saturationState; @@ -11,6 +12,7 @@ static FxReverbState g_reverbState; void AudioEffects_Init(void) { g_params.audio_on_off = false; + FxOctaver_Init(&g_octaverState, &g_params.octaver); FxEqualizer_Init(&g_eqState, &g_params.equalizer); FxOverdrive_Init(&g_overdriveState, &g_params.overdrive); FxSaturation_Init(&g_saturationState, &g_params.saturation); @@ -21,6 +23,7 @@ void AudioEffects_Init(void) float AudioEffects_Process(float input) { float sample = input; + sample = FxOctaver_Process(&g_octaverState, &g_params.octaver, sample); sample = FxEqualizer_Process(&g_eqState, &g_params.equalizer, sample); sample = FxOverdrive_Process(&g_overdriveState, &g_params.overdrive, sample); sample = FxSaturation_Process(&g_saturationState, &g_params.saturation, sample); diff --git a/Appli/Core/Src/fx_octaver.c b/Appli/Core/Src/fx_octaver.c new file mode 100644 index 0000000..fc47980 --- /dev/null +++ b/Appli/Core/Src/fx_octaver.c @@ -0,0 +1,141 @@ +#include "fx_octaver.h" +#include + +#define FX_OCTAVER_BUFFER_MASK (FX_OCTAVER_BUFFER_SIZE - 1U) +#define FX_OCTAVER_ENV_TABLE_SIZE 256U + +/* Rapport de vitesse de lecture pour chaque voix : lire le buffer plus vite que + * l'ecriture multiplie la frequence (octave au-dessus), plus lentement la divise + * (octave en-dessous). */ +static const float fx_octaver_ratios[FX_OCTAVER_NUM_VOICES] = +{ + 0.25f, /* -2 octaves */ + 0.5f, /* -1 octave */ + 2.0f, /* +1 octave */ + 4.0f /* +2 octaves */ +}; + +/* Fenetre de Hann tabulee (evite un cosf() par grain et par echantillon). */ +static float fx_octaver_env_table[FX_OCTAVER_ENV_TABLE_SIZE + 1U]; +static bool fx_octaver_env_table_ready = false; + +static void FxOctaver_BuildEnvTable(void) +{ + if (fx_octaver_env_table_ready) + { + return; + } + for (uint32_t i = 0; i <= FX_OCTAVER_ENV_TABLE_SIZE; i++) + { + float phase = (float)i / (float)FX_OCTAVER_ENV_TABLE_SIZE; + fx_octaver_env_table[i] = 0.5f - 0.5f * cosf(2.0f * (float)M_PI * phase); + } + fx_octaver_env_table_ready = true; +} + +static inline float FxOctaver_EnvLookup(float phase) +{ + float pos = phase * (float)FX_OCTAVER_ENV_TABLE_SIZE; + uint32_t i0 = (uint32_t)pos; + if (i0 >= FX_OCTAVER_ENV_TABLE_SIZE) + { + i0 = FX_OCTAVER_ENV_TABLE_SIZE - 1U; + } + float frac = pos - (float)i0; + return fx_octaver_env_table[i0] * (1.0f - frac) + fx_octaver_env_table[i0 + 1U] * frac; +} + +static inline float FxOctaver_ReadInterpolated(const float *buffer, uint32_t write_idx, float delay) +{ + float read_pos = (float)write_idx - delay; + while (read_pos < 0.0f) + { + read_pos += (float)FX_OCTAVER_BUFFER_SIZE; + } + uint32_t i0 = (uint32_t)read_pos & FX_OCTAVER_BUFFER_MASK; + uint32_t i1 = (i0 + 1U) & FX_OCTAVER_BUFFER_MASK; + float frac = read_pos - (float)(uint32_t)read_pos; + return buffer[i0] * (1.0f - frac) + buffer[i1] * frac; +} + +/* Lecteur de grains a deux pointeurs en fondu croise : chaque pointeur avance + * (ou recule) dans le buffer a une vitesse "ratio" differente de celle de + * l'ecriture, ce qui change la hauteur percue. Les deux grains sont toujours + * en opposition de phase exacte (decales d'un demi-grain a l'origine, et le + * meme increment est applique aux deux avant chaque repli) : la fenetre de + * Hann du second grain vaut donc toujours 1 moins celle du premier, ce qui + * garantit un niveau de sortie constant pendant le fondu et evite un second + * calcul de fenetre. */ +static float FxOctaver_ProcessVoice(FxOctaverVoiceState *vs, const float *buffer, uint32_t write_idx, float ratio) +{ + float step = 1.0f - ratio; + + for (uint32_t g = 0; g < 2U; g++) + { + vs->delay[g] += step; + if (vs->delay[g] >= (float)FX_OCTAVER_GRAIN_SIZE) + { + vs->delay[g] -= (float)FX_OCTAVER_GRAIN_SIZE; + } + else if (vs->delay[g] < 0.0f) + { + vs->delay[g] += (float)FX_OCTAVER_GRAIN_SIZE; + } + } + + float phase0 = vs->delay[0] / (float)FX_OCTAVER_GRAIN_SIZE; + float env0 = FxOctaver_EnvLookup(phase0); + float env1 = 1.0f - env0; + + float sample0 = FxOctaver_ReadInterpolated(buffer, write_idx, vs->delay[0]); + float sample1 = FxOctaver_ReadInterpolated(buffer, write_idx, vs->delay[1]); + + return env0 * sample0 + env1 * sample1; +} + +void FxOctaver_Init(FxOctaverState *state, FxOctaverParams *params) +{ + params->enabled = false; + params->level_down2 = 0.0f; + params->level_down1 = 0.0f; + params->level_dry = 1.0f; + params->level_up1 = 0.0f; + params->level_up2 = 0.0f; + + for (uint32_t i = 0; i < FX_OCTAVER_BUFFER_SIZE; i++) + { + state->buffer[i] = 0.0f; + } + state->write_idx = 0U; + + for (uint32_t v = 0; v < FX_OCTAVER_NUM_VOICES; v++) + { + state->voices[v].delay[0] = 0.0f; + state->voices[v].delay[1] = (float)FX_OCTAVER_GRAIN_SIZE * 0.5f; + } + + FxOctaver_BuildEnvTable(); +} + +float FxOctaver_Process(FxOctaverState *state, const FxOctaverParams *params, float input) +{ + if (!params->enabled) + { + return input; + } + + state->buffer[state->write_idx & FX_OCTAVER_BUFFER_MASK] = input; + + float down2 = FxOctaver_ProcessVoice(&state->voices[0], state->buffer, state->write_idx, fx_octaver_ratios[0]); + float down1 = FxOctaver_ProcessVoice(&state->voices[1], state->buffer, state->write_idx, fx_octaver_ratios[1]); + float up1 = FxOctaver_ProcessVoice(&state->voices[2], state->buffer, state->write_idx, fx_octaver_ratios[2]); + float up2 = FxOctaver_ProcessVoice(&state->voices[3], state->buffer, state->write_idx, fx_octaver_ratios[3]); + + state->write_idx++; + + return input * params->level_dry + + down2 * params->level_down2 + + down1 * params->level_down1 + + up1 * params->level_up1 + + up2 * params->level_up2; +} diff --git a/Appli/TouchGFX/CelloEffects.touchgfx b/Appli/TouchGFX/CelloEffects.touchgfx index d0bd5e0..63d9fe3 100644 --- a/Appli/TouchGFX/CelloEffects.touchgfx +++ b/Appli/TouchGFX/CelloEffects.touchgfx @@ -71,7 +71,6 @@ { "Type": "ButtonWithLabel", "Name": "buttonWithLabel1", - "X": 6, "Y": 93, "Width": 420, "Height": 94, @@ -117,7 +116,7 @@ "Type": "ButtonWithLabel", "Name": "buttonWithLabel3", "X": 380, - "Y": -1, + "Y": 281, "Width": 420, "Height": 94, "Pressed": "__generated\\glass_theme_images_widgets_button_regular_height_50_large_rounded_pressed.png", @@ -139,8 +138,7 @@ { "Type": "ButtonWithLabel", "Name": "buttonWithLabel4", - "X": 380, - "Y": 375, + "Y": 187, "Width": 420, "Height": 94, "Pressed": "__generated\\glass_theme_images_widgets_button_regular_height_50_large_rounded_pressed.png", @@ -182,6 +180,29 @@ "TextRotation": "0", "Preset": "glass_theme\\presets\\button\\regular\\height_50\\large_rounded_normal.json" }, + { + "Type": "ButtonWithLabel", + "Name": "buttonWithLabel6", + "X": 380, + "Y": 93, + "Width": 420, + "Height": 94, + "Pressed": "__generated\\glass_theme_images_widgets_button_regular_height_50_large_rounded_pressed.png", + "Released": "__generated\\glass_theme_images_widgets_button_regular_height_50_large_rounded_normal.png", + "TextId": "OCTAVER", + "ReleasedColor": { + "Red": 230, + "Green": 214, + "Blue": 170 + }, + "PressedColor": { + "Red": 230, + "Green": 214, + "Blue": 170 + }, + "TextRotation": "0", + "Preset": "glass_theme\\presets\\button\\regular\\height_50\\large_rounded_normal.json" + }, { "Type": "ToggleButton", "Name": "toggleButton1", @@ -265,6 +286,18 @@ "Type": "ActionCustom", "FunctionName": "toggleAudioOnOFF" } + }, + { + "InteractionName": "Interaction7", + "Trigger": { + "Type": "TriggerClicked", + "TriggerComponent": "buttonWithLabel6" + }, + "Action": { + "Type": "ActionGotoScreen", + "ScreenTransitionType": "ScreenTransitionNone", + "ActionComponent": "Octaver" + } } ] }, @@ -498,6 +531,319 @@ } ] }, + { + "Name": "Octaver", + "Components": [ + { + "Type": "Image", + "Name": "image1", + "Y": -1, + "Width": 800, + "Height": 483, + "RelativeFilename": "fondHorlogerie1.png" + }, + { + "Type": "Box", + "Name": "box1", + "Width": 800, + "Height": 480, + "Color": { + "Red": 35, + "Green": 24, + "Blue": 15 + }, + "Alpha": 240 + }, + { + "Type": "TextArea", + "Name": "textArea2", + "X": 102, + "Y": 427, + "Width": 35, + "Height": 42, + "TextId": "OCT_m2", + "TextRotation": "0", + "Color": { + "Red": 230, + "Green": 214, + "Blue": 170 + }, + "AutoSize": true + }, + { + "Type": "TextArea", + "Name": "textArea3", + "X": 244, + "Y": 427, + "Width": 35, + "Height": 42, + "TextId": "OCT_m1", + "TextRotation": "0", + "Color": { + "Red": 230, + "Green": 214, + "Blue": 170 + }, + "AutoSize": true + }, + { + "Type": "TextArea", + "Name": "textArea4", + "X": 389, + "Y": 427, + "Width": 22, + "Height": 42, + "TextId": "OCT_0", + "TextRotation": "0", + "Color": { + "Red": 230, + "Green": 214, + "Blue": 170 + }, + "AutoSize": true + }, + { + "Type": "TextArea", + "Name": "textArea5", + "X": 526, + "Y": 427, + "Width": 45, + "Height": 42, + "TextId": "OCT_p1", + "TextRotation": "0", + "Color": { + "Red": 230, + "Green": 214, + "Blue": 170 + }, + "AutoSize": true + }, + { + "Type": "TextArea", + "Name": "textArea6", + "X": 665, + "Y": 427, + "Width": 45, + "Height": 42, + "TextId": "OCT_p2", + "TextRotation": "0", + "Color": { + "Red": 230, + "Green": 214, + "Blue": 170 + }, + "AutoSize": true + }, + { + "Type": "Slider", + "Name": "slider1", + "X": 91, + "Y": 82, + "Width": 56, + "Height": 352, + "BackgroundUnselected": "__generated\\glass_theme_images_widgets_slider_vertical_thick_track_medium.png", + "BackgroundSelected": "__generated\\glass_theme_images_widgets_slider_vertical_thick_filler_medium.png", + "Indicator": "__generated\\glass_theme_images_widgets_slider_vertical_thick_rounded_dark.png", + "BackgroundX": 23, + "BackgroundY": 26, + "IndicatorMax": 300, + "ValueMax": 100, + "Preset": "glass_theme\\presets\\slider\\vertical\\thick\\medium_rounded_dark.json" + }, + { + "Type": "Slider", + "Name": "slider2", + "X": 233, + "Y": 82, + "Width": 56, + "Height": 352, + "BackgroundUnselected": "__generated\\glass_theme_images_widgets_slider_vertical_thick_track_medium.png", + "BackgroundSelected": "__generated\\glass_theme_images_widgets_slider_vertical_thick_filler_medium.png", + "Indicator": "__generated\\glass_theme_images_widgets_slider_vertical_thick_rounded_dark.png", + "BackgroundX": 23, + "BackgroundY": 26, + "IndicatorMax": 300, + "ValueMax": 100, + "Preset": "glass_theme\\presets\\slider\\vertical\\thick\\medium_rounded_dark.json" + }, + { + "Type": "Slider", + "Name": "slider3", + "X": 372, + "Y": 82, + "Width": 56, + "Height": 352, + "BackgroundUnselected": "__generated\\glass_theme_images_widgets_slider_vertical_thick_track_medium.png", + "BackgroundSelected": "__generated\\glass_theme_images_widgets_slider_vertical_thick_filler_medium.png", + "Indicator": "__generated\\glass_theme_images_widgets_slider_vertical_thick_rounded_dark.png", + "BackgroundX": 23, + "BackgroundY": 26, + "IndicatorMax": 300, + "ValueMax": 100, + "Preset": "glass_theme\\presets\\slider\\vertical\\thick\\medium_rounded_dark.json" + }, + { + "Type": "Slider", + "Name": "slider4", + "X": 520, + "Y": 82, + "Width": 56, + "Height": 352, + "BackgroundUnselected": "__generated\\glass_theme_images_widgets_slider_vertical_thick_track_medium.png", + "BackgroundSelected": "__generated\\glass_theme_images_widgets_slider_vertical_thick_filler_medium.png", + "Indicator": "__generated\\glass_theme_images_widgets_slider_vertical_thick_rounded_dark.png", + "BackgroundX": 23, + "BackgroundY": 26, + "IndicatorMax": 300, + "ValueMax": 100, + "Preset": "glass_theme\\presets\\slider\\vertical\\thick\\medium_rounded_dark.json" + }, + { + "Type": "Slider", + "Name": "slider5", + "X": 661, + "Y": 82, + "Width": 56, + "Height": 352, + "BackgroundUnselected": "__generated\\glass_theme_images_widgets_slider_vertical_thick_track_medium.png", + "BackgroundSelected": "__generated\\glass_theme_images_widgets_slider_vertical_thick_filler_medium.png", + "Indicator": "__generated\\glass_theme_images_widgets_slider_vertical_thick_rounded_dark.png", + "BackgroundX": 23, + "BackgroundY": 26, + "IndicatorMax": 300, + "ValueMax": 100, + "Preset": "glass_theme\\presets\\slider\\vertical\\thick\\medium_rounded_dark.json" + }, + { + "Type": "TextArea", + "Name": "textArea1", + "X": 295, + "Y": 26, + "Width": 188, + "Height": 42, + "TextId": "OCTAVER", + "TextRotation": "0", + "Color": { + "Red": 230, + "Green": 214, + "Blue": 170 + }, + "AutoSize": true + }, + { + "Type": "ToggleButton", + "Name": "toggleButton1", + "X": 576, + "Y": 20, + "Width": 170, + "Height": 60, + "Pressed": "__generated\\glass_theme_images_widgets_togglebutton_large_round_text_on_active.png", + "Released": "__generated\\glass_theme_images_widgets_togglebutton_large_round_text_off_normal.png", + "Preset": "glass_theme\\presets\\togglebutton\\large\\round_active_text.json" + }, + { + "Type": "ButtonWithLabel", + "Name": "buttonWithLabel1", + "Width": 225, + "Height": 94, + "Pressed": "__generated\\glass_theme_images_widgets_button_regular_height_50_small_rounded_pressed.png", + "Released": "__generated\\glass_theme_images_widgets_button_regular_height_50_small_rounded_normal.png", + "TextId": "BACK", + "ReleasedColor": { + "Red": 230, + "Green": 214, + "Blue": 170 + }, + "PressedColor": { + "Red": 230, + "Green": 214, + "Blue": 170 + }, + "TextRotation": "0", + "Preset": "glass_theme\\presets\\button\\regular\\height_50\\small_rounded_normal.json" + } + ], + "Interactions": [ + { + "InteractionName": "Interaction1", + "Trigger": { + "Type": "TriggerClicked", + "TriggerComponent": "buttonWithLabel1" + }, + "Action": { + "Type": "ActionGotoScreen", + "ScreenTransitionType": "ScreenTransitionNone", + "ActionComponent": "Overview" + } + }, + { + "InteractionName": "Interaction2", + "Trigger": { + "Type": "TriggerClicked", + "TriggerComponent": "toggleButton1" + }, + "Action": { + "Type": "ActionCustom", + "FunctionName": "toggleClicked" + } + }, + { + "InteractionName": "Interaction3", + "Trigger": { + "Type": "TriggerSliderValueChanged", + "TriggerComponent": "slider1" + }, + "Action": { + "Type": "ActionCustom", + "FunctionName": "slider1Clicked" + } + }, + { + "InteractionName": "Interaction4", + "Trigger": { + "Type": "TriggerSliderValueChanged", + "TriggerComponent": "slider2" + }, + "Action": { + "Type": "ActionCustom", + "FunctionName": "slider2Clicked" + } + }, + { + "InteractionName": "Interaction5", + "Trigger": { + "Type": "TriggerSliderValueChanged", + "TriggerComponent": "slider3" + }, + "Action": { + "Type": "ActionCustom", + "FunctionName": "slider3Clicked" + } + }, + { + "InteractionName": "Interaction6", + "Trigger": { + "Type": "TriggerSliderValueChanged", + "TriggerComponent": "slider4" + }, + "Action": { + "Type": "ActionCustom", + "FunctionName": "slider4Clicked" + } + }, + { + "InteractionName": "Interaction7", + "Trigger": { + "Type": "TriggerSliderValueChanged", + "TriggerComponent": "slider4" + }, + "Action": { + "Type": "ActionCustom", + "FunctionName": "slider5Clicked" + } + } + ] + }, { "Name": "Saturation", "Components": [ diff --git a/Appli/TouchGFX/assets/texts/texts.xml b/Appli/TouchGFX/assets/texts/texts.xml index 5131661..478914b 100644 --- a/Appli/TouchGFX/assets/texts/texts.xml +++ b/Appli/TouchGFX/assets/texts/texts.xml @@ -11,6 +11,9 @@ EQUALIZER + + OCTAVER + OVERDRIVE @@ -86,6 +89,21 @@ 16K + + -2 + + + -1 + + + 0 + + + +1 + + + +2 + diff --git a/Appli/TouchGFX/gui/include/gui/octaver_screen/OctaverPresenter.hpp b/Appli/TouchGFX/gui/include/gui/octaver_screen/OctaverPresenter.hpp new file mode 100644 index 0000000..50ce3e8 --- /dev/null +++ b/Appli/TouchGFX/gui/include/gui/octaver_screen/OctaverPresenter.hpp @@ -0,0 +1,36 @@ +#ifndef OCTAVERPRESENTER_HPP +#define OCTAVERPRESENTER_HPP + +#include +#include + +using namespace touchgfx; + +class OctaverView; + +class OctaverPresenter : public touchgfx::Presenter, public ModelListener +{ +public: + OctaverPresenter(OctaverView& v); + + /** + * The activate function is called automatically when this screen is "switched in" + * (ie. made active). Initialization logic can be placed here. + */ + virtual void activate(); + + /** + * The deactivate function is called automatically when this screen is "switched out" + * (ie. made inactive). Teardown functionality can be placed here. + */ + virtual void deactivate(); + + virtual ~OctaverPresenter() {} + +private: + OctaverPresenter(); + + OctaverView& view; +}; + +#endif // OCTAVERPRESENTER_HPP diff --git a/Appli/TouchGFX/gui/include/gui/octaver_screen/OctaverView.hpp b/Appli/TouchGFX/gui/include/gui/octaver_screen/OctaverView.hpp new file mode 100644 index 0000000..0a26993 --- /dev/null +++ b/Appli/TouchGFX/gui/include/gui/octaver_screen/OctaverView.hpp @@ -0,0 +1,24 @@ +#ifndef OCTAVERVIEW_HPP +#define OCTAVERVIEW_HPP + +#include +#include + +class OctaverView : public OctaverViewBase +{ +public: + OctaverView(); + virtual ~OctaverView() {} + virtual void setupScreen(); + virtual void tearDownScreen(); + + virtual void toggleClicked(); + virtual void slider1Clicked(int value); + virtual void slider2Clicked(int value); + virtual void slider3Clicked(int value); + virtual void slider4Clicked(int value); + virtual void slider5Clicked(int value); +protected: +}; + +#endif // OCTAVERVIEW_HPP diff --git a/Appli/TouchGFX/gui/src/octaver_screen/OctaverPresenter.cpp b/Appli/TouchGFX/gui/src/octaver_screen/OctaverPresenter.cpp new file mode 100644 index 0000000..7f2d130 --- /dev/null +++ b/Appli/TouchGFX/gui/src/octaver_screen/OctaverPresenter.cpp @@ -0,0 +1,18 @@ +#include +#include + +OctaverPresenter::OctaverPresenter(OctaverView& v) + : view(v) +{ + +} + +void OctaverPresenter::activate() +{ + +} + +void OctaverPresenter::deactivate() +{ + +} diff --git a/Appli/TouchGFX/gui/src/octaver_screen/OctaverView.cpp b/Appli/TouchGFX/gui/src/octaver_screen/OctaverView.cpp new file mode 100644 index 0000000..5f0e97c --- /dev/null +++ b/Appli/TouchGFX/gui/src/octaver_screen/OctaverView.cpp @@ -0,0 +1,48 @@ +#include +#include + +OctaverView::OctaverView() +{ +} + +void OctaverView::setupScreen() +{ + OctaverViewBase::setupScreen(); + toggleButton1.forceState(AudioEffects_GetParams()->octaver.enabled); + slider1.setValue((int16_t)(AudioEffects_GetParams()->octaver.level_down2 * 100.0f)); + slider2.setValue((int16_t)(AudioEffects_GetParams()->octaver.level_down1 * 100.0f)); + slider3.setValue((int16_t)(AudioEffects_GetParams()->octaver.level_dry * 100.0f)); + slider4.setValue((int16_t)(AudioEffects_GetParams()->octaver.level_up1 * 100.0f)); + slider5.setValue((int16_t)(AudioEffects_GetParams()->octaver.level_up2 * 100.0f)); +} + +void OctaverView::tearDownScreen() +{ + OctaverViewBase::tearDownScreen(); +} + +void OctaverView::toggleClicked() +{ + AudioEffects_GetParams()->octaver.enabled = toggleButton1.getState(); +} + +void OctaverView::slider1Clicked(int value) +{ + AudioEffects_GetParams()->octaver.level_down2 = value / 100.0f; +} +void OctaverView::slider2Clicked(int value) +{ + AudioEffects_GetParams()->octaver.level_down1 = value / 100.0f; +} +void OctaverView::slider3Clicked(int value) +{ + AudioEffects_GetParams()->octaver.level_dry = value / 100.0f; +} +void OctaverView::slider4Clicked(int value) +{ + AudioEffects_GetParams()->octaver.level_up1 = value / 100.0f; +} +void OctaverView::slider5Clicked(int value) +{ + AudioEffects_GetParams()->octaver.level_up2 = value / 100.0f; +} diff --git a/STM32CubeIDE/Appli/.project b/STM32CubeIDE/Appli/.project index bad970e..9d607a4 100644 --- a/STM32CubeIDE/Appli/.project +++ b/STM32CubeIDE/Appli/.project @@ -420,6 +420,16 @@ 1 PARENT-2-PROJECT_LOC/Appli/TouchGFX/gui/src/model/Model.cpp + + Application/User/gui/OctaverPresenter.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/gui/src/octaver_screen/OctaverPresenter.cpp + + + Application/User/gui/OctaverView.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/gui/src/octaver_screen/OctaverView.cpp + Application/User/gui/OverdrivePresenter.cpp 1 @@ -565,6 +575,11 @@ 1 PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/gui_generated/src/initscreen_screen/InitScreenViewBase.cpp + + Application/User/generated/OctaverViewBase.cpp + 1 + PARENT-2-PROJECT_LOC/Appli/TouchGFX/generated/gui_generated/src/octaver_screen/OctaverViewBase.cpp + Application/User/generated/OverdriveViewBase.cpp 1 diff --git a/gcc/makefile_appli b/gcc/makefile_appli index 6d9c0e2..50ff7ed 100644 --- a/gcc/makefile_appli +++ b/gcc/makefile_appli @@ -300,6 +300,7 @@ board_c_files += \ Appli/Core/Src/stm32h7rsxx_hal_timebase_tim.c \ Appli/Core/Src/system_stm32h7rsxx.c \ Appli/Core/Src/audio_effects.c \ + Appli/Core/Src/fx_octaver.c \ Appli/Core/Src/fx_equalizer.c \ Appli/Core/Src/fx_overdrive.c \ Appli/Core/Src/fx_saturation.c \