Some notes about analog multichannel playback
=============================================

Analog multichannel playback was implemented by
Eduard Hasenleithner <eduard@hasenleithner.at>
Created: 2001-07-05

If you have any questions regarding this topic, don't
hesitate to mail me :)

Usage
=====
Multichannel playback is now possible with the emu10k1
driver. An audio application requests the number of channels
with the SNDCTL_DSP_CHANNELS ioctl, and the new code is
activated.

The voices start with fx8, and increment for each additional
voice. For example, five channel output uses fx8 .. fx12 as
dsp input. Since no routes are present for this input, nothing
can be heard! In order to route the channels to the speakers
following commands must be issued:

emu-dspmgr -a"fx8:Front L"
emu-dspmgr -a"fx9:Front R"
emu-dspmgr -a"fx10:Rear L"
emu-dspmgr -a"fx11:Rear R"
emu-dspmgr -a"fx12:Analog Center"
emu-dspmgr -a"fx13:Analog LFE"

The reason for not using the voices from fx0 on is just
convenience. One must not delete all routes before setting
up the new routes for multichannel output. It is possible
to use fx0 as base. 

To set a different fx number as base invoke

emu-config -m 0

for setting fx0 as base. Every other fx can also be set.
Attention: fx15 is unusable. So for 6ch output, this parameter
should be no higher than 9! Using fx15 would need extra code
in the driver which is not yet included.

To level the output of ch5 and ch6 (SbLive5.1, Center and LFE)
a new OSS mixer control has been included. The control name is
SOUND_MIXER_IMIX and has the name "Mix" in aumix. Although this
is a stereo control it is intended for setting the Center and
LFE individually.

How does it work?
=================

The emu10k1 chip has the possibility to play 64 voices. This
is more than sufficient to replay 5.1 surround. But the chip
can not replay this the same way as stereo.

For stereo streams, two voices point to the same input buffer.
A flag in one of the emu10k1 register signals, that the voice
should only read every second sample. Using an offset of one
sample, two voices can be combined to replay stereo.

But this method does not work for replaying more than two
channels. Doing this, required some kind of software emulation.
What I did was to allocate the needed number of mono voices
along with separate voice buffers. In the write function,
the input stream gets split up into the individual voice
buffers.

Are there problems?
===================

Although this works very well it has several drawbacks. These
drawbacks do not interfere with the usual DVD playback, but
should be considered when doing something else.

So, remember following facts:
*) fragment_size
	The fragment size ioctl does not set the fragment size
	of the user-space buffer, but the fragment size of the
	individual voice buffers. Therefore the fragment size reported
	to the user program is num_channels * requested_fragment_size. 
*) memory mapped access
	memory mapped access is simply not possible. As this
	access needs support from hardware, there is no way
	to do it.

Aside from that, all other things should work. But it is
possible that I did not modify all IOCTLs to care for the
multichannel extension I made. If you need one IOCTL, and
it don't works, email me.

Some internals
==============

This section is not intended for end users, but only for some
person, who wants to modify the code.

The former structure of the source code had almost no preparations
for implementing multiple channels. Therefore, following two
structures had to be modified:

*) woinst
	woinst is now responsible for more than one voice. The
	voice member is now an array. All bytes values in this
	structure refer to a single voice. To report them to
	user space they must be multipled by the number of voices.
	The number of _separately_ allocated voices is contained
	in num_voices. So, for stereo, num_voices is still 1!
	
*) waveout_buffer
	waveout_buffer contains all values with the metrics
	for the first voice. All other voices are dependend on
	this first voice and are assumed to have the same values.
	Instead of the three variables emupageindex, addr and
	dma_handle, a new structure, waveout_mem is present
	in waveout_buffer. This new structure is inserted as an
	array of waveout_mem. With this modification, it is
	possible to allocate more than one buffer.

So, every function which relys on the values of waveout_buffer must
take the number of voices into account.

