Просмотр исходного кода

Better submenus, resetting audio buffer, mixed wavefoems

LTVA1 3 лет назад
Родитель
Сommit
054a61a378
8 измененных файлов с 194 добавлено и 1 удалено
  1. 2 0
      flizzer_tracker.h
  2. 1 0
      flizzer_tracker_hal.c
  3. 3 0
      init_deinit.c
  4. 1 0
      input/instrument.c
  5. 12 0
      input_event.c
  6. 164 1
      sound_engine/sound_engine_osc.c
  7. 10 0
      util.c
  8. 1 0
      util.h

+ 2 - 0
flizzer_tracker.h

@@ -134,11 +134,13 @@ typedef enum
 
 typedef enum
 {
+    SUBMENU_PATTERN_RETURN,
     SUBMENU_PATTERN_EXIT,
 } PatternSubmenuParams;
 
 typedef enum
 {
+    SUBMENU_INSTRUMENT_RETURN,
     SUBMENU_INSTRUMENT_EXIT,
 } InstrumentSubmenuParams;
 

+ 1 - 0
flizzer_tracker_hal.c

@@ -62,6 +62,7 @@ void sound_engine_PWM_timer_init(bool external_audio_output) // external audio o
     {
         bool unu = furi_hal_speaker_acquire(1000);
         UNUSED(unu);
+        furi_hal_gpio_init(&gpio_ext_pa6, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
     }
 
     LL_TIM_EnableAllOutputs(SPEAKER_PWM_TIMER);

+ 3 - 0
init_deinit.c

@@ -53,7 +53,10 @@ FlizzerTrackerApp *init_tracker(uint32_t sample_rate, uint8_t rate, bool externa
     tracker->pattern_submenu = submenu_alloc();
     tracker->instrument_submenu = submenu_alloc();
 
+    submenu_add_item(tracker->pattern_submenu, "Return", SUBMENU_PATTERN_RETURN, submenu_callback, tracker);
     submenu_add_item(tracker->pattern_submenu, "Exit", SUBMENU_PATTERN_EXIT, submenu_callback, tracker);
+
+    submenu_add_item(tracker->instrument_submenu, "Return", SUBMENU_INSTRUMENT_RETURN, submenu_callback, tracker);
     submenu_add_item(tracker->instrument_submenu, "Exit", SUBMENU_INSTRUMENT_EXIT, submenu_callback, tracker);
 
     view_dispatcher_add_view(tracker->view_dispatcher, VIEW_SUBMENU_PATTERN, submenu_get_view(tracker->pattern_submenu));

+ 1 - 0
input/instrument.c

@@ -420,6 +420,7 @@ void instrument_edit_event(FlizzerTrackerApp *tracker, FlizzerTrackerEvent *even
     if (event->input.key == InputKeyOk && event->input.type == InputTypeLong && !tracker->editing)
     {
         // play_song(tracker, true);
+        reset_buffer(&tracker->sound_engine);
         tracker_engine_set_song(&tracker->tracker_engine, NULL);
 
         Instrument *inst = tracker->song.instrument[tracker->current_instrument];

+ 12 - 0
input_event.c

@@ -10,6 +10,12 @@ void submenu_callback(void *context, uint32_t index)
         {
             switch (index)
             {
+                case SUBMENU_PATTERN_RETURN:
+                {
+                    view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER);
+                    break;
+                }
+
                 case SUBMENU_PATTERN_EXIT:
                 {
                     tracker->quit = true;
@@ -32,6 +38,12 @@ void submenu_callback(void *context, uint32_t index)
         {
             switch (index)
             {
+                case SUBMENU_INSTRUMENT_RETURN:
+                {
+                    view_dispatcher_switch_to_view(tracker->view_dispatcher, VIEW_TRACKER);
+                    break;
+                }
+
                 case SUBMENU_INSTRUMENT_EXIT:
                 {
                     tracker->quit = true;

+ 164 - 1
sound_engine/sound_engine_osc.c

@@ -17,7 +17,7 @@ static inline uint16_t sound_engine_triangle(uint32_t acc)
 
 static inline uint16_t sound_engine_sine(uint32_t acc, SoundEngine *sound_engine)
 {
-    return (sound_engine->sine_lut[(acc >> (ACC_BITS - SINE_LUT_BITDEPTH))] << (OUTPUT_BITS - SINE_LUT_BITDEPTH));
+    return ((uint16_t)sound_engine->sine_lut[(acc >> (ACC_BITS - SINE_LUT_BITDEPTH))] << (OUTPUT_BITS - SINE_LUT_BITDEPTH));
 }
 
 inline static void shift_lfsr(uint32_t *v, uint32_t tap_0, uint32_t tap_1)
@@ -86,6 +86,169 @@ uint16_t sound_engine_osc(SoundEngine *sound_engine, SoundEngineChannel *channel
             return sound_engine_sine(channel->accumulator, sound_engine);
             break;
         }
+
+        case (SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE):
+        case (SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE_METAL):
+        case (SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL):
+        {
+            return sound_engine_pulse(channel->accumulator, channel->pw) & sound_engine_noise(channel, prev_acc);
+        }
+
+        case (SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_NOISE):
+        case (SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_NOISE_METAL):
+        case (SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL):
+        {
+            return sound_engine_triangle(channel->accumulator) & sound_engine_noise(channel, prev_acc);
+        }
+
+        case (SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE):
+        {
+            return sound_engine_pulse(channel->accumulator, channel->pw) & sound_engine_triangle(channel->accumulator);
+        }
+
+        case (SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE):
+        case (SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE_METAL):
+        case (SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL):
+        {
+            return sound_engine_pulse(channel->accumulator, channel->pw) & sound_engine_noise(channel, prev_acc) & sound_engine_triangle(channel->accumulator);
+        }
+
+        case (SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE):
+        case (SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE_METAL):
+        case (SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL):
+        {
+            return sound_engine_saw(channel->accumulator) & sound_engine_noise(channel, prev_acc);
+        }
+
+        case (SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW):
+        {
+            return sound_engine_pulse(channel->accumulator, channel->pw) & sound_engine_saw(channel->accumulator);
+        }
+
+        case (SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE):
+        case (SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE_METAL):
+        case (SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL):
+        {
+            return sound_engine_pulse(channel->accumulator, channel->pw) & sound_engine_saw(channel->accumulator) & sound_engine_noise(channel, prev_acc);
+        }
+
+        case (SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW):
+        {
+            return sound_engine_triangle(channel->accumulator) & sound_engine_saw(channel->accumulator);
+        }
+
+        case (SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE):
+        case (SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE_METAL):
+        case (SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL):
+        {
+            return sound_engine_triangle(channel->accumulator) & sound_engine_saw(channel->accumulator) & sound_engine_noise(channel, prev_acc);
+        }
+
+        case (SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW):
+        {
+            return sound_engine_pulse(channel->accumulator, channel->pw) & sound_engine_triangle(channel->accumulator) & sound_engine_saw(channel->accumulator);
+        }
+
+        case (SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE):
+        case (SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE_METAL):
+        case (SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL):
+        {
+            return sound_engine_pulse(channel->accumulator, channel->pw) & sound_engine_triangle(channel->accumulator) & sound_engine_saw(channel->accumulator) & sound_engine_noise(channel, prev_acc);
+        }
+
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_NOISE):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_NOISE_METAL):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL):
+        {
+            return sound_engine_sine(channel->accumulator, sound_engine) & sound_engine_noise(channel, prev_acc);
+        }
+
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE):
+        {
+            return sound_engine_pulse(channel->accumulator, channel->pw) & sound_engine_sine(channel->accumulator, sound_engine);
+        }
+
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE_METAL):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL):
+        {
+            return sound_engine_pulse(channel->accumulator, channel->pw) & sound_engine_sine(channel->accumulator, sound_engine) & sound_engine_noise(channel, prev_acc);
+        }
+
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE):
+        {
+            return sound_engine_triangle(channel->accumulator) & sound_engine_sine(channel->accumulator, sound_engine);
+        }
+
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_NOISE):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_NOISE_METAL):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL):
+        {
+            return sound_engine_triangle(channel->accumulator) & sound_engine_sine(channel->accumulator, sound_engine) & sound_engine_noise(channel, prev_acc);
+        }
+
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_PULSE):
+        {
+            return sound_engine_pulse(channel->accumulator, channel->pw) & sound_engine_triangle(channel->accumulator) & sound_engine_sine(channel->accumulator, sound_engine);
+        }
+
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE_METAL):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_PULSE | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL):
+        {
+            return sound_engine_pulse(channel->accumulator, channel->pw) & sound_engine_triangle(channel->accumulator) & sound_engine_sine(channel->accumulator, sound_engine) & sound_engine_noise(channel, prev_acc);
+        }
+
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_SAW):
+        {
+            return sound_engine_saw(channel->accumulator) & sound_engine_sine(channel->accumulator, sound_engine);
+        }
+
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE_METAL):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL):
+        {
+            return sound_engine_saw(channel->accumulator) & sound_engine_sine(channel->accumulator, sound_engine) & sound_engine_noise(channel, prev_acc);
+        }
+
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW):
+        {
+            return sound_engine_pulse(channel->accumulator, channel->pw) & sound_engine_saw(channel->accumulator) & sound_engine_sine(channel->accumulator, sound_engine);
+        }
+
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE_METAL):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL):
+        {
+            return sound_engine_pulse(channel->accumulator, channel->pw) & sound_engine_saw(channel->accumulator) & sound_engine_sine(channel->accumulator, sound_engine) & sound_engine_noise(channel, prev_acc);
+        }
+
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW):
+        {
+            return sound_engine_saw(channel->accumulator) & sound_engine_triangle(channel->accumulator) & sound_engine_sine(channel->accumulator, sound_engine);
+        }
+
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE_METAL):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL):
+        {
+            return sound_engine_saw(channel->accumulator) & sound_engine_triangle(channel->accumulator) & sound_engine_sine(channel->accumulator, sound_engine) & sound_engine_noise(channel, prev_acc);
+        }
+
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW):
+        {
+            return sound_engine_saw(channel->accumulator) & sound_engine_pulse(channel->accumulator, channel->pw) & sound_engine_triangle(channel->accumulator) & sound_engine_sine(channel->accumulator, sound_engine);
+        }
+
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE_METAL):
+        case (SE_WAVEFORM_SINE | SE_WAVEFORM_PULSE | SE_WAVEFORM_TRIANGLE | SE_WAVEFORM_SAW | SE_WAVEFORM_NOISE | SE_WAVEFORM_NOISE_METAL):
+        {
+            return sound_engine_saw(channel->accumulator) & sound_engine_pulse(channel->accumulator, channel->pw) & sound_engine_triangle(channel->accumulator) & sound_engine_sine(channel->accumulator, sound_engine) & sound_engine_noise(channel, prev_acc);
+        }
+
+        default:
+            break;
     }
 
     return 0;

+ 10 - 0
util.c

@@ -30,8 +30,18 @@ void set_command(TrackerSongPatternStep *step, uint16_t command)
     step->command |= command & (0x7fff);
 }
 
+void reset_buffer(SoundEngine *sound_engine)
+{
+    for (uint16_t i = 0; i < sound_engine->audio_buffer_size; i++)
+    {
+        sound_engine->audio_buffer[i] = 512;
+    }
+}
+
 void play_song(FlizzerTrackerApp *tracker, bool from_cursor)
 {
+    reset_buffer(&tracker->sound_engine);
+
     tracker->tracker_engine.playing = true;
     tracker->was_editing = tracker->editing;
     tracker->editing = false;

+ 1 - 0
util.h

@@ -18,6 +18,7 @@ void set_instrument(TrackerSongPatternStep *step, uint8_t inst);
 void set_volume(TrackerSongPatternStep *step, uint8_t vol);
 void set_command(TrackerSongPatternStep *step, uint16_t command);
 
+void reset_buffer(SoundEngine *sound_engine);
 void play_song(FlizzerTrackerApp *tracker, bool from_cursor);
 void stop_song(FlizzerTrackerApp *tracker);