Hi,
I'm using Jack API in a synthesizer c++ program I'm developing running over a Raspberry Pi 4.
Sample rate is 44100 ( jackSampleRate = jack_get_sample_rate(client_out); )
Buffer size is set to 512 ( jack_set_buffer_size(client_out, _JACK_AUD_PERIOD_SIZE); ) (#define _JACK_AUD_PERIOD_SIZE 512).
Calculated process callback rate is 512/44100 = 11.6mSec.
Actually, process callback is initiated every 5.8mSec (with nframes = 512).
Any idea why the process callback rate is x2 than I expect it to be? (or my assumption is wrong? Why?)
Thanks,
Nahum
re. JACK process callback time period
may I ask how exactly did you get that result, measuring it to 5.8ms ?
Measuring process rate
Sure,
jackCallbackProcess_out is the callback function.
( jack_set_process_callback(client_out, jackCallbackProcess_out, 0); )
The callback function transfers the new data ( process_out(nframes) )and signals to initiates a new audio update cycle.
int jackCallbackProcess_out(jack_nframes_t nframes, void *arg)
{
int err, core;
if (transport_aware_out)
{
jack_position_t pos;
if (jack_transport_query(client_out, &pos) != JackTransportRolling)
{
process_silence_out(nframes);
return 0;
}
}
process_out(nframes);
// Triger update process
pthread_mutex_lock(&updateThreadMutex);
pthread_mutex_unlock(&updateThreadMutex);
// Signal update thread
pthread_cond_signal(&updateThreadCv);
return 0;
}
The update process thread measures the entrance time and calculates the elapsed time from the previous entrance time -> ~5800 microsec.
void* AUDMNG_updateThread(void *arg)
{
int lockCount = 0, voice, count;
int ID;
int core, utilization;
struct timeval startts, prvStartts;
struct timeval stopts;
while (updateThreadIsRunning)
{
pthread_mutex_lock(&updateThreadMutex);
pthread_cond_wait(&updateThreadCv, &updateThreadMutex);
pthread_mutex_unlock(&updateThreadMutex);
ModSynth::get_instance()->update_tasks(0);
prvStartts.tv_usec = startts.tv_usec;
gettimeofday(&startts, NULL);
fprintf(stderr, "Time from last block: %i Time from prev block end time [us]: %i\n", startts.tv_usec- prvStartts.tv_usec, startts.tv_usec - stopts.tv_usec);
.
.
.
gettimeofday(&stopts, NULL);
}
return NULL;
}
Thanks,
Nahum.
re. Measuring process rate
it looks that you're using
pthread_mutex_lock()
inside a real-time thread context?nb. the jack process callback always runs in a RT priority/scheduled thread!
omg! please don't!
i don't know about the pthread / kernel implementation details on armv7 or arm64, but in the generic sense, it is a big no-no! proverbial undefined behavior ensues...:)
re. Measuring process rate
Thanks for the prompt reply.
Apparently I'm not a RT SW expert :-) (Just an HW Eng. who writes code for fun :-) ).
Any hint how can I trigger the update process/thread in a different (proper/recommended) way?
Can it explain the double rate issue?
Thanks,
Nahum.
i don't really know why you
i don't really know why you get that double-rate figure, maybe it's because of the erm... somewhat flawed real-timing logic?
maybe you could rearrange it to the snipped below, which is likely one notch more correct to have on a real-time thread ?
hth.
cheers
JACK process callback time period
Once again, thanks for your great support.
Tried it and it works well, yet, still getting the double-rate.
Any idea where more I can seek for help?
Thanks,
Nahum.
maybe it's because you're
maybe it's because you're locking/unlocking the mutex in tight sequence in the main line loop?
try this pattern instead:
seeya
mutex location
I have moved the mutex lock and unlock to be inside the while loop.
I think the unlock may be after the wait for signal, assuming a sufficient time on wait state.
This still gives the same rate.
I will try to make the signal processing and the JACK output process to be asynchronous.
Thanks,
Nahum.
Issue resolved
To make a long story short - a wrong audio card driver.
Now callback rate is ~11msec, as it should be.
Thanks,
Nahum.
Add new comment