From alsa-devel-owner@alsa.jcu.cz  Fri Oct  2 21:35:41 1998
Received: from entry.jcu.cz (IDENT:perex@entry.jcu.cz [160.217.1.111])
	by marvin.jcu.cz (8.9.1a/8.9.1) with SMTP id VAA15504;
	Fri, 2 Oct 1998 21:34:57 +0200
Date: Fri, 2 Oct 1998 21:35:01 +0200 (CEST)
From: Jaroslav Kysela <perex@jcu.cz>
To: "P.J.Leonard" <P.J.Leonard@bath.ac.uk>
cc: kde-multimedia@alpha.tat.physik.uni-tuebingen.de, alsa-devel@alsa.jcu.cz
Subject: Re: Playing and mixing wave files
In-Reply-To: <3614F201.59E2@bath.ac.uk>
Message-ID: <Pine.LNX.3.96.981002211925.1260C-100000@entry.jcu.cz>
MIME-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
Reply-To: alsa-devel@alsa.jcu.cz
Sender: alsa-devel-owner@alsa.jcu.cz
Precedence: list

On Fri, 2 Oct 1998, P.J.Leonard wrote:

> Johannes Walch wrote:
> > 
> > Stefan Westerfeld wrote:
> > 
> >      1. Client 1 arrives, and wants to play wav-File foo.wav
> >      2. Your server does a write to OSS with the first 4096
> >      samples of foo.wav
> >      3. 1ms later, Client2 arrives, and wants to play wav-File
> >      bla.wav
> >      4. Now, only the first 44 samples of foo.wav have been
> >      really played,
> >         while the others are still in some OSS buffers.
> > 
> >         But IMHO the only chance now is to mix the next 4096
> >      samples of foo.wav
> >         with the first 4096 samples of bla.wav, and then write
> >      them to OSS.
> > 
> >      Then, the delay you produced is 4096*(1/44100s) = 92ms,
> >      instead of the 1ms
> >      delay in reality.
> > 
> >      The only solution I can think of is to use really small
> >      buffers, and that's
> >      what KSynth is doing. But if you do so, you will need a high
> >      priority, to
> >      be able to generate continous output, even if other
> >      processes need the cpu
> >      badly. ;)
> > 
> > 
> > I think of another possibility. It's just not ok that the sound system
> > take so much cpu time. All the people who don't need low latency audio
> > will turn off the sound system then and that's not the approach.
> > I think the audio server should not work with a fix buffer size. In
> > normal environment (system sounds) a buffer size of 4096 is ok (or
> > even more) and when a "realtime sound" application is started (like
> > games or ksynth or something) then the buffer size is decreased. I
> > think this would be a simple and effective solution. I don't know if
> > this is possible with OSS but we should probably not focus so much on
> > OSS anyway. I don't like the commercial aspect of OSS and there's an
> > alternative sound driver project going on. It's called  ALSA  and
> > allready quite advanced. So maybe we should give this a thought.
> 
>  From what I hear on the ALSA list the audio drivers are pretty good
> (better than OSS). I used the ALSA driver in the OSS emulation
> mode without problem. However ALSA has not yet got the internal synth
> support
> for all sound cards (e.g. my AWE32). 
> Untill this is implemented I would not recommend using the ALSA drivers 
> because you would still need OSS and I don't think you can just load up
> the synth driver part of OSS (I could be wrong).

This also depends if user needs use synthesizer. OK. Sequencer interface
design is a little bit delayed (more that I expected at summer), but as I
wrote before - I will not work on EMU8000 code. I'll port only GUS
WaveTable routines soon as possible from ultra driver.

Back to original question: PCM mixing issues. I want solve this problem
with ALSA driver. Looks that this feature is strongly needed, but none is
going to create good new interface which will solve all troubles with this
problem. Answer on all questions is my draft which I included to this
mail. I expect some discussion about it on ALSA devel mailing list (look
to http://alsa.jcu.cz for more details - here is also link to list
archive).

If you have some questions or other ideas, feel free write me.

						Jaroslav

P.S. I'm sorry for my (not very good) english.
P.P.S. Warning!!! If you reply to this message you should look carefully 
to recipients (remove kde-multimedia mailing list if message is only for
ALSA developers).

------- CUT HERE

		ALSA PCM realtime mixing interface - Draft v0.1
		===============================================
		        Jaroslav Kysela <perex@jcu.cz>


    ALSA driver already supports all features which are needed for exclusive
access to PCM devices. Modern sound driver needs ability of realtime mixing
of independend PCM streams. Mixing should be done in user space or in kernel
space. Unfortunately user space have some limitations for which this
implementation isn't very good:
	1) user code doesn't know precise current position in stream
	2) user code may deliver samples to kernel space delayed
	3) user code doesn't have access to hardware and use optimal mode
           for data transfers and playback (GUS cards)
   ALSA implementation leaves some code to user space. In user space should
be code for conversion to mixing format, rate and adding some digital
effects (echo, 3D etc..).
   As transfer method between user space and kernel space will be used
mmaped access. This means that application will write samples directly
to driver's buffer (this shouldn't be hardware buffer of necessity).
This eliminates one copy of samples.
   As synchronization source (as standard PCM code uses) will be used
system clock (gettimeofday). This method of synchronization will also allow
delayed start of samples.

   Compatibility issues: Interface isn't compatible with current available
interfaces such as OSS and exclusive ALSA PCM interface. Author of draft is
expecting that application authors will use new interface in applications and
some ports of old applications will be done. Main goal of ALSA project is
creating something new and modern. If we will support old OSS interface,
authors probably will leave at this interface and this doesn't ensure good
performance for future. ALSA already offers OSS compatibility in exclusive
mode. This should be enough. Author simply doesn't know how can be done good
(without compromises) mixing with fragment issues.

   Other issues: Using ALSA PCM mixing interface and exclusive interfaces
(ALSA PCM or OSS emulation). Mixing interface will be coded on top of
hardware drivers and sharing between exclusive interfaces cannot be
possible. User must choose if he (she) want run exlusive application or
rather application which will use shared mixed playback.

   Record direction: Is needed to create multiple record input? Author of
this draft think that all applications are using exclusive record input
at this time and this feature isn't needed for future. Data for record 
monitoring should be already read via proc interface at current time.

==== expected additions to asound.h ====

/*****************************************************************************
 *                                                                           *
 *        Digital Audio (PCM) mixing interface - /dev/snd/pcmmix??           *
 *                                                                           *
 *****************************************************************************/

#define SND_PCM_MIX_VERSION		SND_PROTOCOL_VERSION( 1, 0, 0 )

struct snd_pcm_mix_info {
  unsigned int type;			/* soundcard type */
  unsigned char id[32];			/* ID of PCM mixing device */
  unsigned char name[80];		/* name of device */
  unsigned int format;                  /* SND_PCM_SFMT_XXXX */
  unsigned int rate;                    /* mixing rate in Hz */
  unsigned int channels;                /* hardware channels (voices) */
  unsigned char *buffer;		/* initial buffer for mmaped access */
  unsigned int size;			/* initial buffer size for mmaped access */
  unsigned char reserved[64];		/* reserved for future */
};

struct snd_pcm_mix_setup {
  unsigned char volume[128];		/* linear volume levels (0-255) */
  unsigned int channels;		/* channels (voices) */
  struct timeval start;			/* start time in us or zero=now */
  unsigned int size;			/* buffer size in bytes or zero=initial */
  int wakeup_size;			/* wakeup size in bytes */
  unsigned char reserved[256];		/* reserved for future */
};

struct snd_pcm_mix_status {
  int count;                            /* number of bytes writeable without blocking */
  int queue;                            /* number of bytes in queue */
  int freeptr;				/* pointer to free area in byte offset */
  int underrun;                         /* count of underruns from last status */
  struct timeval time;                  /* time the next write is going to play */
  struct timeval stime;                 /* time when playback was started */
  int scount;                           /* number of bytes processed from playback start (last underrun) */
  unsigned char reserved[64];		/* reserved for future */
};

#define SND_PCM_MIX_IOCTL_PVERSION	_IOR ( 'm', 0x00, int )
#define SND_PCM_MIX_IOCTL_INFO		_IOR ( 'm', 0x01, struct snd_pcm_mix_info )
#define SND_PCM_MIX_IOCTL_SETUP		_IOWR( 'm', 0x10, struct snd_pcm_mix_setup )
#define SND_PCM_MIX_IOCTL_STATUS	_IOR ( 'm', 0x20, struct snd_pcm_mix_status )
#define SND_PCM_MIX_IOCTL_FLUSH		_IO  ( 'm', 0x30 )
#define SND_PCM_MIX_IOCTL_DRAIN		_IO  ( 'm', 0x31 )
#define SND_PCM_MIX_IOCTL_PAUSE		_IOWR( 'm', 0x32, int )

--------- CUT HERE


-----
Jaroslav Kysela <perex@jcu.cz>
Academic Computer Centre, University of South Bohemia
Branisovska 31, C. Budejovice, CZ-370 05 Czech Republic


