You are here

JACK process callback time period

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

Forums: 
rncbc's picture

may I ask how exactly did you get that result, measuring it to 5.8ms ?

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.

rncbc's picture

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...:)

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.

rncbc's picture

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 ?

// Trigger update process
if (pthread_mutex_trylock(&updateThreadMutex) == 0) {
    // Signal update thread
    pthread_cond_signal(&updateThreadCv);
    pthread_mutex_unlock(&updateThreadMutex);
}

hth.
cheers

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.

rncbc's picture

maybe it's because you're locking/unlocking the mutex in tight sequence in the main line loop?

try this pattern instead:

pthread_mutex_lock(&updateThreadMutex);

while (updateThreadIsRunning)
{
    pthread_cond_wait(&updateThreadCv, &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);
}

pthread_mutex_unlock(&updateThreadMutex);

seeya

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.

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