JACK process callback time period

Forums

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

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.

Permalink

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

Permalink

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 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

Permalink

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 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

Permalink

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.

Permalink

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

The content of this field is kept private and will not be shown publicly.

Markdown

  • Parses markdown and converts it to HTML.
  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type='1 A I'> <li> <dl> <dt> <dd> <h2 id='jump-*'> <h3 id> <h4 id> <h5 id> <h6 id> <img src alt height width> <strike> <pre> <p> <br>
  • Lines and paragraphs break automatically.

Filtered HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <b> <i> <pre> <img src alt height width> <strike>
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.

Plain text

  • No HTML tags allowed.
  • Lines and paragraphs break automatically.
  • Web page addresses and email addresses turn into links automatically.
File attachments
Unlimited number of files can be uploaded to this field.
2 MB limit.
Allowed types: jpg jpeg gif png txt doc docx xls xlsx pdf ppt pps odt ods odp zip gz bz2 xz patch diff wav ogg flac ogv mp4 qtz.
CAPTCHA
Enter the characters shown in the image.