Subject: Re: [linux-audio-dev] audioengine/laaga prototype now operational (audible)
From: Richard Guenther (rguenth_AT_tat.physik.uni-tuebingen.de)
Date: Mon Jun 18 2001 - 12:24:06 EEST
On Sun, 17 Jun 2001, Paul Davis wrote:
> Your comments on the emerging design would be very welcome.
Instead of opposing against the whole design, I'll just start
commenting on the actual interface (audioengine.h):
audioengine_handle_t *
audioengine_open (const char *client_name,
AudioengineProcessCallback, void *process_arg,
AudioengineBufferSizeCallback, void *bufsize_arg,
AudioengineSampleRateCallback, void *srate_arg);
I dont like having more than one callback at all. Instead the client
should query the buffer size (whats that at all!?? maximum buffersize?
Not again something like LADSPA delay_10ms delay_500ms delay_1s sort
of crap...). Also the sample rate should be per connection and
constant during its lifetime (just transparently disconnect/reconnect
from the UI, if you like) - we want to support resampling nodes,
dont we?
Also, is this "client_name" a port? Why do I register the process
callback wrt the registration of my app to the engine? Isnt that
process a per-port-bundle operation? I.e. more like
audioengine_open(const char *client_name);
port_bundle_t *
audioengine_new_port_bundle(const char *name, (* process)());
audioengine_register_port(const char *port_name, port_bundle_t *);
(so you'd usually group things like left/right but not necessarily
two instances of that)
Or you planned to support multiple audioengine_open() calls per
process?
---int audioengine_activate (audioengine_handle_t *handle); int audioengine_deactivate (audioengine_handle_t *handle);
I dont see you need those for an always-running-system. Perhaps be able to "mute"/"suspend" a connection, but not the app
----
audioengine_port_t * audioengine_port_register (audioengine_handle_t *, const char *port_name, const char *port_type, unsigned long flags, unsigned long buffer_size);
whats a physical connection!??? whats a multi connection!???? Either those are always possible (engine driven) or explicit - you dont need those flags. Drop buffer_size, too. In fact - drop support for different typed data than audio - you have too much specific stuff in the engine based approach anyway. ==>> make it simple.
----
int audioengine_port_unregister (audioengine_handle_t *, audioengine_port_t *);
You dont need the engine handle.
----
int audioengine_port_lock (audioengine_handle_t *, const char *port_name); int audioengine_port_unlock (audioengine_handle_t *, const char *port_name);
You dont need those - instead make the ports reference counted by the number of open connections and gc them, if they were deleted and no connections are there.
----
unsigned long audioengine_get_sample_rate (audioengine_handle_t *); unsigned long audioengine_get_buffer_size (audioengine_handle_t *);
Make this per port/connection. Dont allow them to change during port (yes!) or connection (at least that) lifetime.
----
GSList *audioengine_get_ports (audioengine_handle_t *, const char *port_name_pattern, const char *type_name_pattern, unsigned long flags);
Dont use GSList's :) List of returned ports are the port identifier strings (the spec doesnt tell).
----
void audioengine_listen_for_ports (audioengine_handle_t *, AudioenginePortRegistrationCallback, void *);
Uh - if you want to allow highlevel events from the engine, just use some more abstract stuff like a SYSV message queue for that (not another callback...), then you can add messages without adding more calls.
----
char *audioengine_port_name (audioengine_port_t *port, char *buf, unsigned int bufsize);
you cant get hold of the audioengine_port_t if you;re not the one who registered it? So I think this call is pointless. Also do not design such "compound" I-support-every-kind-of-arg-you-can-think-of calls :) Just use
char *audioengine_port_name (audioengine_port_t *port);
its not performace critical at all.
----
audioengine_port_t *audioengine_port_by_id (audioengine_handle_t *handle, audioengine_port_id_t);
Ah - here it is. Whats the port_id ?? You have a unique string identifier, so how you need another id? HINT: for internal (inter-process) use just use the virtual address (for shm the offset inside the segment) of the struct. Quite a useful unique identifier.
Richard.
-- Richard Guenther <richard.guenther_AT_uni-tuebingen.de> WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/ The GLAME Project: http://www.glame.de/
This archive was generated by hypermail 2b28 : Mon Jun 18 2001 - 12:23:23 EEST