Version 50.0 - 1.4.2004
/\/exus /)evelopment
Enhanced
audio.device solution for the MorphOS operating system
Developed by Emanuele Cesaroni of Nexus Development /\//)
(url = http://xoomer.virgilio.it/nexusdev/nexusdev/)
INDEX
The
purpose of this device is to make fully compatibles with MorphOS all
the
programs written in the past using the native audio.device which was
thought to
interact with the hardware audio chips of the old 68k Amigas. This PPC
enhanced
version of the audio.device redirects the commands to the AHI device
allowing to
use the last generation of sound boards supported by the ahi system.
The device
foresees all the audio.device's original commands: CMD_CLEAR,
CMD_FLUSH,
CMD_READ, CMD_RESET, CMD_START, CMD_STOP, CMD_UPDATE, CMD_WRITE,
ADCMD_ALLOCATE,
ADCMD_FINISH, ADCMD_FREE, ADCMD_LOCK, ADCMD_PERVOL, ADCMD_SETPREC and
ADCMD_WAITCYCLE. I advice you to read this guide to be informed about
its
functional limits.
The version
you are using is still under development, so isn't in the final form.
The
project's roadmap foresees to improve the device in the next releases.
You can
get the version device's number simply typing on shell:
"any_prompt> version devs:audio.device"
You will get a string as "audio.device xx.y" where xx is the version
and the y the revision.
Starting
from version 50.0 dated october 2003 the code is fully PPC compiled.
You
need MorphOS running and a bit of harddisk space (about 40 KBytes) in
your
system's partition. AHI device in version 4 minimum is strictly needed.
Simply
copy the file "audio.device" to the "DEVS:" directory. Each
time you want to update the device with a new version or revision
repeat the
above passes replacing the "audio.device" file in "DEVS:".
Take care that after the first device use it could be loaded in ram
where it
becomes resident. So to use the new installed one, when the old has
been opened
just only once, you need to reboot the whole system.
The
device could be configured trought some global variables placed in
"envarc:audio.device/".
In absence of them default values are used. The "default values" point
to a configuration which is the closest possible to the original
audio.device
behaviour. The default value is used always when the relative global
var is not
found. Moreover some of them must stay under certain numeric intervals.
All of
them are read at audio.device startup (exec.library/OpenDevice()) and
don't
change until the device is not closed (exec.library/CloseDevice()).
Here the
explaination of the available ones.
MINPERIOD (1 <= x <= 124)
This informs the audio.device about which period value use as minimum
when
reproducing the samples. The default value is 124, because it was the
original
minimum hardware limit imposed by Paula. Many programs, in certain
circumstances,
use to ask for lower values (Frogger is an example) so to get a good
audio
ouptut, even in these cases, this configuration input is provided. Read
the
compatibility list where you can find some infos for each program
tested and the
"Emulation approach" section of this
guide for more details.
To get the MINPERIOD global var to 124, type on shell:
any_path:> setenv
"env:audio.device/MINPERIOD"
124
Then copy it/them to envarc: to save it/them at each boot, type on
shell:
any_path:> makedir
envarc:audio.device
any_path:>
copy env:audio.device to envarc:audio.device
The value can be equal or greater than 1 as minimum and equal or lower
than 124
as maximum.
This
audio.device when is opened for the first time performs these
operations:
1) Creates a dos process (an exec superset slave task) which is
responsable of
all ahi.device calls and is named "NexusDEV slave audio" (in version
50.0 with 127 as priority).
2) The slave process opens ahi.device and setups 4 message ports each
one used
for each audio unit (from 0 to 3) to receive the CMD_WRITEs commands.
So, for example, if a task opens the audio.device and wants to play a
sample,
allocates the wanted channels combination (ADCMD_ALLOCATE) and sends
trought the
device a CMD_WRITE command to the slave process unit. The slave process
converts
the incoming audio io request into an ahi one which will be sent to the
ahi.device. When AHI returns the slave process returns the audio
request to the
calling task.
**Important**
The device uses the AHI_DEFAULT_UNIT (unit 0). To get the best
performances from
the device in conjunction with AHI set at least to 4 the number of
channels
field of unit 0 under the AHI main preferences program. The equation
is: more
channels = better sound quality.
**Important**
The device uses a sub process to have an asynch behaviour. Its priority
is 127,
so very hight, to allow it to be fast enought to efficently run the
audio.
Decreasing its priority during the device's life in the system could
cause
problems (audio will be stopped, the task will be blocked).
This
audio.device is thought to be compatible with all the programs written
using the
OS instead banging the hardware. Most coders used to lock (by
ADCMD_LOCK) the
channels to access directly to the hardware audio registers. These
programs are
not compatible with this device but above all with the entire OS. In
this case
you need of UAE. Refer to the "Compatibility
list" and the "Emulation Approach"
sections.
Because
doesn't exist a native audio.device's source code available all the
work done is
based upon an assumption derived from documents about the original
audio.device
operating method (reverse engineering, no disassembling). For this
reason may be
not compatible and most programs using it may have problems. The
debugging and
the received reports about its usage in combination with certain
programs will
allow to improve the whole project. Read the history log to get infos
about the
known bugs. Please be patient using it!
To
improve the device are wellcome impressions and reports about its
behaviour.
Please send them writing to me.
Be more precise as possible describing the problem you get, the program
you was
using with, the device version and revision etc. If you are a developer
of a
program which uses the audio.device (and it had always worked well)
would be
very appreciable if you test the app with my device reporting the
results and
some infos more about the approach you had used coding.
The device was written by Emanuele
Cesaroni of Nexus Development. You can find Nexus Development at "http://www.genie.it/utenti/nexusdev".
Many thanks for your support...
The audio.device on the classic Amigas interacts with a physical piece
of
hardware, so with the well known Paula chip. Instead this enhanced
audio.device
interacts with AHI. For this reason even if AHI allows better
performances the
device is forced to be closer to the Paula own performances. This
allows a
better emulation. This approach and the use of AHI could give problem
in certain
situations. Here a list of them i found during the development.
1) The min period problem.
On all documents about Paula (as on all hearts'walls) you can read that
it
supports a period range beetween 124 and 65536 clock's cycles per
sample. You
can ask less than 124 or more than 65536 but without get effects. This
is an
hardware limit which could not be surpassed. Even if AHI could supports
very
lower period values i forced the device to work (as default) with 124
as minimum
value. So if some coders, in their programs, asked for values < 124
they won't
be considered. As result the output may be corrupted. You are allowed
to config
the minimum period trought an envarc: global variable. Please read the "Configuration"
section of this document about the MINPERIOD variable.
2) The AHI performances
AHI is an audio layer. So each time a task wants to play a sample AHI
library is
called before the sound wave is sent to the audio board's chips. This
is the
way. For this reason, the coding approach must consider that is better
to send
longer audio streams few times in a second than sending shorter audio
streams
many times per second. The old Paula chip had better performances in
the second
case. The narrator.device is an example. To reproduce the sound it
sends to the
Paula (trought the audio device) very short samples, in stereo, a lot
of times
per second. AHI, even used in low level api, is not able to reproduce
the audio
at a reasonable speed. So in most cases the audio is not outputted.
This is a
limit, which may be fixxed only by faster AHI versions, or maybe on
faster audio
devices. Taken from the AHI developer documentation (consider the
unroll samples
technique for the audio.device is not possible; it is a real time audio
processor layer!):
"Also note that playing very short sounds will be very CPU
intensive, since
there are many tasks that must be done each time a sound has reached its end (like starting the next one,
calling the
SoundFunc, etc.).
Therefore, it is recommended that you "unroll" short sounds a couple of times before you play them. How many times you should unroll? Well, it
depends on the situation, of course, but try making the sound a
thousand samples
long if you can. Naturally, if you need your SoundFunc to be called,
you cannot
unroll."
The
programs here listed were tested with the device. Their behaviour had
seen
regular in all circumstances. The tests were done as deep as possible
considering my aknowledgement with them. Where you found a ! you can
read some
infos more about how it works.
-
ADoom v1.3
- AmigaOS v3.5 own sound preferences program (sound.datatype 40.6)
- AmigaOS v3.1 own sound preferences program (sound.datatype 40.6)
- Amigenerator v0.34
! The audio works but you heard a wait noise in the background.
The only
way to bypass the problem is to run the program with the NOPSG option
enabled.
- Aqua
- Delitracker v2.32
! The program opens the audio.device to get the channels but
after a
CMD_LOCK it bangs the hardware and then dies. You can also exit safetly
from it
without playing nothing.
- DirectoryOpus v4.12
- DoomAttack 68k v1.10
! The audio is ok but the video can't work properly on my
machine.
- FroggerNG (68k and MorphOS versions)
! Playing some videos the audio seems slow. This is due to the
"Min
period problem" about what you can read in the "Emulation
Approach" section. I saw that playing a wmv stream it asked for a
period of 80. So, in this case, this is the minimum value i advice for
the
global var "envarc:audio.device/MINPERIOD".
- MAME v0.34.3 (tested with very few roms)
- Miami v3.0d (sound.datatype 40.6)
- MooVID v1.2 player on AmigaOS v3.5
- Multiview 45.9 (sound.datatype 40.6)
- narrator.device v37.7
! The narrator.device uses to send tons of requests (CMD_WRITES)
to the
Paula chip trought the audio.device. The problem is that AHI actually
can't
support this amount of short calls. AHI is a software layer so works
better when
the requests are few and longer and worse when are many and shorter.
Read the
"Emulation approach" section of this
guide for more details.
- Payback 68k
- Ports of Call (game)
- Prayer v2.0
! Not totally supported (needs a small change in sources)
because bangs
the hardware.
- PuzzleBOBS game v0.750 (in all its audio output modes)
- Rustle
! It asks 0 as period, so pay attention
to your MINPERIOD
global varfile configuration. In this case MINPERIOD = 124 is the
adviced value
to use.
- Say and Saymore
! See narrator.device in this section.
- Samplitude Opus v3.5
- SongPlayer v1.4
! It opens regularly the device to get
the channels but then
bangs the hardware.
- WBClock v45.10 (sound.datatype 40.6)
- YAM v2.3p1 (sound.datatype 40.6)
- Wipeout2097
- Xgb (Game boy emulator)
1)
Some commands as ADCMD_WAITCYCLE had never been tested by external apps
(is very
rare they are used). They have been tested succesfully under the
audio.device
own test program only.
2) The device's init function probably touchs some register it
shouldn't. Some
programs (ADoom for example) at first audio.device opening, stops
forever after
had opened the device. I think is due to a stack or register problem. I
am
inquiring.
(50.0
- 1.4.2004)
A final extreme experiment on the low level approach had failed. I
tried this:
At the audio.device first open i alloc a very large mem block for audio
buffering. Then i turn on ahi so just at the beginning ahi is always
reproducing
a sample full of zeros. When an audio request income i copy its data
for the
requested lenght on the buffer so it starts immediately because ahi was
just
infinite looping under that mem area. I need just to copy the data and
change
len and freq. For our ppc processor this should be an easy work
considering that
this coding way looks like the unrool technique. Unlucky this approach
is too
extreme and the multitasking may corrupts too much the output. The
global
behaviour results totally out of controll, there are too many delays
and a big
noise in the background. Audio wants quality... so in future lets leave
the
narrator.device where it is... it is a too old piece of software. Its
the time
to write it again! ;-)
All
the experimental pieces of code will be removed before the next
releases.
(50.0 - 20.3.2004)
Added the configuration layer trought the dos.library/GetVar(). Since
today some
configuration inputs could be read from some global vars in
"env:audio.device/".
Actually is supported the MINPERIOD input value only. All the test
previously
done with the use of the low level api failed. It seems AHI is not
enought fast
in reproducing the audio when requesting too many commands per second
at short
lenght. The supporting is still left there. Now is sure that to have a
good
device reaction to the inputs a process pri of 127 is strictly needed.
(50.0 - 25.2.2004)
Started today a great change to the code tring to fix a problem with
the
narrator.device. I am replacing the ahi.device use with the ahi low
level api
protocol in conjunction with the timer.device to count real the sample
lenght.
Replaced CTR_SIG_BREAKF with the SIGF_DOS signal one for the controll
exchange
protocoll.
(50.0 - 19.1.2004)
Some small changes to get Delitracker compatible at program starting
and exiting.
In any case Delitracker bangs the hardware soon after an ADCMD_LOCK and
on
MorphOS it dies. If you don't play anything the program exits well.
Some fixes
to the Slave Process init procedure too.
(50.0 - 17.12.2003)
Rewritten a small part of the builtin audio.device command (CMD_CLOSE)
thought
to die the slave process. A fix now lets the device to work regularly
with
CMD_WRITE commands with more than one single cycle per wave
(ioa_Cycles) as it
happens in "Ports of Call" game. Added again some semaphores where
they are strictly needed.
(50.0 - 15.11.2003)
After some tests i wrote again the linking protocol between the slave
process
and the main device unit. Because the slave process **MUST** be
synchronized
with the device in certain situation were the data sharing model is not
allowed
i searched for a signal bit number which the slave process could use to
unlock
the device waiting. The device infact sends the command to the slave
process and
soon after it waits for a signal while the slave process is touching
some
structures they can't manage in the same time. When this lapse is ended
the
device is unlocked trought a signal. But which signal bit number use
for this
controll exchange? Well, the own IORequest signal is not sufficent when
a task
sends command from more than one task. This is the example of Wipeout.
It has
two tasks, one opens the device and waits for the commands end the
other sends
them only. Reply to the waiting one before the command is end made a
lot of
confusion to the app which had a task completely locked. An other way i
used in
the past was to alloc a signal for each Task the device receives
command from.
So i putted a copy of the pointer of each of them in a list and when a
command
was received i went to see if a signal was just ready for that task. If
it was
just allocated i used it for the linking procedure. This was a really
big waste
of time because at each command i had to do a long reasearch trought
the list.
So finally i adopted this method which somebody could consider
dangerous, but
since today it has always worked. Simply when i receive an IORequest i
obtain
its task pointer. I stole to it the CTRL_SIG_BREAKF signal and then i
force it
to wait for this signal only. When the controll exchange is done i
bring back
the task's wait signal set to its initial status. Hope this will work
ever!
(50.0 - 2.10.2003)
A very long inactive time on this project. In this new release the
device has
been re-styled deeply and the version was brought down again to the
50.0. The
most important changes of this re-styled version.
1)
No more the FAKE and REAL operating modes difference. Now the device
works only
in REAL mode so it outputs really the audio trought ahi.device which
now is
strictly needed al least in version v4. If it isn't present on the
system the
device fails just in OpenDevice().
2) Erased totally the virtual channels system. Now there are only 4
channels, or
better 4 units as the original audio.device had. The units are under
the slave
process control and each one has a message port thought to receive
CMD_WRITEs
commands only. All the other commands are received by an other one
message port
controlled by the slave process again.
3) No more IORequest mirroring but fast message handling between the
device and
the slave process.
4) Added the original audio.device's double buffering technique. When
more than
two CMD_WRITEs are sent to the device the first is output, the second
is put in
a cache the others are inserted in a wait list. This allows to start
faster the
second wave when the first is ended so the null audio lapse between
them is
shorter for a better sound quality.
5) Rewritten all the commands functions. Now they are faster. Rewritten
AbortIO()
which was one of the bigger problem of the past revisions. Now seems
very stable
and effectively functional.
6) Erased the old link system used to interact with the slave process.
Actually
is used the IORequest own replyport and signal.
7) Rewritten BeginIO(), OpenDevice() and CloseDevice() internal
routines and the
slave process main loop totally. Erased a lot of old code and complex
procedures.
The device now is smaller, simpler and faster.
8) Erased all the semaphores used in BeginIO(), AbortIO() and in the
OpenDevice()
and CloseDevice() internal functions.
(52.2 - 16.4.2003)
Not a new revision but a lot of few changes in the code to make it
faster and
more stable.
(52.2 - 10.4.2003)
A lot of improvements on this release. Rewritten TOTALLY AbortIO(). Now
a lot of
programs which gave problems in the past are working properly.
Rewritten
CMD_FLUSH and CMD_FINISH. Moreover i modified the process priority.
This may be
dangerous but since i increase it all the programs under testing are
working
better. The priority now is 127. Because the original audio.device
worked
trought hardware interrupts is clear that a software device needs to be
faster
as possible in replying to the programs.
(52.1 - 10.4.2003)
Modified the AHI starter. Actually i am using BeginIO() instead of
SendIO().
This seems better in certain circustances.
(52.0 - 7.4.2003)
Rewritten ADCMD_PERVOL. Actually it does a lot of usefull things. It
modifies on
channel the period and volume as the classic audio.device used to do.
(51.9 - 4.4.2003)
Activated again the FAKE mode. It works as well as the REAL mode one.
Rewritten
some parts of code which were not allowing to enable the -02 GCC
optimization.
(51.8 - 2.4.2003)
Rewritten the system which manages, finds, allocs, frees the virtual
channels.
Actually the channel struct at beginning has a node struct. This allows
to move
channels between lists without moving data or copying structure fields
for each
audio output. Actually the exec.library/AllocSignal() not checked is
fixxed.
When a task opens the audio.device its task's struct address is put in
a list.
The list contains for the task a just allocated signal and some structs
just
ready to make faster initializations and slave process message
exchanging. Most
part of the code was optimized erasing function calls with quick memory
array
accesses (the case of the count chans routine).
(51.7 - 28.3.2003)
Fixxed the NT_MESSAGE IOAudio node-type problem in BeginIO() so now
most
programs which use CheckIO() now work (ADoom). Fixxed a bug in
ADCMD_ALLOCATE
when the task asks for a particular channel key just known. Rewritten
ADCMD_PERVOL even if actually it does nothing special more than null.
Added in
this doc a program compatibility list. Tested with 12 channels and 4
programs at
4 channels for each succesfully (only one didn't exit!).
(51.6 - 22.3.2003)
Rewritten totally the system which manages lists. Verified, under
Samplitude
Opus, the CMD_STOP and CMD_START. Now they work. Removed the FAKE mode
part of
code. It will be added again later recycling the REAL mode routines
after the
needed tests. So in release 51.6 the device works exclusively in REAL
mode. The
whole is still 68k, not optimized.
(51.5 - 12.3.3003)
Rewritten the exit routines in the slave process. Actually the process
is
removed from the device itself. Rewritten the device init functions
which inits
the slave process and an usefull semaphore. The tests under MorphOS
actually are
going well. No hits and no bad memory accesses.
(51.4 - 02.3.2003)
Fourth release. The device supports definitely AHI. The audio output is
functional and good. I tested it with my PuzzleBOBS game and it works.
Rewritten
the AbortIO() function so most of programs which use it now work. The
device now
performs less operation during each audio initializing for better
performance.
(51.3 - 20.2.2003)
Third release. Added some code for the REAL mode. The slave task
actually is a
process allowing to open the ahi.device. The system opens AHI if it
founds it.
If not it swaps into FAKE mode. Actually
is ready to work in REAL mode. Moreover the device was tested with 8
channels
and two programs asking both for 4 channels. The test was successfull
but in
this release the number of channels was brought to 4 maximum again. The
whole is
still GCC 68K compiled without any optimizations. Under MorphOS all the
hits to
Ramlib are disappear (there were some not allowed memory accesses).
(51.2 - 19.2.2003)
Fixxed the message link system beetween slave task and audio.device
with the use
of exec.library/AllocSignal() and exec.library/FreeSignal(). The whole
is now
faster and the major problems of the second release seem solved. The
problem
about the bad count period now is fixxed even if it result a bit longer
than the
real audio.device one. This time difference increases when there are
more than
one cycle for wave. That is due to the work done by the slave process
which
loses time initialiting again the timer.device each cycle. The
optimization of
the slave process main code in conjunction with the adoption of the ppc
code
should reduce the problem. This version wont be released.
(51.1 - 15.2.2003)
Second release. Some bugs were removed and the whole is improved.
Actually at
opening and closing (exec.library/OpenDevice() and
exec.library/CloseDevice())
the problems present in the revision 0 are fixxed. Some RamLib's hits,
but no
gurus. All the resources are freed and generally the whole seems
working well.
The bad count period is already present and sometimes when two task
open it at
the same time, one of them results locked at opening and the other at
closing.
(51.0 - 11.2.2003)
First release. The device is ready but needs to be deeply tested.
Actually is
68k, supports only 4 channels and works in FAKE mode. Sometimes it
crashes. If
you run the test program from shell add some mem to stack before. This
may rend
it more stable.
All of the files in
this archive are
Copyright 2003 Nexus Development of Emanuele Cesaroni.
/\/exus
/)evelopment