Skip to content

Commit 811047a

Browse files
committed
Add Volume + Actually Play Tone
[Problem] Need to actually play the sound, but this also requires the volume to be adjustable. [Solution] Used the audio HAL APIs to play the tone and added volume to the ToneData structure that is configurable in the settings. [Testing] Confirmed working on device.
1 parent 01afdb3 commit 811047a

7 files changed

+84
-2
lines changed

application.fam

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,5 @@ App(
1313
fap_author="Gerald McAlister",
1414
fap_weburl="https://github.com/GEMISIS/tone_gen",
1515
fap_icon_assets="images", # Image assets to compile for this application
16-
sources=["src/*.c", "src/scenes/*.c", "src/utils/*.c"],
16+
sources=["src/*.c", "src/scenes/*.c", "src/system/*.c", "src/utils/*.c"],
1717
)

src/scenes/playback_scene.c

+11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1+
#include <furi_hal.h>
2+
13
#include "playback_scene.h"
24
#include "../app_context.h"
35
#include "../tone_gen.h"
6+
#include "../system/audio_helper.h"
47

58
#define SINE_WAVE(x, toneModelData) \
69
(sin((x + toneDataModel->animationOffset) * 50) * 20 + (64 / 2))
@@ -56,10 +59,16 @@ void scene_on_enter_playback_scene(void* context) {
5659
struct ToneData_t* toneDataModel = (struct ToneData_t*)view_get_model(playbackView->viewData);
5760
toneDataModel->waveType = ((struct ToneData_t*)app->additionalData)->waveType;
5861
toneDataModel->frequency = ((struct ToneData_t*)app->additionalData)->frequency;
62+
toneDataModel->volume = ((struct ToneData_t*)app->additionalData)->volume;
5963

6064
// Set the currently active view
6165
FURI_LOG_I(TAG, "setting active view");
6266
view_dispatcher_switch_to_view(app->view_dispatcher, ToneGenAppView_PlaybackView);
67+
68+
if(initializeSpeaker()) {
69+
FURI_LOG_I(TAG, "Starting sound");
70+
startSound(toneDataModel);
71+
}
6372
}
6473

6574
// Not actively used in this instance.
@@ -74,4 +83,6 @@ bool scene_on_event_playback_scene(void* context, SceneManagerEvent event) {
7483
void scene_on_exit_playback_scene(void* context) {
7584
FURI_LOG_I(TAG, "scene_on_exit_playback_scene");
7685
UNUSED(context);
86+
stopSound();
87+
deinitializeSpeaker();
7788
}

src/scenes/settings_scene.c

+26
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ static void frequency_option_change(VariableItem* item) {
3838
variable_item_set_current_value_text(item, frequencyStr);
3939
}
4040

41+
char* volumeStr;
42+
static void volume_option_change(VariableItem* item) {
43+
struct AppContext_t* app = variable_item_get_context(item);
44+
uint8_t index = variable_item_get_current_value_index(item);
45+
((struct ToneData_t*)app->additionalData)->volume = ((float)(index)) / 10.0f;
46+
snprintf(volumeStr, 5, "%d", (index * 10));
47+
variable_item_set_current_value_text(item, volumeStr);
48+
}
49+
4150
/** resets the menu, gives it content, callbacks and selection enums */
4251
void scene_on_enter_settings_scene(void* context) {
4352
FURI_LOG_I(TAG, "scene_on_enter_settings_scene");
@@ -51,6 +60,7 @@ void scene_on_enter_settings_scene(void* context) {
5160
variable_item_list_reset(variableItemListView->viewData);
5261

5362
FURI_LOG_D(TAG, "Adding options for settings");
63+
// Wave type setting
5464
VariableItem* item = variable_item_list_add(
5565
variableItemListView->viewData,
5666
"Wave Type",
@@ -62,6 +72,7 @@ void scene_on_enter_settings_scene(void* context) {
6272
variable_item_set_current_value_text(
6373
item, wave_option_names[((struct ToneData_t*)app->additionalData)->waveType]);
6474

75+
// Frequency setting
6576
item = variable_item_list_add(
6677
variableItemListView->viewData,
6778
"Frequency",
@@ -75,6 +86,20 @@ void scene_on_enter_settings_scene(void* context) {
7586
snprintf(frequencyStr, 8, "%dhz", ((struct ToneData_t*)app->additionalData)->frequency);
7687
variable_item_set_current_value_text(item, frequencyStr);
7788

89+
// Volume setting
90+
item = variable_item_list_add(
91+
variableItemListView->viewData, "Volume", 11, volume_option_change, app);
92+
variable_item_set_current_value_index(
93+
item, (uint8_t)(((struct ToneData_t*)app->additionalData)->volume * 10.0f));
94+
95+
volumeStr = calloc(8, sizeof(char));
96+
snprintf(
97+
volumeStr,
98+
5,
99+
"%d",
100+
((uint8_t)(((struct ToneData_t*)app->additionalData)->volume * 100.0f)));
101+
variable_item_set_current_value_text(item, volumeStr);
102+
78103
view_dispatcher_switch_to_view(app->view_dispatcher, ToneGenAppView_VariableItemList);
79104
}
80105

@@ -90,4 +115,5 @@ void scene_on_exit_settings_scene(void* context) {
90115
FURI_LOG_I(TAG, "scene_on_exit_settings_scene");
91116
UNUSED(context);
92117
free(frequencyStr);
118+
free(volumeStr);
93119
}

src/system/audio_helper.c

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "audio_helper.h"
2+
3+
bool initializeSpeaker() {
4+
return furi_hal_speaker_acquire(SPEAKER_TIMEOUT);
5+
}
6+
7+
bool startSound(struct ToneData_t* toneData) {
8+
bool hasSpeaker = furi_hal_speaker_is_mine();
9+
if(!hasSpeaker) {
10+
hasSpeaker = furi_hal_speaker_acquire(SPEAKER_TIMEOUT);
11+
}
12+
13+
if(hasSpeaker) {
14+
FURI_LOG_I(TAG, "Sound is beginning to play");
15+
furi_hal_speaker_start(toneData->frequency, toneData->volume);
16+
} else {
17+
FURI_LOG_E(TAG, "Error acquiring speaker!");
18+
}
19+
return hasSpeaker;
20+
}
21+
22+
void stopSound() {
23+
furi_hal_speaker_stop();
24+
}
25+
26+
void deinitializeSpeaker() {
27+
furi_hal_speaker_release();
28+
}

src/system/audio_helper.h

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef _AUDIO_HELPER_H_
2+
3+
#define _AUDIO_HELPER_H_
4+
5+
#include <furi_hal.h>
6+
7+
#include "../tone_gen.h"
8+
9+
#define SPEAKER_TIMEOUT 10
10+
11+
bool initializeSpeaker();
12+
bool startSound(struct ToneData_t* toneData);
13+
void stopSound();
14+
void deinitializeSpeaker();
15+
16+
#endif

src/tone_gen.c

+1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ int32_t tone_gen_app(void* p) {
116116
((struct ToneData_t*)appContext->additionalData)->animationOffset = 0;
117117
((struct ToneData_t*)appContext->additionalData)->frequency = 440;
118118
((struct ToneData_t*)appContext->additionalData)->waveType = SINE;
119+
((struct ToneData_t*)appContext->additionalData)->volume = 1.0f;
119120

120121
result = setupViews(&appContext);
121122
if(result == 0) {

src/tone_gen.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#define TAG "tone-gen"
66

77
#include <furi.h>
8-
#include <music_worker/music_worker.h>
98

109
// ids for all scenes used by the app
1110
typedef enum {
@@ -31,6 +30,7 @@ struct ToneData_t {
3130
int animationOffset;
3231
ToneWaveType waveType;
3332
uint16_t frequency;
33+
float volume;
3434
};
3535

3636
#endif

0 commit comments

Comments
 (0)