# HG changeset patch # User Josef 'Jeff' Sipek # Date 1672376172 18000 # Thu Dec 29 23:56:12 2022 -0500 # Node ID e5ce75f6818ee852c1e5070b45c3d5453b5026c1 # Parent 88ab4b95dd4878fed9e01fa11e8e89011db89a06 Use symmetry to store only 1/4 of a sine wave This shrinks the sine_wave array by 190 bytes, but requires a bit more complex code to calculate any value which takes up 42 extra bytes of flash. So, overall we save 148 bytes of flash. text data bss dec hex filename 1530 2 33 1565 61d fmfox-atmega48p.elf (before) 1382 2 33 1417 589 fmfox-atmega48p.elf (after) Additionally, this fixes slight offset in the negative half-cycle. Previously, the mean of the sine wave was 127.5 instead of 128 as one would expect from a sine wave. Signed-off-by: Josef 'Jeff' Sipek diff --git a/fmfox.h b/fmfox.h --- a/fmfox.h +++ b/fmfox.h @@ -46,7 +46,7 @@ /* * Various tone sequences */ -extern const __flash uint8_t sine_wave[WAVE_STEPS]; +extern const __flash uint8_t sine_wave[WAVE_STEPS / 4 + 1]; extern const __flash uint8_t tones_fixed[10]; extern const __flash uint8_t tones_lfsr[16]; extern const __flash uint8_t tones_morse[2]; diff --git a/gen-wave.py b/gen-wave.py --- a/gen-wave.py +++ b/gen-wave.py @@ -32,7 +32,7 @@ print("#error \"WAVE_STEPS doesn't match gen-wave.py\"") print("#endif") print("const __flash uint8_t sine_wave[] = {") -for i in range(WAVE_STEPS): +for i in range(WAVE_STEPS // 4 + 1): print("[%u] = %u," % (i, 127 * math.sin(2 * math.pi * i / WAVE_STEPS) + 128)) print("};") diff --git a/main.c b/main.c --- a/main.c +++ b/main.c @@ -139,6 +139,38 @@ * Audio */ +static inline uint8_t get_wave(uint8_t idx) +{ + bool reverse; + bool negate; + + if (idx < (1 * WAVE_STEPS / 4)) { + reverse = false; + negate = false; + idx -= 0; + } else if (idx < (2 * WAVE_STEPS / 4)) { + reverse = true; + negate = false; + idx -= 1 * WAVE_STEPS / 4; + } else if (idx < (3 * WAVE_STEPS / 4)) { + reverse = false; + negate = true; + idx -= 2 * WAVE_STEPS / 4; + } else { + reverse = true; + negate = true; + idx -= 3 * WAVE_STEPS / 4; + } + + if (reverse) + idx = (WAVE_STEPS / 4) - idx; + + if (negate) + return 128 - sine_wave[idx] + 128; + + return sine_wave[idx]; +} + static inline uint8_t first_fixed_tone(void) { return 0; @@ -204,7 +236,7 @@ * sent through the DAC. The actual latching of the previous sample * is done in the assembly isr. */ - dac_write(sine_wave[phase]); + dac_write(get_wave(phase)); steps--; sample_num++;