Callback question

View: New views
5 Messages — Rating Filter:   Alert me  

Callback question

by jorgeecardona :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi all.

I'm trying to understand how works jack, but i'm stuck on the way that
the callbacks at the clients are called from the server. Is there a
signaling system, like the posix signals? i was reading the code, but
i can't find where exactly is stored the client process function
pointer, and when is called.

Basically i need to write a kind of framework that let pass data
between several "blocks" (client programs), and jack is very close to
what i need.

Thanks.

--
Jorge Eduardo Cardona
jorgeecardona@...
jorgeecardona.blogspot.com
------------------------------------------------
Linux registered user  #391186
Registered machine    #291871
------------------------------------------------
_______________________________________________
Jack-Devel mailing list
Jack-Devel@...
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org

Re: Callback question

by David-71 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, 27 May 2009 18:35:08 -0500
Jorge Cardona <jorgeecardona@...> wrote:

> I'm trying to understand how works jack, but i'm stuck on the way that
> the callbacks at the clients are called from the server. Is there a
> signaling system, like the posix signals? i was reading the code, but
> i can't find where exactly is stored the client process function
> pointer, and when is called.

First off, have a good read at :
http://jackaudio.org/files/docs/html/index.html

jackd's clever design makes it *really easy*. Once you've done the
necessary intialisation, write your own audio processing function using
this prototype :

http://jackaudio.org/files/docs/html/types_8h.html#4923142208a8e7dacf00ca7a10681d2b

and register it with jack_set_process_callback()
(see :
http://jackaudio.org/files/docs/html/group__ClientCallbacks.html#g62351a5803421b6c21b9ffb9124801ef)

>From then on, the automagic of jack will call this function periodically
(paced by the backend driver you've chosen and the runtime parameters
given to the jackd daemon) without any further action from your own
code.

Please have a look at the example client code generously provided with
the source code of jackd and I'm sure you'll grasp the idea.

Cheers ! jackd is a gem.

--
David
_______________________________________________
Jack-Devel mailing list
Jack-Devel@...
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org

Re: Callback question

by Gabriel M. Beddingfield :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Hi Jorge,

On Wed, May 27, 2009 6:35 pm, Jorge Cardona wrote:
> I'm trying to understand how works jack, but i'm stuck on the way that
> the callbacks at the clients are called from the server. Is there a
> signaling system, like the posix signals? i was reading the code, but
> i can't find where exactly is stored the client process function
> pointer, and when is called.

For Jack1, look in engine.c for jack_engine_process().  Whenever it wants
to call the client callbacks, this is the function that does it.  The
JSList* node holds a linked-list to all the client data (void*
node->data).  For each client, either jack_process_internal() or
jack_process_external() is called.

Inside jack_process_internal(), you'll find:

        jack_client_internal_t *client;
        jack_client_control_t *ctl;

        client = (jack_client_internal_t *) node->data;
        ctl = client->control;

And later on:

        if (ctl->process_cbset)
                if (client->private_client->process (nframes,
client->private_client->process_arg)) {
                        jack_error ("internal client %s failed", ctl->name);
                        engine->process_errors++;
                }

ctl->process_cbset is a flag indicating whether or not the callback has
been set.  If so, client->private_client->process is the pointer to the
callback.

Someone correct me if I made a mistake here.

HTH,
Gabriel

--
               G a b r i e l   M   B e d d i n g f i e l d

_______________________________________________
Jack-Devel mailing list
Jack-Devel@...
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org

Re: Callback question

by torbenh :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, May 27, 2009 at 07:24:02PM -0500, Gabriel M. Beddingfield wrote:

>
> Hi Jorge,
>
> On Wed, May 27, 2009 6:35 pm, Jorge Cardona wrote:
> > I'm trying to understand how works jack, but i'm stuck on the way that
> > the callbacks at the clients are called from the server. Is there a
> > signaling system, like the posix signals? i was reading the code, but
> > i can't find where exactly is stored the client process function
> > pointer, and when is called.
>
> For Jack1, look in engine.c for jack_engine_process().  Whenever it wants
> to call the client callbacks, this is the function that does it.  The
> JSList* node holds a linked-list to all the client data (void*
> node->data).  For each client, either jack_process_internal() or
> jack_process_external() is called.
>
> Inside jack_process_internal(), you'll find:
>
> jack_client_internal_t *client;
> jack_client_control_t *ctl;
>
> client = (jack_client_internal_t *) node->data;
> ctl = client->control;
>
> And later on:
>
> if (ctl->process_cbset)
> if (client->private_client->process (nframes,
> client->private_client->process_arg)) {
> jack_error ("internal client %s failed", ctl->name);
> engine->process_errors++;
> }
>
> ctl->process_cbset is a flag indicating whether or not the callback has
> been set.  If so, client->private_client->process is the pointer to the
> callback.

note that client->private_client->process only exists in the clients
address space.

I also think the question was rather how to implement a similar system,
and how the control is passed around processes.
So internal clients are not really relevant here.

jack is a lot cleverer, than described here.
between the invocation of the process callbacks of two clients, control
will not be transfered to jackd, the external clients transfer control,
by writing a byte into a pipe, where the next process is blocking on.

look at libjack/client.c: jack_client_thread_aux()
this is where it all happens.

------------------------------------------------------------------------------------
static void
jack_client_thread_aux (void *arg)
{
        jack_client_t *client = (jack_client_t *) arg;
        jack_client_control_t *control = client->control;

        pthread_mutex_lock (&client_lock);
        client->thread_ok = TRUE;
        client->thread_id = pthread_self();
        pthread_cond_signal (&client_ready);
        pthread_mutex_unlock (&client_lock);

        control->pid = getpid();
        control->pgrp = getpgrp();

        DEBUG ("client thread is now running");

        if (control->thread_init_cbset) {
                DEBUG ("calling client thread init callback");
                client->thread_init (client->thread_init_arg);
        }

        /* wait for first wakeup from server */

        if (jack_thread_first_wait (client) == control->nframes) {

                /* now run till we're done */

                if (control->process_cbset) {

                        /* run process callback, then wait... ad-infinitum */

                        while (1) {
                                DEBUG("client calls process()");
                                int status = (client->process (control->nframes,
                                                                client->process_arg) ==
                                              control->nframes);
                                control->state = Finished;
                                DEBUG("client leaves process(), re-enters wait");
                                if (!jack_thread_wait (client, status)) {
                                        break;
                                }
                                DEBUG("client done with wait");
                        }

                } else {
                        /* no process handling but still need to process events */
                        while (jack_thread_wait (client, 0) == control->nframes)
                                ;
                }
        }

        jack_client_thread_suicide (client);
}
-------------------------------------------------------------------------------------

note that these fds are setup during the graphchange step, where
processing is suspended.




>
> Someone correct me if I made a mistake here.
>
> HTH,
> Gabriel
>
> --
>                G a b r i e l   M   B e d d i n g f i e l d
>
> _______________________________________________
> Jack-Devel mailing list
> Jack-Devel@...
> http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org

--
torben Hohn
http://galan.sourceforge.net -- The graphical Audio language
_______________________________________________
Jack-Devel mailing list
Jack-Devel@...
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org

Re: Callback question

by Gabriel M. Beddingfield :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Thu, May 28, 2009 12:15 am, torbenh@... wrote:
> So internal clients are not really relevant here.

Thanks for clearing that up, Torben.

--
               G a b r i e l   M   B e d d i n g f i e l d

_______________________________________________
Jack-Devel mailing list
Jack-Devel@...
http://lists.jackaudio.org/listinfo.cgi/jack-devel-jackaudio.org