From alsa-devel-owner@alsa.jcu.cz  Mon May 11 23:32:25 1998
Received: from altrade.nijmegen.inter.nl.net (altrade.nijmegen.inter.nl.net [193.67.237.6])
	by marvin.jcu.cz (8.8.8/8.8.8) with ESMTP id XAA06550
	for <alsa-devel@jcu.cz>; Mon, 11 May 1998 23:32:23 +0200
Received: from obelix.fvdpol.inter.nl.net by altrade.nijmegen.inter.nl.net
	via bd99-17.Breda.NL.net [193.79.246.242] with ESMTP for <alsa-devel@jcu.cz>
	id XAA05330 (8.8.8/3.27); Mon, 11 May 1998 23:32:07 +0200 (MET DST)
Received: (from frank@localhost) by obelix.fvdpol.inter.nl.net (8.8.7/8.7.3) id VAA23852 for alsa-devel@jcu.cz; Mon, 11 May 1998 21:02:00 +0200
From: Frank van de Pol <F.K.W.van.de.Pol@inter.nl.net>
Message-Id: <199805111902.VAA23852@obelix.fvdpol.inter.nl.net>
Subject: Re: New Sequencer core
To: alsa-devel@jcu.cz
Date: Mon, 11 May 1998 21:02:00 +0200 (MET DST)
In-Reply-To: <35555F2E.50CCD9EE@arrakis.es> from "Antonio Larrosa" at May 10, 98 08:02:54 am
Content-Type: text
Reply-To: alsa-devel@alsa.jcu.cz
Sender: alsa-devel-owner@alsa.jcu.cz
Precedence: list

Antonio Larrosa wrote:
> 
> Frank van de Pol wrote:
> > 
> > When using the songposition notation, a tick is and keeps being a fraction a
> > a bar; changing the tempo while playing, will just result in a different
> > number of ticks per second. Events (eg. hihat pattern) that is queued with
> > the 'old' tempo will then follow the new tempo while staying in groove. The
> > tick->second calculation has only to be performed for the event that is to
> > be dequeued. If a time notation (in seconds) was used instead, we indeed
> > should have to run over the list of queued events.
> > 
> > If multiple tempo changes are queued, like in your example, that will work
> > out fine as I'll illustate later.
> 
> Well, yes it would work, I know that ticks are well defined and all that, 
> but I think that ms. are more ... "intuitive" :-)
> 
> In fact, you are right that there are not many difference between using
> one or other unit (and we all be probably using ticks finally), but as I
> said in another posting, ms. is a more general time unit that can be used
> to synchronize many things that don't have a 'tempo' (like animations, or

Yes, yes, yes, that is one type of events that needs us or ms timing. 

> audio output). Anyway we can always convert one unit to another, but
> why using a conversion when we can always use the same unit ?

If we want to handle tempo changes (we will), we'll need to go trough all
enqueued events, and fixup timestamps. Bweh, that's an ugly hack!

[snip]

> > To overcome this compromise, we can use two parallel queues, one for the
> > real-time (seconds), and one for the song position (ticks).
> 
> I don't think this is the solution, we should only have one queue, (with
> the preferred unit) allowing the programmer to use ms and ticks and just
> convert (internally) the input unit to the one used in the queue.

It is technically easier and more elegant to implement 2 priority queues
instead of just one and have to fixup the timestamps on every tempo change.

[snip]

> > 
> > "Client" in my proposal is just _anything_ that communicates with the
> > sequencer core. The sequencer core is nothing more than a foundation that
> > does nothing but _queueing_ and _routing messages_ between clients. These
> > clients can either reside in userland or kernel land, and can be
> > applications like sequencers, midi players etc., or can be device drivers
> > that play sounds (MIDI, synths, soft synths) or have inputs (MIDI keyboards,
> > drums etc.), or simply 'massage' the data and act as filters, mappers.
> 
> That is very good, it seems that I messed up some things, in fact it is
> similar to something which I thought of doing in a midi server I was
> going to do (before knowing of the ALSA project).
> 
> I thought of virtual midi input and output devices, so a program can send
> midi events with the same API to a device, or doing the role of a virtual
> midi input device, so that another program can connect to it and receive
> the events, just as they connect to a midi input port to receive the
> events of an external keyboard.
>

yep

 
> A virtual midi output device could then be used to simulate a midi device
> (timidity in mind :-)). The API would be the same as of a program that
> receives data from a midi input port.

yep

> 
> But your idea is something that allows the same things and even more.
> 
> > 
> > In the above simple example for a MIDI player, one can add a additional
> > client that allows for instance to change the pitch of certain note events
> > (only specific channels). All this imaginary client does is simply shift the
> > pitch of the received data by 2 semi-tones, and send it to the MIDI output.
> > If now the MIDI player does not send it's events directly to the MIDI outpu,
> > but sends it to this 'pitchshift' client; we get to hear the same song, now
> > with a different pitch. Okay you'll think; whats the use for this pitch
> > shifter? Not much I think, but it illustates one big strenght of this
> 
> Not much ?, that is the basic of a midi mapper !
> Have you seen KMid ?, I developed it because I needed a midi player
> with a midi mapper in Linux (kmid is the only I know that can do it) with
> your proposed design, every program can use the same midi mapper (which
> could be put in a client) without changing the source code.

I guess you got the idea :-)

> 
> The concept of adding clients would be great, but I think it can be difficult
> to pass these events to clients which are in fact other applications.
> Do you know of any method of doing this ?
> Should we use shared memory, or sockets to communicate the clients
> with the server (driver) ? I would preffer sockets, but then, does
> anyone know if it's possible to sleep while waiting for data and
> awake the process when data is available ?

As you can read in my v0.01 proposal, I have 2 interface in mind:

- one for clients that reside in kernel (eg. device drivers)
- one for clients that reside in userland

the 2nd type I thought would just read()/write() the sequencer device,
just like with the /dev/musick. the select() can be used to multiplex read
and writes. (that answers your question about sleeping i suppose)
  
> 
> > 
> > The presencee of a priority queue instead of a FIFO allow us to add new
> > events to be played now or shortly to an queue with events that are already
> > queued for the future. No need to mess with the out-of-band ioctl's.
> 
> So it's (will be) far better than OSS, I like specially the priority queue
> (curious name) much more than the FIFO

a priority queue is just a software engineering term for a data structure
that is basicly a specially ordered head, with the (in our case) event with
lowest timestamp on top. You can insert data in random order, and pull from
it in sorted order.


[snip]
> > 
> > - OSS compatibility can be guaranteed by creating a client with /dev/music
> >   and /dev/sequencer interface that simply maps the OSS events to ALSA events.
> >   And perhaps even a client that calls the OSS to perform/play ALSA events
> >   (use OSS as low-level I/O).
> No please !, we have enough with having to make an OSS-compatible layer to the
> driver, why should we also do the OSS driver ALSA-compatible ?
> (even if it could be done ? :-))

OSS compatibily is not MUST, but can be convenient to have. It can always be
implemented as an additional client. Having suck an compatiblity client
offers next possiblities:

- a OSS API client allows us to us all those old software that doesn't
  support the ALSA (yet). 

- a client that uses OSS as output device allows us to use the OSS drivers.
  That way we can have output on MIDI and synth devices that the ALSA doesn't 
  have drivers for (yet). 

[snip]

> > Thanks for you response, this means that at least some people take the
> > trouble to go though that long story of me. I can understand that it's hard
> 
> Yes, it takes time, but we do read your stories ;-)

thank!


[snip]
> 
> As I've said, I didn't understood your "clients" mechanism at first, but
> they are now well explained (and I think now I understand :-))
> 
> I think that the design is now more or less done, with as many
                                                    ~~~~~~~~~~~~~
> queues as output devices to allow having different tempos, each queue
  ~~~~~~~~~~~~~~~~~~~~~~~~
> measured in ticks and allowing the programmer to insert events by giving
> the time of the event in ticks or in ms. 
> Anyway I would like to know how to implement the clients communications.


No, but that is not the idea.

The sequencer core (you know, the stuff from my proposal) is basicly only a
event scheduler and router between clients. Everything is a client. This
whole 'web' of clients communicate with the sequencer core. They enqueue
events, and get their events delivered. In such a system there is only one
'master' clock to determine when it is time to process a scheduled event.
For this reason there should only be one (pair of, both us and ticks) queue
for the whole system. 

If we want to support multiple tempos (multiuser sequencing???), we will
have to support multiple queue pairs with their timing stuff, and thus
create multiple systems. Yes, we'll have to take that with the design, but
no, we don't have to implement that multiple system functionality from 
day 1. 


[snip]
> > That's very easy with this new architecture (ALSA = Advanced Linux Sequencing
> > Architecture):
> > 
> > - You can simply enqueue volume change events (controller data) with a
> >   timestamp of _now_.
> This is exactly what I have always dreamt of :-)
Your dream will come thru
> 

Frank.

========================---------------->
#define NAME    "Frank van de Pol"     
#define ADDRESS "mgr. Nelislaan 10"  
#define CITY    "4741 AB Hoeven"    
#define COUNTRY "The Netherlands"  
#define EMAIL   "F.K.W.van.de.Pol@inter.NL.net     -o)
                                                   /\\
Linux - Why use Windows, since there is a door?   _\_v

