@@ -745,13 +745,16 @@ static int g_audio_monitor_count;
745745static jack_port_t * g_midi_in_port ;
746746static jack_position_t g_jack_pos ;
747747static bool g_jack_rolling ;
748+ static uint32_t g_jack_xruns ;
748749static volatile double g_transport_bpb ;
749750static volatile double g_transport_bpm ;
750751static volatile bool g_transport_reset ;
751752static volatile enum TransportSyncMode g_transport_sync_mode ;
752753static bool g_aggregated_midi_enabled ;
753754static bool g_processing_enabled ;
754755static bool g_verbose_debug ;
756+ static bool g_cpu_load_enabled ;
757+ static volatile bool g_cpu_load_trigger ;
755758
756759// Wall clock time since program startup
757760static uint64_t g_monotonic_frame_count = 0 ;
@@ -844,6 +847,7 @@ static void AllocatePortBuffers(effect_t* effect, int in_size, int out_size);
844847static int BufferSize (jack_nframes_t nframes , void * data );
845848static void FreeWheelMode (int starting , void * data );
846849static void PortRegistration (jack_port_id_t port_id , int reg , void * data );
850+ static int XRun (void * data );
847851static void RunPostPonedEvents (int ignored_effect_id );
848852static void * PostPonedEventsThread (void * arg );
849853#ifdef __MOD_DEVICES__
@@ -1121,6 +1125,15 @@ static void PortRegistration(jack_port_id_t port_id, int reg, void* data)
11211125 UNUSED_PARAM (data );
11221126}
11231127
1128+ static int XRun (void * data )
1129+ {
1130+ ++ g_jack_xruns ;
1131+
1132+ return 0 ;
1133+
1134+ UNUSED_PARAM (data );
1135+ }
1136+
11241137static bool ShouldIgnorePostPonedEffectEvent (int effect_id , postponed_cached_effect_events * cached_events )
11251138{
11261139 if (effect_id == cached_events -> last_effect_id )
@@ -1225,7 +1238,14 @@ static void RunPostPonedEvents(int ignored_effect_id)
12251238 list_splice_init (& g_rtsafe_list , & queue );
12261239 pthread_mutex_unlock (& g_rtsafe_mutex );
12271240
1228- if (list_empty (& queue ))
1241+ // fetch this value only once per run
1242+ const bool cpu_load_trigger = g_jack_global_client != NULL && g_cpu_load_trigger ;
1243+
1244+ if (cpu_load_trigger )
1245+ {
1246+ g_cpu_load_trigger = false;
1247+ }
1248+ else if (list_empty (& queue ))
12291249 {
12301250 // nothing to do
12311251 if (g_verbose_debug ) {
@@ -1260,7 +1280,7 @@ static void RunPostPonedEvents(int ignored_effect_id)
12601280 INIT_LIST_HEAD (& cached_output_mon .symbols .siblings );
12611281
12621282 // if all we have are jack_midi_connect requests, do not send feedback to server
1263- bool got_only_jack_midi_requests = true ;
1283+ bool got_only_jack_midi_requests = ! cpu_load_trigger ;
12641284
12651285 if (g_verbose_debug ) {
12661286 puts ("DEBUG: RunPostPonedEvents() Before the queue iteration" );
@@ -1580,6 +1600,18 @@ static void RunPostPonedEvents(int ignored_effect_id)
15801600 }
15811601 }
15821602
1603+ if (cpu_load_trigger )
1604+ {
1605+ snprintf (buf , FEEDBACK_BUF_SIZE , "cpu_load %f %f %d" , jack_cpu_load (g_jack_global_client ),
1606+ #ifdef HAVE_JACK2_1_9_23
1607+ jack_max_cpu_load (g_jack_global_client ),
1608+ #else
1609+ 0.f ,
1610+ #endif
1611+ g_jack_xruns );
1612+ socket_send_feedback_debug (buf );
1613+ }
1614+
15831615 if (g_verbose_debug ) {
15841616 puts ("DEBUG: RunPostPonedEvents() After the queue iteration" );
15851617 fflush (stdout );
@@ -2877,6 +2909,18 @@ static int ProcessGlobalClient(jack_nframes_t nframes, void *arg)
28772909 if (UpdateGlobalJackPosition (pos_flag , false))
28782910 needs_post = true;
28792911
2912+ if (g_cpu_load_enabled )
2913+ {
2914+ const uint32_t cpu_update_rate = g_sample_rate / 2 ;
2915+ const uint32_t frame_check = g_monotonic_frame_count % cpu_update_rate ;
2916+
2917+ if (frame_check + nframes >= cpu_update_rate )
2918+ {
2919+ g_cpu_load_trigger = true;
2920+ needs_post = true;
2921+ }
2922+ }
2923+
28802924 if (needs_post )
28812925 sem_post (& g_postevents_semaphore );
28822926
@@ -4194,6 +4238,7 @@ int effects_init(void* client)
41944238 jack_set_process_callback (g_jack_global_client , ProcessGlobalClient , NULL );
41954239 jack_set_buffer_size_callback (g_jack_global_client , BufferSize , NULL );
41964240 jack_set_port_registration_callback (g_jack_global_client , PortRegistration , NULL );
4241+ jack_set_xrun_callback (g_jack_global_client , XRun , NULL );
41974242
41984243#ifdef HAVE_HYLIA
41994244 /* Init hylia */
@@ -8368,6 +8413,16 @@ int effects_aggregated_midi_enable(int enable)
83688413 return SUCCESS ;
83698414}
83708415
8416+ int effects_cpu_load_enable (int enable )
8417+ {
8418+ if (g_jack_global_client == NULL )
8419+ return ERR_INVALID_OPERATION ;
8420+
8421+ g_cpu_load_enabled = enable != 0 ;
8422+ effects_output_data_ready ();
8423+ return SUCCESS ;
8424+ }
8425+
83718426int effects_freewheeling_enable (int enable )
83728427{
83738428 if (g_jack_global_client == NULL )
0 commit comments