All of lore.kernel.org
 help / color / mirror / Atom feed
* Type safe Haskell interface to ALSA sequencer
@ 2010-05-25 14:11 Henning Thielemann
  2010-05-25 15:27 ` Clemens Ladisch
  0 siblings, 1 reply; 2+ messages in thread
From: Henning Thielemann @ 2010-05-25 14:11 UTC (permalink / raw)
  To: alsa-devel


Dear ALSA developers,

  I read the ALSA-Sequencer-API-Doxygen documentation, various 
ALSA-MIDI-How-Tos and their examples and succeeded to work with ALSA 
sequencers in Haskell. However, I'm still uncertain about the meaning of 
the system components and how they interact. It is extensively documented, 
what works, but not, what does not work. Whenever I do a mistake, ALSA 
leaves me with an unspecific "operation not permitted" or "invalid 
argument" error code. Thus I try to encode conditions in Haskell types.

  For instance once I got an "Invalid argument" error code and only after 
some investigation, I found that I opened the sequencer in Output mode but 
later called event_input. (Actually I only wanted to output something, but 
used event_input for synchronization using Echo events. Unfortunately the 
intention of Echo messages is even not explained in the Doxygen stuff.) In 
order to prevent another occurrence of this problem, I defined distinct 
Haskell types for sequencers depending on the input mode. Now, event_input 
is only allowed on sequencers that were opened in Output or Duplex mode.

  However I wondered, why I could create writeable ports in a output-only 
sequencer. Does this make sense? Would it be reasonable to forbid 
writeable ports in output sequencers and readable ports in input 
sequencers by Haskell types? Is there a difference between 
cap_read|cap_write and cap_duplex?

  I also wondered why there can be several ports in one sequencer, since 
multiple clients can connect to one port, and event_input and event_output 
have no port argument. Further I wondered why queues are not bound to a 
specific port. Can queues be shared amongst ports? Is it sensible to have 
multiple queues in one sequencer? Why has sync_output_queue no queue 
argument? The more I think about it, it seems to me that a port is more an 
identifier, a part of an address, than a mailbox. I could use ports as 
tags, that tell which part of an application to control. A queue looks 
like a mail company and I can use the same sender and receiver addresses 
across different companies. If this is true, then I think it would be 
worth to mention this in the API documentation.

  In another example I called sync_output_queue in order to wait for all 
events being sent, but it aborted with "Operation not permitted", whereas 
I have seen example code where it works. What are the preconditions to 
calling sync_output_queue?

  I really like to see a picture of how sequencers, clients, ports, 
port_infos, queues, timers, events are related.

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Type safe Haskell interface to ALSA sequencer
  2010-05-25 14:11 Type safe Haskell interface to ALSA sequencer Henning Thielemann
@ 2010-05-25 15:27 ` Clemens Ladisch
  0 siblings, 0 replies; 2+ messages in thread
From: Clemens Ladisch @ 2010-05-25 15:27 UTC (permalink / raw)
  To: Henning Thielemann; +Cc: alsa-devel

Henning Thielemann wrote:
> ...
>   However I wondered, why I could create writeable ports in a output-only
> sequencer. Does this make sense? Would it be reasonable to forbid
> writeable ports in output sequencers and readable ports in input
> sequencers by Haskell types?

The PORT_CAP flags say what _other_ clients are allowed to do with the
port, but they do not enforce restrictions for the port's client itself.

For example, aplaymidi needs a source port for the events it sends, but
this port isn't of interest to any other application, so it doesn't set
_any_ CAP flag.

Whether an application can read/write events is determined only by the
INPUT/OUTPUT flags given to snd_seq_open.

> Is there a difference between cap_read|cap_write and cap_duplex?

In theory, the latter indicates that input and output are allowed at the
same time.  (In practice, nobody cares.)

>   I also wondered why there can be several ports in one sequencer, since
> multiple clients can connect to one port,

MIDI has a limit of 16 channels per port, so it is often necessary to
have multiple ports per device.

> and event_input and event_output have no port argument.

Events are sent between clients; their source and destination ports are
more like labels.

> Further I wondered why queues are not bound to a specific port. Can
> queues be shared amongst ports?

Queues are about _timing_; they allow events sent through them to be
timestamped and/or to be delivered at a specific time.

Queues do not have a direct relationship with ports, the events sent
through them have.

> Is it sensible to have multiple queues in one sequencer?

If you want to use multiple timers.

> Why has sync_output_queue no queue argument?

Because it does not actually apply to a sequencer queue.  Events that
are scheduled to be sent later remain in the sending client's output
buffer until they are actually delivered.  This output buffer is called
"queue" here.

> ... it would be worth to mention this in the API documentation.

I've added an entry to my TODO list to move the "documentation" TODO
entry further up.

>   In another example I called sync_output_queue in order to wait for all
> events being sent, but it aborted with "Operation not permitted", whereas
> I have seen example code where it works. What are the preconditions to
> calling sync_output_queue?

In theory, none except having the client opened for output, and I don't
see any code that could return -EPERM for this.


Regards,
Clemens

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2010-05-25 15:27 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-05-25 14:11 Type safe Haskell interface to ALSA sequencer Henning Thielemann
2010-05-25 15:27 ` Clemens Ladisch

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.