<!DOCTYPE article PUBLIC "-//Davenport//DTD DocBook V3.0//EN">

<article>

<artheader>

<title> Using The DOSEMU Sound System (SBEMU)</title>

<author>
<firstname> Alistair MacDonald, updated by Stas Sergeev and subsequently by Ben Davis.
</firstname>

<authorblurb>

<para>
<ulink url="mailto:A.MacDonald@slitesys.demon.co.uk">&#60;A.MacDonald@slitesys.demon.co.uk&#62;
</ulink>
</para>

</authorblurb>
</author>

<pubdate>dosemu-1.2</pubdate>

<abstract>

<para>
The document describes the use of the DOSEMU Sound code (SBEMU), and
what you can expect from it.
</para>

</abstract>

</artheader>

<sect1>
<title>Introduction</title>

<para>
It is much better to be pessimistic about the capabilities of DOSEMU's
sound code. The code itself provides an <emphasis>EMULATION</emphasis> of the popular
SB cards. The actual level of emulation that can be achieved is
dependent upon the capabilities of the sound driver on your
system. Currently the emulation can only talk to the OSS driver
(included in the Linux kernel) although it has been written in a
modular fashion to allow other drivers to be written. For more details 
on the internals please see the WWW pages at <ulink
url="http://www.slitesys.demon.co.uk/a.macdonald/dosemu/sound/"
>http://www.slitesys.demon.co.uk/a.macdonald/dosemu/sound/</ulink
>.
</para>

<para>
The SB and DMA emulation was extensively reworked a while ago by Stas
Sergeev to the point of emulating the SB Pro quite well. Ben Davis
has since added SB16 support. So the pessimism in the last paragraph
may no longer be justified. However, there are programs that don't
work or don't work well. (SB16 support implemented 22-24 May 2003.)
</para>

</sect1>

<sect1>
<title>What to (and what not to!) expect</title>

<para>
The emulation consists of a number of parts, and I'll examine these
separately.
</para>

<sect2>
<title> FM</title>

<para>
The FM driver is the least complete. Most of the chip functions are
there, but no audio output occurs. This means that software which uses 
the presence/operation of the timer should detect the timer presence,
but if the audio needs or uses FM you will hear nothing.
</para>

</sect2>

<sect2>
<title> MPU-401</title>

<para>
This is the MIDI emulation. This should be fairly complete.
For using with OSS you need either an external daemon 'midid'
(this is supplied), or your sound card must have a Wave Table 
synthesizer and /dev/midi configured and working.
Note that if you use ALSA, you don't need a Wave Table.
It is possible to use TiMidity++ instead.
</para>

</sect2>

<sect2>
<title> SB (Digital)</title>

<para>
This is the digital aspect of the audio output. It is the most mature.
Most of the functionality up to and including SB-16 is implemented.
Note that SB MIDI is not implemented, although MPU-401 
emulation (above) is.
</para>

</sect2>

</sect1>

<sect1>
<title> Using SBEMU</title>

<para>
SBEMU needs to be turned on at
run-time. Then your DOS applications need to be configured to use the
emulation (just as they need to be configured to use the real Sound
Blaster card). The basic steps are given below.
</para>

<sect2>
<title> DOSEMU Run-time Configuration</title>

<para>
The default settings are:

<screen>
    Base Address:   220
    IRQ:            5
    DMA:            1
    Midi Port:      330 (Not normally needed)
</screen>

</para>

<para>
Note that these do <emphasis>NOT</emphasis> need to be the same as your real sound 
card.
</para>

<sect3>
<title> Changing the SBEMU settings</title>

<para>
The DOSEMU Sound settings are controlled by the following entries in
<literal remap="tt">/etc/dosemu.conf</literal>
<FOOTNOTE>

<para>
Note that there is some overlap
here with the configuration notes in the README. This will be
addressed at a later stage.
</para>

</FOOTNOTE>
: 
</para>

<para>

<screen>
$_sound = (off)		# sound support on/off
$_sb_base = (0x220)
$_sb_irq = (5)
$_sb_dma = (1)
$_sb_hdma = (5)
$_sb_dsp = "/dev/dsp"
$_sb_mixer = ""
$_mpu_base = (0x330)
</screen>

</para>

<para>
Note that these are the default values. <literal remap="tt">$_sb_dsp</literal>
and <literal remap="tt">$_sb_mixer</literal> are pre-configured to work with
the standard OSS-Free driver. You are unlikely to need to change these values
unless you have multiple drivers in your kernel (such
as the Ultra project drivers).
Note: <literal remap="tt">$_sb_mixer</literal> can be set to "/dev/mixer"
if you want DOSEMU to be able to change the volume on your sound card,
but most people don't like that, so it is disabled by default.
</para>

<para>
There are several driver-specific settings for each supported underlying
driver (only OSS right now, or the OSS emulation of ALSA). In general
you don't need to alter the default values, but many OSS drivers appear
to have some very nasty quirks, so some tweaking might be necessary
if you have some problems with your particular driver.

<screen>
$_oss_min_frags = (4)
$_oss_max_frags = (0x20)
$_oss_stalled_frags = (1)
$_oss_do_post = (off)
$_oss_min_extra_frags = (2)
</screen>
</para>

<para>
<literal remap="tt">$_oss_min_frags</literal> specifies the minimum number
of fragments to divide your card's DMA buffer to. If you buffer underruns,
try increasing this value.
</para>
<para>
<literal remap="tt">$_oss_max_frags</literal> specifies the maximum number
of fragments to divide your card's DMA buffer to.
</para>
<para>
<literal remap="tt">$_oss_stalled_frags</literal> is a hack to work around
a bug found in most of the existing OSS drivers, including the SB one.
Even when the playback is completed, these drivers are reporting that
one fragment is still in use. If your driver doesn't have that problem,
feel free to set this to 0.
</para>
<para>
<literal remap="tt">$_oss_do_post</literal> is a hack that makes it possible
to work with drivers that do not honour the SNDCTL_DSP_SETFRAGMENT ioctl
command (unpatched Aureal Vortex binary driver is a known offender). This
hack is incompatible with the standard OSS drivers and must be disables
unless your driver doesn't work otherwise.
</para>
<para>
<literal remap="tt">$_oss_min_extra_frags</literal> can be increased if
you have underruns.
</para>

</sect3>

<sect3>
<title> Configuring Midi</title>

<para>
The midi driver can be used in two way. It is possible to direct the
output of the SBEMU midi driver directly to a sound card, or through
the <literal remap="tt">midid</literal> daemon. All midi traffic is directed at
<literal remap="tt">~/.dosemu/run/dosemu-midi</literal>. You will need to create this,
or link it to the appropriate device, according to your
configuration. Details about this are given below.
</para>

<sect4>
<title> Using Midid</title>

<para>
This is the preferred method of producing MIDI output. This daemon is
built by default and lives in the same directory as your other DOSEMU
binaries. You will need to create the output pipe for the SBEMU driver:
</para>

<para>

<screen>
% mkdir -p ~/.dosemu/run
% rm -f ~/.dosemu/run/dosemu-midi
% mknod ~/.dosemu/run/dosemu-midi p
</screen>

</para>

<para>
If you already have a <literal remap="tt">~/.dosemu/run</literal> directory then the
<literal remap="tt">mkdir</literal> will fail. This is not a problem.
</para>

<para>
Finally, you need to start the midid program:
</para>

<para>

<screen>
% midid ~/.dosemu/run/dosemu-midi &#38;
</screen>

</para>

<para>
This will run the driver in the background, giving you your prompt
back.You should now run DOSEMU. Midid will terminate when DOSEMU
terminates.
</para>

</sect4>

<sect4>
<title> Sending Midi direct to a device</title>

<para>
To use this method with OSS, you simply need to link the SBEMU midi output file
to the input of your MIDI device. The simplest method of doing this
is:
</para>

<para>

<screen>
% mkdir -p ~/.dosemu/run
% rm -f ~/.dosemu/run/dosemu-midi
% ln -s /dev/MyMidiDevice ~/.dosemu/run/dosemu-midi
</screen>

</para>

<para>
Where <literal remap="tt">/dev/MyMidiDevice</literal> is the path to your midi
device. If you already have a <literal remap="tt">~/.dosemu/run</literal> directory
then the <literal remap="tt">mkdir</literal> will fail. This is not a problem.
</para>

<para>
For ALSA, things are a bit trickier.
Here is an explanation from Robert Komar:
</para>

<para>
The kernel-side basics for getting it working
are described at <ulink
url="http://www.midi-howto.com">http://www.midi-howto.com</ulink>. 
For ALSA, I load the snd-seq-oss
and snd-virmidi kernel modules along with the usual ones started by
alsasound.  I then start timidity as a daemon as follows:
</para>

<para>
<screen> 
% timidity -iA -A100 -B2,8 -Os -EFreverb=0 -EFchorus=0 > /dev/null 2>&1 &
</screen>
</para>

<para>
Note, that you have to get a recent development version of Timidity++
(I use TiMidity++-2.12.0-pre1), and you have to specify support for the
server when running configure before building Timidity++.
</para>

<para>
At this point, you should be able to use `pmidi' to list the various
midi ports and to play music on them.  Check to see that you can play
midi music via the Timidity++ server.
</para>

<para>
I then connect the timidity server to a virtual midi device so that
I can access it through the /dev/snd/ interface (rather than only
through an ALSA-aware program like pmidi):
</para>

<para>
<screen> 
% /usr/local/bin/aconnect 75:0 128:1
</screen>
</para>

<para>
The addresses would probably be different in your case, but the midi-howto
site covers these details fairly well.
</para>

<para>
Listing the midi ports with aconnect on my machine shows (I have a
SoundBlaster Live! Value card):
</para>

<para>
<screen>
# aconnect -o -l
client 65: 'Emu10k1 WaveTable' [type=kernel]
    0 'Emu10k1 Port 0  '
    1 'Emu10k1 Port 1  '
    2 'Emu10k1 Port 2  '
    3 'Emu10k1 Port 3  '
        Connected From: 74:0
client 72: 'Virtual Raw MIDI 1-0' [type=kernel]
    0 'VirMIDI 1-0     '
client 73: 'Virtual Raw MIDI 1-1' [type=kernel]
    0 'VirMIDI 1-1     '
client 74: 'Virtual Raw MIDI 1-2' [type=kernel]
    0 'VirMIDI 1-2     '
        Connecting To: 65:3
client 75: 'Virtual Raw MIDI 1-3' [type=kernel]
    0 'VirMIDI 1-3     '
        Connecting To: 128:1
client 128: 'Client-128' [type=user]
    0 'TiMidity port 0 '
    1 'TiMidity port 1 '
        Connected From: 75:0
</screen>
</para>

<para>
Before running dosemu, I go to the .dosemu/run directory and redirect
the output from dosemu-midi to the virtual midi device connected to the
timidity daemon:
</para>

<para>
<screen>
% cd ~/.dosemu/run
% cat dosemu-midi > /dev/snd/midiC1D3
</screen>
[ note that the permanent symlink should also work, see above --SS ]
</para>

<para>
Note that midid isn't required in this case.  In another terminal, I start
up dosemu and run the games with music playing via General Midi.  Et Voila!
I get sound effects and music while playing Duke3d!  (and just in time,
since my version of Win2K won't play these old DOS games with sound and
VESA video modes).
</para>

</sect4>

</sect3>

</sect2>

<sect2>
<title> Configuring DOS</title>

<para>
You should set your BLASTER environment variable to match your DOSEMU
settings. Note that these don't need to correspond to your real sound
card. For a base SB with the values above, use the following DOS command:
</para>

<para>

<screen>
set BLASTER=A220 I5 D1 H5 T6
</screen>

</para>

<para>
The T6 identifies this as a Type 6 SB device, i.e. an SB 16.
Here is a table of SB types:
<orderedList>
<listitem><para>Legacy SB</para></listitem>
<listitem><para>SB Pro</para></listitem>
<listitem><para>SB 2.0</para></listitem>
<listitem><para>SB Pro 2.0</para></listitem>
<listitem><para>SB Pro MCV</para></listitem>
<listitem><para>SB 16</para></listitem>
</orderedList>
</para>

</sect2>

<sect2>
<title> Configuring the Applications</title>

<para>
Bearing in mind what was stated above, the following are the
recommended methods for configuring applications to use SBEMU. The
first is the preferred method. If you need to manually set any
parameters remember to use those you configured DOSEMU with.
</para>

<sect3>
<title> Midi with Digital Audio</title>

<para>
Configure the applications to use 'General Midi' for Music, and 'SB'
for Digital Audio.
This will work if your card have a Wave Table (/dev/midi)
or hardware mixing ability (TiMidity++).
</para>

</sect3>

<sect3>
<title> SB Music with SB Audio</title>

<para>
Configure the application with 'SB' for Music and Audio. Note that if
the system plans to use FM for the music you will not get music.
</para>

</sect3>

<sect3>
<title> Midi Music, No Audio</title>

<para>
Configure the application with 'General Midi' for Music and no Audio.
</para>

</sect3>

</sect2>

</sect1>

<sect1>
<title> Debugging SBEMU</title>

<para>
The debugging output for SBEMU is enabled in the same way as all
DOSEMU debug, and collected in the same manner. The debug flag for
sound is 'S'. Because the DMA controller is hardware it uses the debug 
flag 'h'. To get basic debugging information into a file called
<literal remap="tt">sound.out</literal> use:
</para>

<para>

<screen>
% dosemu.bin -D-a+Sh -o sound.out
</screen>

</para>

<para>
You can get slightly more verbose output if you use level 2 debugging
(e.g. use <literal remap="tt">-D-a+2Sh</literal>). If you need someone
else to look at the
debug output then feel free to send it to the list or report it at
<ulink url="
http://sourceforge.net/tracker/?atid=457447&amp;group_id=49784&amp;func=browse">
the SourceForge bug tracker at
http://sourceforge.net/tracker/?atid=457447&amp;group_id=49784&amp;func=browse
</ulink>,
but <emphasis>PLEASE</emphasis>,
remove any unnecessary debug output, and give a DETAILED description
of the problem.
</para>

</sect1>

</article>
