Skip to content

Commit

Permalink
Switch to Frequency + Rework Settings for Variable Item List Use
Browse files Browse the repository at this point in the history
[Problem]
Currently using period and frequency to generate the tone to play.
This isn't easy to understand, and isn't nicely compatible with
understanding what tone will play.

[Solution]
Updated to use frequency for the tone to play, plus updated the
Settings Scene to instead use a variable item list for changing
the settings. This makes the settings manageable now.

[Testing]
Tested on device and confirmed working.
  • Loading branch information
GEMISIS committed Dec 29, 2023
1 parent 296928b commit 01afdb3
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 83 deletions.
16 changes: 5 additions & 11 deletions src/scenes/playback_scene.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,11 @@
#include "../app_context.h"
#include "../tone_gen.h"

#define SINE_WAVE(x, toneModelData) \
(toneDataModel->amplitude * \
sin((x + toneDataModel->animationOffset) * 50 * toneDataModel->period) * 20 + \
(64 / 2))
#define SINE_WAVE(x, toneModelData) \
(sin((x + toneDataModel->animationOffset) * 50) * 20 + (64 / 2))

#define SQUARE_WAVE(x, toneModelData) \
(toneDataModel->amplitude * \
(sin((x + toneDataModel->animationOffset) * 50 * toneDataModel->period) > 0 ? 1 : -1) * \
20 + \
(64 / 2))
#define SQUARE_WAVE(x, toneModelData) \
((sin((x + toneDataModel->animationOffset) * 50) > 0 ? 1 : -1) * 20 + (64 / 2))

// Renders the waveform
static void playback_view_draw_callback(Canvas* canvas, void* model) {
Expand Down Expand Up @@ -59,9 +54,8 @@ void scene_on_enter_playback_scene(void* context) {

FURI_LOG_I(TAG, "setting view model");
struct ToneData_t* toneDataModel = (struct ToneData_t*)view_get_model(playbackView->viewData);
toneDataModel->amplitude = ((struct ToneData_t*)app->additionalData)->amplitude;
toneDataModel->period = ((struct ToneData_t*)app->additionalData)->period;
toneDataModel->waveType = ((struct ToneData_t*)app->additionalData)->waveType;
toneDataModel->frequency = ((struct ToneData_t*)app->additionalData)->frequency;

// Set the currently active view
FURI_LOG_I(TAG, "setting active view");
Expand Down
126 changes: 59 additions & 67 deletions src/scenes/settings_scene.c
Original file line number Diff line number Diff line change
@@ -1,36 +1,41 @@
#include <gui/modules/submenu.h>
#include <gui/modules/popup.h>
#include <gui/modules/variable_item_list.h>

#include "settings_scene.h"
#include "../app_context.h"
#include "../tone_gen.h"
#include "../utils/linked_list.h"

/** indices for menu items */
typedef enum {
SettingsMenuOptions_WaveType,
SettingsMenuOptions_Amplitude,
SettingsMenuOptions_Period,
} SettingsMenuOptions;

/** main menu callback - sends a custom event to the scene manager based on the menu selection */
// Not actively used in this instance.
void menu_callback_settings_scene(void* context, uint32_t index) {
UNUSED(context);
// struct AppContext_t* app = context;
switch(index) {
case SettingsMenuOptions_WaveType:
FURI_LOG_I(TAG, "selection one");
// scene_manager_handle_custom_event(app->scene_manager, ToneGenAppEvent_StartPlayback);
break;
case SettingsMenuOptions_Amplitude:
FURI_LOG_I(TAG, "selection two");
// scene_manager_handle_custom_event(app->scene_manager, ToneGenAppEvent_AdjustTone);
break;
case SettingsMenuOptions_Period:
FURI_LOG_I(TAG, "selection three");
// scene_manager_handle_custom_event(app->scene_manager, ToneGenAppEvent_AdjustTone);
break;
}
UNUSED(index);
}

static uint8_t wave_option_values[] = {SINE, SQUARE};
static char* wave_option_names[] = {"Sine", "Square"};
static void wave_type_option_change(VariableItem* item) {
struct AppContext_t* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, wave_option_names[index]);
((struct ToneData_t*)app->additionalData)->waveType = index;
}

// Since the max number of options for variable item lists is
// the size of an 8-bit integer, we need to limit the max
// number of steps. In this case, we limit it to 241 total
// steps available, incrementing in steps of 10.
#define MIN_FREQ 100
#define MAX_FREQ 2500
#define FREQ_STEPS 10
#define INDEX_TO_FREQ(index) (uint16_t)((index * FREQ_STEPS) + MIN_FREQ)
#define FREQ_TO_INDEX(freq) (uint8_t)((freq - MIN_FREQ) / FREQ_STEPS)
char* frequencyStr;
static void frequency_option_change(VariableItem* item) {
struct AppContext_t* app = variable_item_get_context(item);
uint8_t index = variable_item_get_current_value_index(item);
((struct ToneData_t*)app->additionalData)->frequency = INDEX_TO_FREQ(index);
snprintf(frequencyStr, 8, "%dhz", ((struct ToneData_t*)app->additionalData)->frequency);
variable_item_set_current_value_text(item, frequencyStr);
}

/** resets the menu, gives it content, callbacks and selection enums */
Expand All @@ -40,62 +45,49 @@ void scene_on_enter_settings_scene(void* context) {

// Setup our menu
FURI_LOG_D(TAG, "Adding view menu");
struct View_t* menuView = app->activeViews[ToneGenAppView_Submenu];
struct View_t* variableItemListView = app->activeViews[ToneGenAppView_VariableItemList];

// Set the currently active view
submenu_reset(menuView->viewData);
variable_item_list_reset(variableItemListView->viewData);

submenu_set_header(menuView->viewData, "Tone Settings");

FURI_LOG_D(TAG, "Adding menu options for settings");
submenu_add_item(
menuView->viewData,
FURI_LOG_D(TAG, "Adding options for settings");
VariableItem* item = variable_item_list_add(
variableItemListView->viewData,
"Wave Type",
SettingsMenuOptions_WaveType,
menu_callback_settings_scene,
app);
submenu_add_item(
menuView->viewData,
"Amplitude",
SettingsMenuOptions_Amplitude,
menu_callback_settings_scene,
COUNT_OF(wave_option_values),
wave_type_option_change,
app);
submenu_add_item(
menuView->viewData,
"Period",
SettingsMenuOptions_Period,
menu_callback_settings_scene,
variable_item_set_current_value_index(
item, ((struct ToneData_t*)app->additionalData)->waveType);
variable_item_set_current_value_text(
item, wave_option_names[((struct ToneData_t*)app->additionalData)->waveType]);

item = variable_item_list_add(
variableItemListView->viewData,
"Frequency",
FREQ_TO_INDEX(MAX_FREQ) + 1,
frequency_option_change,
app);
view_dispatcher_switch_to_view(app->view_dispatcher, ToneGenAppView_Submenu);
variable_item_set_current_value_index(
item, FREQ_TO_INDEX(((struct ToneData_t*)app->additionalData)->frequency));

frequencyStr = calloc(8, sizeof(char));
snprintf(frequencyStr, 8, "%dhz", ((struct ToneData_t*)app->additionalData)->frequency);
variable_item_set_current_value_text(item, frequencyStr);

view_dispatcher_switch_to_view(app->view_dispatcher, ToneGenAppView_VariableItemList);
}

/** main menu event handler - switches scene based on the event */
// Not actively used in this instance.
bool scene_on_event_settings_scene(void* context, SceneManagerEvent event) {
FURI_LOG_I(TAG, "scene_on_event_settings_scene");
UNUSED(context);
// struct AppContext_t* app = context;
bool consumed = false;
switch(event.type) {
case SceneManagerEventTypeCustom:
// switch(event.event) {
// case ToneGenAppEvent_StartPlayback:
// scene_manager_next_scene(app->scene_manager, ToneGenAppScene_Playback);
// consumed = true;
// break;
// case ToneGenAppEvent_AdjustTone:
// scene_manager_next_scene(app->scene_manager, ToneGenAppScene_AdjustTone);
// consumed = true;
// break;
// }
break;
default: // eg. SceneManagerEventTypeBack, SceneManagerEventTypeTick
consumed = false;
break;
}
return consumed;
UNUSED(event);
return false;
}

void scene_on_exit_settings_scene(void* context) {
FURI_LOG_I(TAG, "scene_on_exit_settings_scene");
UNUSED(context);
free(frequencyStr);
}
3 changes: 1 addition & 2 deletions src/tone_gen.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,7 @@ int32_t tone_gen_app(void* p) {
if(result == APP_CONTEXT_OK) {
appContext->additionalData = malloc(sizeof(struct ToneData_t));
((struct ToneData_t*)appContext->additionalData)->animationOffset = 0;
((struct ToneData_t*)appContext->additionalData)->amplitude = 1;
((struct ToneData_t*)appContext->additionalData)->period = 1;
((struct ToneData_t*)appContext->additionalData)->frequency = 440;
((struct ToneData_t*)appContext->additionalData)->waveType = SINE;

result = setupViews(&appContext);
Expand Down
5 changes: 2 additions & 3 deletions src/tone_gen.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,12 @@ typedef enum {
ToneGenAppView_count
} ToneGenAppView;

typedef enum { SQUARE, SINE } ToneWaveType;
typedef enum { SINE, SQUARE } ToneWaveType;

struct ToneData_t {
int animationOffset;
int amplitude;
int period;
ToneWaveType waveType;
uint16_t frequency;
};

#endif

0 comments on commit 01afdb3

Please sign in to comment.