diff --git a/apps/pcmbuf.c b/apps/pcmbuf.c index e2b1d7f87b..91b9f1329b 100644 --- a/apps/pcmbuf.c +++ b/apps/pcmbuf.c @@ -104,6 +104,8 @@ static size_t pcmbuf_mix_sample IDATA_ATTR; static bool low_latency_mode = false; static bool pcmbuf_flush; +static int codec_thread_priority = 0; + extern struct thread_entry *codec_thread_p; /* Helpful macros for use in conditionals this assumes some of the above @@ -235,30 +237,37 @@ static inline void pcmbuf_add_chunk(void) audiobuffer_fillpos = 0; } +#ifdef HAVE_PRIORITY_SCHEDULING +static void boost_codec_thread(bool boost) +{ + if (boost) + { + if (codec_thread_priority == 0) + codec_thread_priority = thread_set_priority( + codec_thread_p, PRIORITY_REALTIME); + } + else if (codec_thread_priority != 0) + { + thread_set_priority(codec_thread_p, codec_thread_priority); + codec_thread_priority = 0; + } +} +#endif /* HAVE_PRIORITY_SCHEDULING */ + static void pcmbuf_under_watermark(void) { + /* Only codec thread initiates boost - voice boosts the cpu when playing + a clip */ + if (thread_get_current() == codec_thread_p) + { #ifdef HAVE_PRIORITY_SCHEDULING - static int old_priority = 0; - - if (LOW_DATA(2) && pcm_is_playing()) - { - if (!old_priority) - { - /* Buffer is critically low so override UI priority. */ - old_priority = thread_set_priority(codec_thread_p, - PRIORITY_REALTIME); - } - } - else if (old_priority) - { - /* Set back the original priority. */ - thread_set_priority(codec_thread_p, old_priority); - old_priority = 0; - } + /* If buffer is critically low, override UI priority, else + set back to the original priority. */ + boost_codec_thread(LOW_DATA(2) && pcm_is_playing()); #endif - - /* Fill audio buffer by boosting cpu */ - trigger_cpu_boost(); + /* Fill audio buffer by boosting cpu */ + trigger_cpu_boost(); + } /* Disable crossfade if < .5s of audio */ if (LOW_DATA(2)) @@ -364,6 +373,11 @@ void pcmbuf_play_stop(void) crossfade_init = false; crossfade_active = false; pcmbuf_flush = false; + +#ifdef HAVE_PRIORITY_SCHEDULING + /* Can unboost the codec thread here no matter who's calling */ + boost_codec_thread(false); +#endif } int pcmbuf_used_descs(void) { diff --git a/firmware/export/thread.h b/firmware/export/thread.h index 2ff4694159..3a979722b9 100644 --- a/firmware/export/thread.h +++ b/firmware/export/thread.h @@ -150,6 +150,7 @@ void wakeup_thread(struct thread_entry **thread); int thread_set_priority(struct thread_entry *thread, int priority); int thread_get_priority(struct thread_entry *thread); #endif +struct thread_entry * thread_get_current(void); void init_threads(void); int thread_stack_usage(const struct thread_entry *thread); int thread_get_status(const struct thread_entry *thread); diff --git a/firmware/thread.c b/firmware/thread.c index 281ab0fa54..614286c422 100644 --- a/firmware/thread.c +++ b/firmware/thread.c @@ -776,6 +776,11 @@ int thread_get_priority(struct thread_entry *thread) } #endif +struct thread_entry * thread_get_current(void) +{ + return cores[CURRENT_CORE].running; +} + void init_threads(void) { unsigned int core = CURRENT_CORE;