diff --git a/dtmf_dolphin.c b/dtmf_dolphin.c index 94d78bc4953..c1b10defa23 100644 --- a/dtmf_dolphin.c +++ b/dtmf_dolphin.c @@ -78,10 +78,10 @@ static void app_free(DTMFDolphinApp* app) { free(app); } -int32_t dtmf_dolphin_app(void *p) { +int32_t dtmf_dolphin_app(void* p) { UNUSED(p); DTMFDolphinApp* app = app_alloc(); - + view_dispatcher_run(app->view_dispatcher); app_free(app); diff --git a/dtmf_dolphin_audio.c b/dtmf_dolphin_audio.c index 2bc16286e9d..4b84ceb97f9 100644 --- a/dtmf_dolphin_audio.c +++ b/dtmf_dolphin_audio.c @@ -1,11 +1,11 @@ #include "dtmf_dolphin_audio.h" -DTMFDolphinAudio *current_player; +DTMFDolphinAudio* current_player; static void dtmf_dolphin_audio_dma_isr(void* ctx) { - FuriMessageQueue *event_queue = ctx; + FuriMessageQueue* event_queue = ctx; - if (LL_DMA_IsActiveFlag_HT1(DMA1)) { + if(LL_DMA_IsActiveFlag_HT1(DMA1)) { LL_DMA_ClearFlag_HT1(DMA1); DTMFDolphinCustomEvent event = {.type = DTMFDolphinEventDMAHalfTransfer}; @@ -21,13 +21,13 @@ static void dtmf_dolphin_audio_dma_isr(void* ctx) { } void dtmf_dolphin_audio_clear_samples(DTMFDolphinAudio* player) { - for (size_t i = 0; i < player->buffer_length; i++) { + for(size_t i = 0; i < player->buffer_length; i++) { player->sample_buffer[i] = 0; } } DTMFDolphinOsc* dtmf_dolphin_osc_alloc() { - DTMFDolphinOsc *osc = malloc(sizeof(DTMFDolphinOsc)); + DTMFDolphinOsc* osc = malloc(sizeof(DTMFDolphinOsc)); osc->cached_freq = 0; osc->offset = 0; osc->period = 0; @@ -36,7 +36,7 @@ DTMFDolphinOsc* dtmf_dolphin_osc_alloc() { } DTMFDolphinPulseFilter* dtmf_dolphin_pulse_filter_alloc() { - DTMFDolphinPulseFilter *pf = malloc(sizeof(DTMFDolphinPulseFilter)); + DTMFDolphinPulseFilter* pf = malloc(sizeof(DTMFDolphinPulseFilter)); pf->duration = 0; pf->period = 0; pf->offset = 0; @@ -45,7 +45,7 @@ DTMFDolphinPulseFilter* dtmf_dolphin_pulse_filter_alloc() { } DTMFDolphinAudio* dtmf_dolphin_audio_alloc() { - DTMFDolphinAudio *player = malloc(sizeof(DTMFDolphinAudio)); + DTMFDolphinAudio* player = malloc(sizeof(DTMFDolphinAudio)); player->buffer_length = SAMPLE_BUFFER_LENGTH; player->half_buffer_length = SAMPLE_BUFFER_LENGTH / 2; player->sample_buffer = malloc(sizeof(uint16_t) * player->buffer_length); @@ -61,56 +61,58 @@ DTMFDolphinAudio* dtmf_dolphin_audio_alloc() { } size_t calc_waveform_period(float freq) { - if (!freq) { + if(!freq) { return 0; } // DMA Rate calculation, thanks to Dr_Zlo - float dma_rate = CPU_CLOCK_FREQ \ - / 2 \ - / DTMF_DOLPHIN_HAL_DMA_PRESCALER \ - / (DTMF_DOLPHIN_HAL_DMA_AUTORELOAD + 1); + float dma_rate = CPU_CLOCK_FREQ / 2 / DTMF_DOLPHIN_HAL_DMA_PRESCALER / + (DTMF_DOLPHIN_HAL_DMA_AUTORELOAD + 1); // Using a constant scaling modifier, which likely represents // the combined system overhead and isr latency. - return (uint16_t) dma_rate * 2 / freq * 0.801923; + return (uint16_t)dma_rate * 2 / freq * 0.801923; } void osc_generate_lookup_table(DTMFDolphinOsc* osc, float freq) { - if (osc->lookup_table != NULL) { + if(osc->lookup_table != NULL) { free(osc->lookup_table); } osc->offset = 0; osc->cached_freq = freq; osc->period = calc_waveform_period(freq); - if (!osc->period) { + if(!osc->period) { osc->lookup_table = NULL; return; } osc->lookup_table = malloc(sizeof(float) * osc->period); - for (size_t i = 0; i < osc->period; i++) { + for(size_t i = 0; i < osc->period; i++) { osc->lookup_table[i] = sin(i * PERIOD_2_PI / osc->period) + 1; } } -void filter_generate_lookup_table(DTMFDolphinPulseFilter* pf, uint16_t pulses, uint16_t pulse_ms, uint16_t gap_ms) { - if (pf->lookup_table != NULL) { +void filter_generate_lookup_table( + DTMFDolphinPulseFilter* pf, + uint16_t pulses, + uint16_t pulse_ms, + uint16_t gap_ms) { + if(pf->lookup_table != NULL) { free(pf->lookup_table); } pf->offset = 0; - uint16_t gap_period = calc_waveform_period(1000 / (float) gap_ms); - uint16_t pulse_period = calc_waveform_period(1000 / (float) pulse_ms); + uint16_t gap_period = calc_waveform_period(1000 / (float)gap_ms); + uint16_t pulse_period = calc_waveform_period(1000 / (float)pulse_ms); pf->period = pulse_period + gap_period; - if (!pf->period) { + if(!pf->period) { pf->lookup_table = NULL; return; } pf->duration = pf->period * pulses; pf->lookup_table = malloc(sizeof(bool) * pf->duration); - for (size_t i = 0; i < pf->duration; i++) { + for(size_t i = 0; i < pf->duration; i++) { pf->lookup_table[i] = i % pf->period < pulse_period; } } @@ -118,7 +120,7 @@ void filter_generate_lookup_table(DTMFDolphinPulseFilter* pf, uint16_t pulses, u float sample_frame(DTMFDolphinOsc* osc) { float frame = 0.0; - if (osc->period) { + if(osc->period) { frame = osc->lookup_table[osc->offset]; osc->offset = (osc->offset + 1) % osc->period; } @@ -129,8 +131,8 @@ float sample_frame(DTMFDolphinOsc* osc) { bool sample_filter(DTMFDolphinPulseFilter* pf) { bool frame = true; - if (pf->duration) { - if (pf->offset < pf->duration) { + if(pf->duration) { + if(pf->offset < pf->duration) { frame = pf->lookup_table[pf->offset]; pf->offset = pf->offset + 1; } else { @@ -142,14 +144,14 @@ bool sample_filter(DTMFDolphinPulseFilter* pf) { } void dtmf_dolphin_osc_free(DTMFDolphinOsc* osc) { - if (osc->lookup_table != NULL) { + if(osc->lookup_table != NULL) { free(osc->lookup_table); } free(osc); } void dtmf_dolphin_filter_free(DTMFDolphinPulseFilter* pf) { - if (pf->lookup_table != NULL) { + if(pf->lookup_table != NULL) { free(pf->lookup_table); } free(pf); @@ -165,22 +167,19 @@ void dtmf_dolphin_audio_free(DTMFDolphinAudio* player) { current_player = NULL; } - bool generate_waveform(DTMFDolphinAudio* player, uint16_t buffer_index) { uint16_t* sample_buffer_start = &player->sample_buffer[buffer_index]; - for (size_t i = 0; i < player->half_buffer_length; i++) { + for(size_t i = 0; i < player->half_buffer_length; i++) { float data = 0; - if (player->osc2->period) { - data = \ - (sample_frame(player->osc1) / 2) + \ - (sample_frame(player->osc2) / 2); + if(player->osc2->period) { + data = (sample_frame(player->osc1) / 2) + (sample_frame(player->osc2) / 2); } else { data = (sample_frame(player->osc1)); } data *= sample_filter(player->filter) ? player->volume : 0.0; - data *= UINT8_MAX / 2; // scale -128..127 - data += UINT8_MAX / 2; // to unsigned + data *= UINT8_MAX / 2; // scale -128..127 + data += UINT8_MAX / 2; // to unsigned if(data < 0) { data = 0; @@ -196,8 +195,13 @@ bool generate_waveform(DTMFDolphinAudio* player, uint16_t buffer_index) { return true; } -bool dtmf_dolphin_audio_play_tones(float freq1, float freq2, uint16_t pulses, uint16_t pulse_ms, uint16_t gap_ms) { - if (current_player != NULL && current_player->playing) { +bool dtmf_dolphin_audio_play_tones( + float freq1, + float freq2, + uint16_t pulses, + uint16_t pulse_ms, + uint16_t gap_ms) { + if(current_player != NULL && current_player->playing) { // Cannot start playing while still playing something else return false; } @@ -213,7 +217,8 @@ bool dtmf_dolphin_audio_play_tones(float freq1, float freq2, uint16_t pulses, ui dtmf_dolphin_speaker_init(); dtmf_dolphin_dma_init((uint32_t)current_player->sample_buffer, current_player->buffer_length); - furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, dtmf_dolphin_audio_dma_isr, current_player->queue); + furi_hal_interrupt_set_isr( + FuriHalInterruptIdDma1Ch1, dtmf_dolphin_audio_dma_isr, current_player->queue); dtmf_dolphin_dma_start(); dtmf_dolphin_speaker_start(); @@ -222,11 +227,12 @@ bool dtmf_dolphin_audio_play_tones(float freq1, float freq2, uint16_t pulses, ui } bool dtmf_dolphin_audio_stop_tones() { - if (current_player != NULL && !current_player->playing) { + if(current_player != NULL && !current_player->playing) { // Can't stop a player that isn't playing. return false; } - while(current_player->filter->offset > 0 && current_player->filter->offset < current_player->filter->duration) { + while(current_player->filter->offset > 0 && + current_player->filter->offset < current_player->filter->duration) { // run remaining ticks if needed to complete filter sequence dtmf_dolphin_audio_handle_tick(); } @@ -236,20 +242,20 @@ bool dtmf_dolphin_audio_stop_tones() { furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL); dtmf_dolphin_audio_free(current_player); - + return true; } bool dtmf_dolphin_audio_handle_tick() { bool handled = false; - if (current_player) { + if(current_player) { DTMFDolphinCustomEvent event; if(furi_message_queue_get(current_player->queue, &event, 250) == FuriStatusOk) { if(event.type == DTMFDolphinEventDMAHalfTransfer) { generate_waveform(current_player, 0); handled = true; - } else if (event.type == DTMFDolphinEventDMAFullTransfer) { + } else if(event.type == DTMFDolphinEventDMAFullTransfer) { generate_waveform(current_player, current_player->half_buffer_length); handled = true; } diff --git a/dtmf_dolphin_audio.h b/dtmf_dolphin_audio.h index 6109eed1bb2..2dd1d6eb6ec 100644 --- a/dtmf_dolphin_audio.h +++ b/dtmf_dolphin_audio.h @@ -24,13 +24,13 @@ typedef struct { typedef struct { size_t buffer_length; size_t half_buffer_length; - uint8_t *buffer_buffer; - uint16_t *sample_buffer; + uint8_t* buffer_buffer; + uint16_t* sample_buffer; float volume; - FuriMessageQueue *queue; - DTMFDolphinOsc *osc1; - DTMFDolphinOsc *osc2; - DTMFDolphinPulseFilter *filter; + FuriMessageQueue* queue; + DTMFDolphinOsc* osc1; + DTMFDolphinOsc* osc2; + DTMFDolphinPulseFilter* filter; bool playing; } DTMFDolphinAudio; @@ -42,7 +42,12 @@ void dtmf_dolphin_audio_free(DTMFDolphinAudio* player); void dtmf_dolphin_osc_free(DTMFDolphinOsc* osc); -bool dtmf_dolphin_audio_play_tones(float freq1, float freq2, uint16_t pulses, uint16_t pulse_ms, uint16_t gap_ms); +bool dtmf_dolphin_audio_play_tones( + float freq1, + float freq2, + uint16_t pulses, + uint16_t pulse_ms, + uint16_t gap_ms); bool dtmf_dolphin_audio_stop_tones(); diff --git a/dtmf_dolphin_data.c b/dtmf_dolphin_data.c index 3f4456ddcb6..72386b83d66 100644 --- a/dtmf_dolphin_data.c +++ b/dtmf_dolphin_data.c @@ -7,13 +7,13 @@ typedef struct { } DTMFDolphinTonePos; typedef struct { - const char *name; + const char* name; const float frequency_1; const float frequency_2; const DTMFDolphinTonePos pos; - const uint16_t pulses; // for Redbox - const uint16_t pulse_ms; // for Redbox - const uint16_t gap_duration; // for Redbox + const uint16_t pulses; // for Redbox + const uint16_t pulse_ms; // for Redbox + const uint16_t gap_duration; // for Redbox } DTMFDolphinTones; typedef struct { @@ -44,52 +44,48 @@ DTMFDolphinSceneData DTMFDolphinSceneDataDialer = { {"0", 941.0, 1336.0, {3, 1, 1}, 0, 0, 0}, {"#", 941.0, 1477.0, {3, 2, 1}, 0, 0, 0}, {"D", 941.0, 1633.0, {3, 3, 1}, 0, 0, 0}, - } -}; + }}; DTMFDolphinSceneData DTMFDolphinSceneDataBluebox = { .name = "Bluebox", .block = DTMF_DOLPHIN_TONE_BLOCK_BLUEBOX, .tone_count = 13, .tones = { - {"1", 700.0, 900.0, {0, 0, 1}, 0, 0, 0}, - {"2", 700.0, 1100.0, {0, 1, 1}, 0, 0, 0}, - {"3", 900.0, 1100.0, {0, 2, 1}, 0, 0, 0}, - {"4", 700.0, 1300.0, {1, 0, 1}, 0, 0, 0}, - {"5", 900.0, 1300.0, {1, 1, 1}, 0, 0, 0}, - {"6", 1100.0, 1300.0, {1, 2, 1}, 0, 0, 0}, - {"7", 700.0, 1500.0, {2, 0, 1}, 0, 0, 0}, - {"8", 900.0, 1500.0, {2, 1, 1}, 0, 0, 0}, - {"9", 1100.0, 1500.0, {2, 2, 1}, 0, 0, 0}, - {"0", 1300.0, 1500.0, {3, 1, 1}, 0, 0, 0}, - {"KP", 1100.0, 1700.0, {0, 3, 2}, 0, 0, 0}, - {"ST", 1500.0, 1700.0, {1, 3, 2}, 0, 0, 0}, - {"2600", 2600.0, 0.0, {3, 2, 3}, 0, 0, 0}, - } -}; + {"1", 700.0, 900.0, {0, 0, 1}, 0, 0, 0}, + {"2", 700.0, 1100.0, {0, 1, 1}, 0, 0, 0}, + {"3", 900.0, 1100.0, {0, 2, 1}, 0, 0, 0}, + {"4", 700.0, 1300.0, {1, 0, 1}, 0, 0, 0}, + {"5", 900.0, 1300.0, {1, 1, 1}, 0, 0, 0}, + {"6", 1100.0, 1300.0, {1, 2, 1}, 0, 0, 0}, + {"7", 700.0, 1500.0, {2, 0, 1}, 0, 0, 0}, + {"8", 900.0, 1500.0, {2, 1, 1}, 0, 0, 0}, + {"9", 1100.0, 1500.0, {2, 2, 1}, 0, 0, 0}, + {"0", 1300.0, 1500.0, {3, 1, 1}, 0, 0, 0}, + {"KP", 1100.0, 1700.0, {0, 3, 2}, 0, 0, 0}, + {"ST", 1500.0, 1700.0, {1, 3, 2}, 0, 0, 0}, + {"2600", 2600.0, 0.0, {3, 2, 3}, 0, 0, 0}, + }}; DTMFDolphinSceneData DTMFDolphinSceneDataRedboxUS = { .name = "Redbox (US)", .block = DTMF_DOLPHIN_TONE_BLOCK_REDBOX_US, .tone_count = 4, .tones = { - {"Nickel", 1700.0, 2200.0, {0, 0, 5}, 1, 66, 0}, - {"Dime", 1700.0, 2200.0, {1, 0, 5}, 2, 66, 66}, + {"Nickel", 1700.0, 2200.0, {0, 0, 5}, 1, 66, 0}, + {"Dime", 1700.0, 2200.0, {1, 0, 5}, 2, 66, 66}, {"Quarter", 1700.0, 2200.0, {2, 0, 5}, 5, 33, 33}, - {"Dollar", 1700.0, 2200.0, {3, 0, 5}, 1, 650, 0}, - } -}; + {"Dollar", 1700.0, 2200.0, {3, 0, 5}, 1, 650, 0}, + }}; DTMFDolphinSceneData DTMFDolphinSceneDataRedboxCA = { .name = "Redbox (CA)", .block = DTMF_DOLPHIN_TONE_BLOCK_REDBOX_CA, .tone_count = 3, .tones = { - {"Nickel", 2200.0, 0.0, {0, 0, 5}, 1, 66, 0}, - {"Dime", 2200.0, 0.0, {1, 0, 5}, 2, 66, 66}, - {"Quarter", 2200.0, 0.0, {2, 0, 5}, 5, 33, 33}, - } -}; + {"Nickel", 2200.0, 0.0, {0, 0, 5}, 1, 66, 0}, + {"Dime", 2200.0, 0.0, {1, 0, 5}, 2, 66, 66}, + {"Quarter", 2200.0, 0.0, {2, 0, 5}, 5, 33, 33}, + }}; DTMFDolphinSceneData DTMFDolphinSceneDataRedboxUK = { .name = "Redbox (UK)", @@ -98,28 +94,25 @@ DTMFDolphinSceneData DTMFDolphinSceneDataRedboxUK = { .tones = { {"10p", 1000.0, 0.0, {0, 0, 5}, 1, 200, 0}, {"50p", 1000.0, 0.0, {1, 0, 5}, 1, 350, 0}, - } -}; + }}; DTMFDolphinSceneData DTMFDolphinSceneDataMisc = { .name = "Misc", .block = DTMF_DOLPHIN_TONE_BLOCK_MISC, .tone_count = 3, .tones = { - {"CCITT 11", 700.0, 1700.0, {0, 0, 5}, 0, 0, 0}, - {"CCITT 12", 900.0, 1700.0, {1, 0, 5}, 0, 0, 0}, + {"CCITT 11", 700.0, 1700.0, {0, 0, 5}, 0, 0, 0}, + {"CCITT 12", 900.0, 1700.0, {1, 0, 5}, 0, 0, 0}, {"CCITT KP2", 1300.0, 1700.0, {2, 0, 5}, 0, 0, 0}, - } -}; + }}; DTMFDolphinToneSection current_section; -DTMFDolphinSceneData *current_scene_data; +DTMFDolphinSceneData* current_scene_data; void dtmf_dolphin_data_set_current_section(DTMFDolphinToneSection section) { current_section = section; - switch (current_section) - { + switch(current_section) { case DTMF_DOLPHIN_TONE_BLOCK_BLUEBOX: current_scene_data = &DTMFDolphinSceneDataBluebox; break; @@ -128,7 +121,7 @@ void dtmf_dolphin_data_set_current_section(DTMFDolphinToneSection section) { break; case DTMF_DOLPHIN_TONE_BLOCK_REDBOX_CA: current_scene_data = &DTMFDolphinSceneDataRedboxCA; - break; + break; case DTMF_DOLPHIN_TONE_BLOCK_REDBOX_UK: current_scene_data = &DTMFDolphinSceneDataRedboxUK; break; @@ -145,14 +138,14 @@ DTMFDolphinToneSection dtmf_dolphin_data_get_current_section() { return current_section; } -DTMFDolphinSceneData *dtmf_dolphin_data_get_current_scene_data() { +DTMFDolphinSceneData* dtmf_dolphin_data_get_current_scene_data() { return current_scene_data; } -bool dtmf_dolphin_data_get_tone_frequencies(float *freq1, float *freq2, uint8_t row, uint8_t col) { - for (size_t i = 0; i < current_scene_data->tone_count; i++) { +bool dtmf_dolphin_data_get_tone_frequencies(float* freq1, float* freq2, uint8_t row, uint8_t col) { + for(size_t i = 0; i < current_scene_data->tone_count; i++) { DTMFDolphinTones tones = current_scene_data->tones[i]; - if (tones.pos.row == row && tones.pos.col == col) { + if(tones.pos.row == row && tones.pos.col == col) { freq1[0] = tones.frequency_1; freq2[0] = tones.frequency_2; return true; @@ -161,10 +154,15 @@ bool dtmf_dolphin_data_get_tone_frequencies(float *freq1, float *freq2, uint8_t return false; } -bool dtmf_dolphin_data_get_filter_data(uint16_t *pulses, uint16_t *pulse_ms, uint16_t *gap_ms, uint8_t row, uint8_t col) { - for (size_t i = 0; i < current_scene_data->tone_count; i++) { +bool dtmf_dolphin_data_get_filter_data( + uint16_t* pulses, + uint16_t* pulse_ms, + uint16_t* gap_ms, + uint8_t row, + uint8_t col) { + for(size_t i = 0; i < current_scene_data->tone_count; i++) { DTMFDolphinTones tones = current_scene_data->tones[i]; - if (tones.pos.row == row && tones.pos.col == col) { + if(tones.pos.row == row && tones.pos.col == col) { pulses[0] = tones.pulses; pulse_ms[0] = tones.pulse_ms; gap_ms[0] = tones.gap_duration; @@ -175,9 +173,9 @@ bool dtmf_dolphin_data_get_filter_data(uint16_t *pulses, uint16_t *pulse_ms, uin } const char* dtmf_dolphin_data_get_tone_name(uint8_t row, uint8_t col) { - for (size_t i = 0; i < current_scene_data->tone_count; i++) { + for(size_t i = 0; i < current_scene_data->tone_count; i++) { DTMFDolphinTones tones = current_scene_data->tones[i]; - if (tones.pos.row == row && tones.pos.col == col) { + if(tones.pos.row == row && tones.pos.col == col) { return tones.name; } } @@ -185,7 +183,7 @@ const char* dtmf_dolphin_data_get_tone_name(uint8_t row, uint8_t col) { } const char* dtmf_dolphin_data_get_current_section_name() { - if (current_scene_data) { + if(current_scene_data) { return current_scene_data->name; } return NULL; @@ -195,27 +193,26 @@ void dtmf_dolphin_tone_get_max_pos(uint8_t* max_rows, uint8_t* max_cols, uint8_t max_rows[0] = 0; max_cols[0] = 0; max_span[0] = 0; - uint8_t tmp_rowspan[5] = { 0, 0, 0, 0, 0 }; - for (size_t i = 0; i < current_scene_data->tone_count; i++) { + uint8_t tmp_rowspan[5] = {0, 0, 0, 0, 0}; + for(size_t i = 0; i < current_scene_data->tone_count; i++) { DTMFDolphinTones tones = current_scene_data->tones[i]; - if (tones.pos.row > max_rows[0]) { + if(tones.pos.row > max_rows[0]) { max_rows[0] = tones.pos.row; } - if (tones.pos.col > max_cols[0]) { + if(tones.pos.col > max_cols[0]) { max_cols[0] = tones.pos.col; } tmp_rowspan[tones.pos.row] += tones.pos.span; - if (tmp_rowspan[tones.pos.row] > max_span[0]) - max_span[0] = tmp_rowspan[tones.pos.row]; + if(tmp_rowspan[tones.pos.row] > max_span[0]) max_span[0] = tmp_rowspan[tones.pos.row]; } max_rows[0]++; max_cols[0]++; } uint8_t dtmf_dolphin_get_tone_span(uint8_t row, uint8_t col) { - for (size_t i = 0; i < current_scene_data->tone_count; i++) { + for(size_t i = 0; i < current_scene_data->tone_count; i++) { DTMFDolphinTones tones = current_scene_data->tones[i]; - if (tones.pos.row == row && tones.pos.col == col) { + if(tones.pos.row == row && tones.pos.col == col) { return tones.pos.span; } } diff --git a/dtmf_dolphin_data.h b/dtmf_dolphin_data.h index fcf072c77e1..56ceaf03dbd 100644 --- a/dtmf_dolphin_data.h +++ b/dtmf_dolphin_data.h @@ -10,6 +10,7 @@ typedef enum { DTMF_DOLPHIN_TONE_BLOCK_BLUEBOX, DTMF_DOLPHIN_TONE_BLOCK_REDBOX_US, DTMF_DOLPHIN_TONE_BLOCK_REDBOX_UK, + DTMF_DOLPHIN_TONE_BLOCK_REDBOX_CA, DTMF_DOLPHIN_TONE_BLOCK_MISC, } DTMFDolphinToneSection; @@ -17,9 +18,14 @@ void dtmf_dolphin_data_set_current_section(DTMFDolphinToneSection section); DTMFDolphinToneSection dtmf_dolphin_data_get_current_section(); -bool dtmf_dolphin_data_get_tone_frequencies(float *freq1, float *freq2, uint8_t row, uint8_t col); +bool dtmf_dolphin_data_get_tone_frequencies(float* freq1, float* freq2, uint8_t row, uint8_t col); -bool dtmf_dolphin_data_get_filter_data(uint16_t *pulses, uint16_t *pulse_ms, uint16_t *gap_ms, uint8_t row, uint8_t col); +bool dtmf_dolphin_data_get_filter_data( + uint16_t* pulses, + uint16_t* pulse_ms, + uint16_t* gap_ms, + uint8_t row, + uint8_t col); const char* dtmf_dolphin_data_get_tone_name(uint8_t row, uint8_t col); diff --git a/dtmf_dolphin_event.h b/dtmf_dolphin_event.h index 75f5bb274e5..525d0eb044d 100644 --- a/dtmf_dolphin_event.h +++ b/dtmf_dolphin_event.h @@ -8,6 +8,7 @@ typedef enum { DTMFDolphinEventStartBluebox, DTMFDolphinEventStartRedboxUS, DTMFDolphinEventStartRedboxUK, + DTMFDolphinEventStartRedboxCA, DTMFDolphinEventStartMisc, DTMFDolphinEventPlayTones, DTMFDolphinEventStopTones, diff --git a/dtmf_dolphin_i.h b/dtmf_dolphin_i.h index 2a0de1b418a..f8ae1530fc0 100644 --- a/dtmf_dolphin_i.h +++ b/dtmf_dolphin_i.h @@ -17,12 +17,12 @@ #define TAG "DTMFDolphin" - enum DTMFDolphinSceneState { DTMFDolphinSceneStateDialer, DTMFDolphinSceneStateBluebox, DTMFDolphinSceneStateRedboxUS, DTMFDolphinSceneStateRedboxUK, + DTMFDolphinSceneStateRedboxCA, DTMFDolphinSceneStateMisc, }; @@ -39,7 +39,4 @@ typedef struct { NotificationApp* notification; } DTMFDolphinApp; -typedef enum { - DTMFDolphinViewMainMenu, - DTMFDolphinViewDialer -} DTMFDolphinView; +typedef enum { DTMFDolphinViewMainMenu, DTMFDolphinViewDialer } DTMFDolphinView; diff --git a/scenes/dtmf_dolphin_scene_dialer.c b/scenes/dtmf_dolphin_scene_dialer.c index 2c24918ba6f..06da595e0ca 100644 --- a/scenes/dtmf_dolphin_scene_dialer.c +++ b/scenes/dtmf_dolphin_scene_dialer.c @@ -2,23 +2,24 @@ // #include "../dtmf_dolphin_data.h" // #include "../dtmf_dolphin_audio.h" - -void dtmf_dolphin_scene_dialer_on_enter(void *context) { +void dtmf_dolphin_scene_dialer_on_enter(void* context) { DTMFDolphinApp* app = context; DTMFDolphinScene scene_id = DTMFDolphinSceneDialer; enum DTMFDolphinSceneState state = scene_manager_get_scene_state(app->scene_manager, scene_id); - switch (state) - { + switch(state) { case DTMFDolphinSceneStateBluebox: dtmf_dolphin_data_set_current_section(DTMF_DOLPHIN_TONE_BLOCK_BLUEBOX); - break; + break; case DTMFDolphinSceneStateRedboxUS: dtmf_dolphin_data_set_current_section(DTMF_DOLPHIN_TONE_BLOCK_REDBOX_US); break; case DTMFDolphinSceneStateRedboxUK: dtmf_dolphin_data_set_current_section(DTMF_DOLPHIN_TONE_BLOCK_REDBOX_UK); break; + case DTMFDolphinSceneStateRedboxCA: + dtmf_dolphin_data_set_current_section(DTMF_DOLPHIN_TONE_BLOCK_REDBOX_CA); + break; case DTMFDolphinSceneStateMisc: dtmf_dolphin_data_set_current_section(DTMF_DOLPHIN_TONE_BLOCK_MISC); break; diff --git a/scenes/dtmf_dolphin_scene_start.c b/scenes/dtmf_dolphin_scene_start.c index cfd85b2f65e..484e9e8eb45 100644 --- a/scenes/dtmf_dolphin_scene_start.c +++ b/scenes/dtmf_dolphin_scene_start.c @@ -3,8 +3,7 @@ static void dtmf_dolphin_scene_start_main_menu_enter_callback(void* context, uint32_t index) { DTMFDolphinApp* app = context; uint8_t cust_event = 255; - switch (index) - { + switch(index) { case 0: cust_event = DTMFDolphinEventStartDialer; break; @@ -18,16 +17,16 @@ static void dtmf_dolphin_scene_start_main_menu_enter_callback(void* context, uin cust_event = DTMFDolphinEventStartRedboxUK; break; case 4: + cust_event = DTMFDolphinEventStartRedboxCA; + break; + case 5: cust_event = DTMFDolphinEventStartMisc; break; default: return; } - view_dispatcher_send_custom_event( - app->view_dispatcher, - cust_event - ); + view_dispatcher_send_custom_event(app->view_dispatcher, cust_event); } void dtmf_dolphin_scene_start_on_enter(void* context) { @@ -36,23 +35,19 @@ void dtmf_dolphin_scene_start_on_enter(void* context) { // VariableItem* item; variable_item_list_set_enter_callback( - var_item_list, - dtmf_dolphin_scene_start_main_menu_enter_callback, - app); + var_item_list, dtmf_dolphin_scene_start_main_menu_enter_callback, app); variable_item_list_add(var_item_list, "Dialer", 0, NULL, context); variable_item_list_add(var_item_list, "Bluebox", 0, NULL, context); variable_item_list_add(var_item_list, "Redbox (US)", 0, NULL, context); variable_item_list_add(var_item_list, "Redbox (UK)", 0, NULL, context); + variable_item_list_add(var_item_list, "Redbox (CA)", 0, NULL, context); variable_item_list_add(var_item_list, "Misc", 0, NULL, context); variable_item_list_set_selected_item( - var_item_list, - scene_manager_get_scene_state(app->scene_manager, DTMFDolphinSceneStart)); + var_item_list, scene_manager_get_scene_state(app->scene_manager, DTMFDolphinSceneStart)); - view_dispatcher_switch_to_view( - app->view_dispatcher, - DTMFDolphinViewMainMenu); + view_dispatcher_switch_to_view(app->view_dispatcher, DTMFDolphinViewMainMenu); } bool dtmf_dolphin_scene_start_on_event(void* context, SceneManagerEvent event) { @@ -63,8 +58,7 @@ bool dtmf_dolphin_scene_start_on_event(void* context, SceneManagerEvent event) { if(event.type == SceneManagerEventTypeCustom) { uint8_t sc_state; - switch (event.event) - { + switch(event.event) { case DTMFDolphinEventStartDialer: sc_state = DTMFDolphinSceneStateDialer; break; @@ -77,6 +71,9 @@ bool dtmf_dolphin_scene_start_on_event(void* context, SceneManagerEvent event) { case DTMFDolphinEventStartRedboxUK: sc_state = DTMFDolphinSceneStateRedboxUK; break; + case DTMFDolphinEventStartRedboxCA: + sc_state = DTMFDolphinSceneStateRedboxCA; + break; case DTMFDolphinEventStartMisc: sc_state = DTMFDolphinSceneStateMisc; break; diff --git a/views/dtmf_dolphin_common.h b/views/dtmf_dolphin_common.h index 855978d2c2b..f2f4838d61c 100644 --- a/views/dtmf_dolphin_common.h +++ b/views/dtmf_dolphin_common.h @@ -7,4 +7,4 @@ #define DTMF_DOLPHIN_NUMPAD_Y 14 #define DTMF_DOLPHIN_BUTTON_WIDTH 13 #define DTMF_DOLPHIN_BUTTON_HEIGHT 13 -#define DTMF_DOLPHIN_BUTTON_PADDING 1 // all sides +#define DTMF_DOLPHIN_BUTTON_PADDING 1 // all sides diff --git a/views/dtmf_dolphin_dialer.c b/views/dtmf_dolphin_dialer.c index 427efb6c41b..bdffa231331 100644 --- a/views/dtmf_dolphin_dialer.c +++ b/views/dtmf_dolphin_dialer.c @@ -24,53 +24,55 @@ static bool dtmf_dolphin_dialer_process_up(DTMFDolphinDialer* dtmf_dolphin_diale static bool dtmf_dolphin_dialer_process_down(DTMFDolphinDialer* dtmf_dolphin_dialer); static bool dtmf_dolphin_dialer_process_left(DTMFDolphinDialer* dtmf_dolphin_dialer); static bool dtmf_dolphin_dialer_process_right(DTMFDolphinDialer* dtmf_dolphin_dialer); -static bool dtmf_dolphin_dialer_process_ok(DTMFDolphinDialer* dtmf_dolphin_dialer, InputEvent* event); +static bool + dtmf_dolphin_dialer_process_ok(DTMFDolphinDialer* dtmf_dolphin_dialer, InputEvent* event); void draw_button(Canvas* canvas, uint8_t row, uint8_t col, bool invert) { - - uint8_t left = DTMF_DOLPHIN_NUMPAD_X + \ - // ((col + 1) * DTMF_DOLPHIN_BUTTON_PADDING) + - (col * DTMF_DOLPHIN_BUTTON_WIDTH); - // (col * DTMF_DOLPHIN_BUTTON_PADDING); - uint8_t top = DTMF_DOLPHIN_NUMPAD_Y + \ - // ((row + 1) * DTMF_DOLPHIN_BUTTON_PADDING) + - (row * DTMF_DOLPHIN_BUTTON_HEIGHT); - // (row * DTMF_DOLPHIN_BUTTON_PADDING); + uint8_t left = DTMF_DOLPHIN_NUMPAD_X + // ((col + 1) * DTMF_DOLPHIN_BUTTON_PADDING) + + (col * DTMF_DOLPHIN_BUTTON_WIDTH); + // (col * DTMF_DOLPHIN_BUTTON_PADDING); + uint8_t top = DTMF_DOLPHIN_NUMPAD_Y + // ((row + 1) * DTMF_DOLPHIN_BUTTON_PADDING) + + (row * DTMF_DOLPHIN_BUTTON_HEIGHT); + // (row * DTMF_DOLPHIN_BUTTON_PADDING); uint8_t span = dtmf_dolphin_get_tone_span(row, col); - if (span == 0) { + if(span == 0) { return; } canvas_set_color(canvas, ColorBlack); - - if (invert) - canvas_draw_rbox(canvas, left, top, + + if(invert) + canvas_draw_rbox( + canvas, + left, + top, (DTMF_DOLPHIN_BUTTON_WIDTH * span) - (DTMF_DOLPHIN_BUTTON_PADDING * 2), DTMF_DOLPHIN_BUTTON_HEIGHT - (DTMF_DOLPHIN_BUTTON_PADDING * 2), 2); else - canvas_draw_rframe(canvas, left, top, + canvas_draw_rframe( + canvas, + left, + top, (DTMF_DOLPHIN_BUTTON_WIDTH * span) - (DTMF_DOLPHIN_BUTTON_PADDING * 2), - DTMF_DOLPHIN_BUTTON_HEIGHT- (DTMF_DOLPHIN_BUTTON_PADDING * 2), + DTMF_DOLPHIN_BUTTON_HEIGHT - (DTMF_DOLPHIN_BUTTON_PADDING * 2), 2); - if (invert) - canvas_invert_color(canvas); - + if(invert) canvas_invert_color(canvas); canvas_set_font(canvas, FontSecondary); // canvas_set_color(canvas, invert ? ColorWhite : ColorBlack); - canvas_draw_str_aligned(canvas, - left - 1 + (int) ((DTMF_DOLPHIN_BUTTON_WIDTH * span) / 2), - top + (int) (DTMF_DOLPHIN_BUTTON_HEIGHT / 2), + canvas_draw_str_aligned( + canvas, + left - 1 + (int)((DTMF_DOLPHIN_BUTTON_WIDTH * span) / 2), + top + (int)(DTMF_DOLPHIN_BUTTON_HEIGHT / 2), AlignCenter, AlignCenter, dtmf_dolphin_data_get_tone_name(row, col)); - if (invert) - canvas_invert_color(canvas); + if(invert) canvas_invert_color(canvas); } void draw_dialer(Canvas* canvas, void* _model) { @@ -82,9 +84,9 @@ void draw_dialer(Canvas* canvas, void* _model) { canvas_set_font(canvas, FontSecondary); - for (int r = 0; r < max_rows; r++) { - for (int c = 0; c < max_cols; c++) { - if (model->row == r && model->col == c) + for(int r = 0; r < max_rows; r++) { + for(int c = 0; c < max_cols; c++) { + if(model->row == r && model->col == c) draw_button(canvas, r, c, true); else draw_button(canvas, r, c, false); @@ -92,21 +94,22 @@ void draw_dialer(Canvas* canvas, void* _model) { } } -void update_frequencies(DTMFDolphinDialerModel *model) { +void update_frequencies(DTMFDolphinDialerModel* model) { dtmf_dolphin_data_get_tone_frequencies(&model->freq1, &model->freq2, model->row, model->col); - dtmf_dolphin_data_get_filter_data(&model->pulses, &model->pulse_ms, &model->gap_ms, model->row, model->col); + dtmf_dolphin_data_get_filter_data( + &model->pulses, &model->pulse_ms, &model->gap_ms, model->row, model->col); } static void dtmf_dolphin_dialer_draw_callback(Canvas* canvas, void* _model) { DTMFDolphinDialerModel* model = _model; - if (model->playing) { + if(model->playing) { // Leverage the prioritized draw callback to handle // the DMA so that it doesn't skip. dtmf_dolphin_audio_handle_tick(); // Don't do any drawing if audio is playing. canvas_set_font(canvas, FontPrimary); elements_multiline_text_aligned( - canvas, + canvas, canvas_width(canvas) / 2, canvas_height(canvas) / 2, AlignCenter, @@ -122,46 +125,41 @@ static void dtmf_dolphin_dialer_draw_callback(Canvas* canvas, void* _model) { canvas_set_font(canvas, FontPrimary); elements_multiline_text(canvas, 2, 10, dtmf_dolphin_data_get_current_section_name()); - canvas_draw_line(canvas, - (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 1, 0, - (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 1, canvas_height(canvas)); + canvas_draw_line( + canvas, + (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 1, + 0, + (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 1, + canvas_height(canvas)); elements_multiline_text(canvas, (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 4, 10, "Detail"); - canvas_draw_line(canvas, 0, DTMF_DOLPHIN_NUMPAD_Y - 3, canvas_width(canvas), DTMF_DOLPHIN_NUMPAD_Y - 3); + canvas_draw_line( + canvas, 0, DTMF_DOLPHIN_NUMPAD_Y - 3, canvas_width(canvas), DTMF_DOLPHIN_NUMPAD_Y - 3); // elements_multiline_text_aligned(canvas, 64, 2, AlignCenter, AlignTop, "Dialer Mode"); draw_dialer(canvas, model); - FuriString *output = furi_string_alloc(); + FuriString* output = furi_string_alloc(); - if (model->freq1 && model->freq2) { + if(model->freq1 && model->freq2) { furi_string_cat_printf( output, "Dual Tone\nF1: %u Hz\nF2: %u Hz\n", - (unsigned int) model->freq1, - (unsigned int) model->freq2); - } else if (model->freq1) { - furi_string_cat_printf( - output, - "Single Tone\nF: %u Hz\n", - (unsigned int) model->freq1); + (unsigned int)model->freq1, + (unsigned int)model->freq2); + } else if(model->freq1) { + furi_string_cat_printf(output, "Single Tone\nF: %u Hz\n", (unsigned int)model->freq1); } canvas_set_font(canvas, FontSecondary); canvas_set_color(canvas, ColorBlack); - if (model->pulse_ms) { - furi_string_cat_printf( - output, - "P: %u * %u ms\n", - model->pulses, - model->pulse_ms); + if(model->pulse_ms) { + furi_string_cat_printf(output, "P: %u * %u ms\n", model->pulses, model->pulse_ms); } - if (model->gap_ms) { - furi_string_cat_printf( - output, - "Gaps: %u ms\n", - model->gap_ms); + if(model->gap_ms) { + furi_string_cat_printf(output, "Gaps: %u ms\n", model->gap_ms); } - elements_multiline_text(canvas, (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 4, 21, furi_string_get_cstr(output)); + elements_multiline_text( + canvas, (max_span * DTMF_DOLPHIN_BUTTON_WIDTH) + 4, 21, furi_string_get_cstr(output)); furi_string_free(output); } @@ -196,11 +194,11 @@ static bool dtmf_dolphin_dialer_process_up(DTMFDolphinDialer* dtmf_dolphin_diale { uint8_t span = 0; uint8_t cursor = model->row; - while (span == 0 && cursor > 0) { + while(span == 0 && cursor > 0) { cursor--; span = dtmf_dolphin_get_tone_span(cursor, model->col); } - if (span != 0) { + if(span != 0) { model->row = cursor; } }, @@ -224,7 +222,7 @@ static bool dtmf_dolphin_dialer_process_down(DTMFDolphinDialer* dtmf_dolphin_dia cursor++; span = dtmf_dolphin_get_tone_span(cursor, model->col); } - if (span != 0) { + if(span != 0) { model->row = cursor; } }, @@ -239,11 +237,11 @@ static bool dtmf_dolphin_dialer_process_left(DTMFDolphinDialer* dtmf_dolphin_dia { uint8_t span = 0; uint8_t cursor = model->col; - while (span == 0 && cursor > 0) { + while(span == 0 && cursor > 0) { cursor--; span = dtmf_dolphin_get_tone_span(model->row, cursor); } - if (span != 0) { + if(span != 0) { model->col = cursor; } }, @@ -267,7 +265,7 @@ static bool dtmf_dolphin_dialer_process_right(DTMFDolphinDialer* dtmf_dolphin_di cursor++; span = dtmf_dolphin_get_tone_span(model->row, cursor); } - if (span != 0) { + if(span != 0) { model->col = cursor; } }, @@ -275,16 +273,18 @@ static bool dtmf_dolphin_dialer_process_right(DTMFDolphinDialer* dtmf_dolphin_di return true; } -static bool dtmf_dolphin_dialer_process_ok(DTMFDolphinDialer* dtmf_dolphin_dialer, InputEvent* event) { +static bool + dtmf_dolphin_dialer_process_ok(DTMFDolphinDialer* dtmf_dolphin_dialer, InputEvent* event) { bool consumed = false; with_view_model( dtmf_dolphin_dialer->view, DTMFDolphinDialerModel * model, { - if (event->type == InputTypePress) { - model->playing = dtmf_dolphin_audio_play_tones(model->freq1, model->freq2, model->pulses, model->pulse_ms, model->gap_ms); - } else if (event->type == InputTypeRelease) { + if(event->type == InputTypePress) { + model->playing = dtmf_dolphin_audio_play_tones( + model->freq1, model->freq2, model->pulses, model->pulse_ms, model->gap_ms); + } else if(event->type == InputTypeRelease) { model->playing = !dtmf_dolphin_audio_stop_tones(); } }, @@ -308,15 +308,15 @@ static void dtmf_dolphin_dialer_enter_callback(void* context) { model->freq2 = 0.0; model->playing = false; }, - true - ); + true); } DTMFDolphinDialer* dtmf_dolphin_dialer_alloc() { DTMFDolphinDialer* dtmf_dolphin_dialer = malloc(sizeof(DTMFDolphinDialer)); dtmf_dolphin_dialer->view = view_alloc(); - view_allocate_model(dtmf_dolphin_dialer->view, ViewModelTypeLocking, sizeof(DTMFDolphinDialerModel)); + view_allocate_model( + dtmf_dolphin_dialer->view, ViewModelTypeLocking, sizeof(DTMFDolphinDialerModel)); with_view_model( dtmf_dolphin_dialer->view, @@ -329,8 +329,7 @@ DTMFDolphinDialer* dtmf_dolphin_dialer_alloc() { model->freq2 = 0.0; model->playing = false; }, - true - ); + true); view_set_context(dtmf_dolphin_dialer->view, dtmf_dolphin_dialer); view_set_draw_callback(dtmf_dolphin_dialer->view, dtmf_dolphin_dialer_draw_callback); @@ -349,4 +348,3 @@ View* dtmf_dolphin_dialer_get_view(DTMFDolphinDialer* dtmf_dolphin_dialer) { furi_assert(dtmf_dolphin_dialer); return dtmf_dolphin_dialer->view; } - diff --git a/views/dtmf_dolphin_dialer.h b/views/dtmf_dolphin_dialer.h index c52343ff0d9..1929afbc592 100644 --- a/views/dtmf_dolphin_dialer.h +++ b/views/dtmf_dolphin_dialer.h @@ -12,4 +12,7 @@ void dtmf_dolphin_dialer_free(DTMFDolphinDialer* dtmf_dolphin_dialer); View* dtmf_dolphin_dialer_get_view(DTMFDolphinDialer* dtmf_dolphin_dialer); -void dtmf_dolphin_dialer_set_ok_callback(DTMFDolphinDialer* dtmf_dolphin_dialer, DTMFDolphinDialerOkCallback callback, void* context); +void dtmf_dolphin_dialer_set_ok_callback( + DTMFDolphinDialer* dtmf_dolphin_dialer, + DTMFDolphinDialerOkCallback callback, + void* context);