# Aros/Developer/AHIDriversDev

* Navbar for the Aros wikibook
* Aros User
* Aros User Docs
* Aros User FAQs
* Aros User Applications
* Aros User DOS Shell
* Aros/User/AmigaLegacy
* Aros Dev Docs
* Aros Developer Docs
* Porting Software from AmigaOS/SDL
* For Zune Beginners
* Zune .MUI Classes
* For SDL Beginners
* Aros Developer BuildSystem
* Specific platforms
* Aros x86 Complete System HCL
* Aros x86 Audio/Video Support
* Aros x86 Network Support
* Aros Intel AMD x86 Installing
* Aros Storage Support IDE SATA etc
* Aros Poseidon USB Support
* x86-64 Support
* Motorola 68k Amiga Support
* Linux and FreeBSD Support
* Windows Mingw and MacOSX Support
* Android Support
* Arm Raspberry Pi Support
* PPC Power Architecture
* misc
* Aros Public License

## Introduction

AHI is a system that is supposed to utilize the hardware for playing prepared sound.
Open Source Drivers - M Blom and G Steger (SBLive), M Schulz (ac97), D Wentzler (HDAudio, Envy24HT and CMI8738), R Vumbaca (SB128) and Krzysztof Smiechowicz (Alsa driver)
A typical device driver is usually in one of three conditions...
* inactive - needs to be installed, power startup or enable
* busy - uninstall, power down or disable, release a device
* finished - read or write requests, lock a device
AHI reads a “modefile” that describes the basic features of the sound driver like mono, stereo, 7.1 surround, etc. The driver is opened and goes looking for a matching sound card.
In case of audio drivers yes - pci are probed. But only the init routine defined by resident structure is called in most cases. If the driver cannot find suitable hardware it quits init and gets unloaded. In AHI config you will never see drivers which do not work.
AHI never talks straight to audio chipsets but it does communicate through buffers which contain details like how many channels are needed, how many bits per sample, and how the samples arrive. It builds up one buffer for talking to the sound chip and another that gets the chips' reply.
The typical way to feed continuously is called double-buffering. While the audio chips are playing the first buffer, AHI will be filling the next sounds into the second buffer. Once the playback routine moves onto the second buffer, the first one will be filled with new stuff, and so on. Obviously, it helps if the audio chipset also supports two buffers.
8, 16, or 32 bit in mono or stereo, or 32 bit 7.1 channels to be played by HW. Mixing multiple channels from apps is done by AHI. A less known detail: ALL modes labeled "HiFi" are using 32 bit samples between AHI and the driver, regardless of the resolution of the samples going in to AHI.
All variable quantities exposed to the user (or driver) are of type Fixed, which is a signed 32 bit fixed point value, with the "fixed point" between the upper16 bits and the lower 16. A value of 1 would be stored as 0x00010000, a value of 0.5 would be 0x00008000, 0.25 would be 0x00004000 etc..
This makes for much faster calculations than a floating point variable would offer.
The sound card is expected to create a hard interrupt as it completes each buffer of audio. Assuming two (or more) buffers are in use, this triggers the re-loading of the just completed buffer so that the sound card can run freely back and forth between two buffers and never run out of new sound. (double-buffering).
Drivers are written to conform with whatever AHI expects, and not the other way around. AHI has served us very well, and it has become the standard audio device for all Amiga inspired platforms, but as we grow into more modern hardware, we may be limited by the constraints of AHI design.
USB audio devices have had some trouble structuring an AHI driver that works with DeviceIO commands instead of being driven by hard interrupts. Some of the techniques that AHI used to make accessing the sound card "easy" are now making it more difficult than it should be. USB audio device works on like any other device would. It processes a queue of write requests, each carrying some amount of data to the sound hardware. There are no interrupts involved, just the same DeviceIO techniques that Exec has been doing since Workbench 1.0. changing over to USB would be almost as simple as changing the OpenDevice call.. but we are not so lucky. AHI will have a USB driver but the "old way" can make things more difficult than was originally expected.
AHI provides each program with volume controls.
sounds is interpreted by the ear in a logirithmic fashion so 10db is perceived as approximately twice as loud, note that's not the same as twice as powerful which is 6db of course.
But sound itself is just a pressure wave and is neither logorithmic nor linear, it just is.
Samples are typically store as LPCM (linear Pulse Code Modulation) and so can definitely be added together with simple addition.
As to AHI reducing the volume when mixing multiple samples, I believe there are several different modes, safe, safe dynamic, full volume, and -3 -6
Say you have 24 channels to mix. Given no other knowledge of the sample values in order to prevent clipping (which is very bad, for speakers or your ears if you have earphones in) you have to reduce the volume of each sample to 1/24, this is (I think) analogous to the safe mode.
This throws away a lot of quality by reducing the sample resolution. There may not be any overflow or very little but it still modifies the output volume. Of course, even in the real world, a lot of sounds together will cause saturation. The trick is to combine them together and compensate for this but still retaining the original sample volumes. Naturally louder sounds will drain out softer sounds so perhaps this can be used to an advantage. But I have seen A+B-(AB) a lot just now.
So if you have a variable number of samples you can reduce the volume by only the current number of used channels. So only 6 channels in use reduce to 1/6 much less loss in clarity but the unreal effect of more sounds reducing the apparent volume of each sub sound, (safe, dynamic)
Or you can take the computer out of the loop and assume the human (or software the human is running like a game doing its own mixing, or AudioEvolution etc.) make sane judgements, no attenuation, no loss of quality, but get it wrong and you blow your ears out. (Ful Volume mode). Since 90% of the time I'm only playing a single stereo stream I always use this option.
The -3 and -6 db modes just add bit of head room into the full volume equation.

## Quick Building

simple way to only recompile the HDAudio driver? running 'make AHI-quick' or 'make workbench-devs-AHI-quick' in AROS directory should to the trick. 'make AHI' will also rebuild dependencies of AHI
only says "MMAKE: Nothing to do for xxxx", despite changes being made The AHI build is done by using calling configure and calling make (%build_with_configure mmake macro). Because of that mmake does not see the dependencies; it just uses some stamp files. You can delete bin/__ARCH__-__CPU__/gen/workbench/devs/AHI and then call 'make AHI-quick'. I hope that should do the trick.
rebuilding AHI drivers is tricky. I use a command like this:
rm bin/pc-i386/gen/workbench/devs/AHI/.installed ; make workbench-devs-AHI-quick && cp bin/pc-i386/AROS/Devs/AHI/hdaudio.audio ...

## Overview of an AHI driver

The AHI source drivers are contained in the main source.bz2 and not contrib, each drivers sources has its own drawer in workbench/devs/AHI/Drivers.
Playback just does a straight copy to the buffer, and recording does nothing at all with the buffer. The buffer size is set by AHI based on sample rate and size, so that the interrupt rate will be 50 Hz. Typically they are around 8KB if I recall correctly for 44100/16bit. The size should not be changed.
If the hardware does not support 32 bit samples, you should re-enable HiFi in the AUDIOMODE so that AHI mixes at "HiFi" quality. The driver already takes care of skipping the upper part when a HiFi mode is used.

### MODEID

The Void drawer contains a dummy playback only driver

### name-main.c

Read more here

### DriverData.h
## AC97
## Structure of OpenSound OSS driver

The OSS API is designed to use the traditional Unix framework of open, read, write, and ioctl, via special devices. For instance, the default device for sound input and output is /dev/dsp.
PDF and Manual Page and sources.
Home Page and OSS BSD Source which is sometimes down.
AC97 Codec/Mixer support in /drv/ sources
via AC97 has Mixer, Read, Write, Interrupts, Audio Set Rate, Audio Set Channels, Audio IOctl, Audio Reset, Audio Reset Input and Output, Audio Open, Audio Close, Audio Start Input, Audio Trigger, Audio Prepare Input, Audio Prepare Output, Alloc Buffers, Get Buffer Pointer, SGD buffers, Control.
SBpci has SRC init, SRC Reg Read, SRC Reg Write, SRC Get Rate, SRC Set Rate, Writemem, Readmem, Interrupt, Audio Set Rate, Audio Set Channels, Audio Set Format, Audio IOctl, Audio Reset, Audio Reset Input and Output, Audio Open, Audio Close, Audio Output Block, Audio Start Input, Audio Trigger, Audio Prepare Input, Audio Prepare Output, Get Buffer Pointer, Control, Mix Init, SBPCI Attach, SBPCI Detach.
cmpci has Defines, Set SPDIF Rate, Setup AC3, Set Mixer, Get Mixer, Change Bits, Mixer Set, Outsw, Mixer IOCtl, Set Recmask, Outsw, Mix Init, Mixer Reset, Interrupts, Audio Set Rate, Audio Set Channels, Audio Set Format, Audio IOctl, Audio Reset, Audio Reset Input and Output, Audio Open, Audio Close, Audio Output Block, Audio Start Input, Audio Trigger, Set DAC Rate, Set DAC Fmt, Set ADC Rate, Set ADC Fmt, Setup Record, Audio Prepare Input, Setup Play, Audio Prepare Output, Get Buffer Pointer, Control, Mix Init, cmpci Attach, cmpci Detach.

## Interrupts

Interrupts can be triggered by the CPU (limited number) or through an additional chip which will have many more.
* asynchronously - resets or power failures
* synchronously - system calls, illegal instructions

## References

INTB_TIMERTICK hack was removed, do not use it any more At what rate does VERTB interrupt happen now?
How it used to be:
VERTB: always 50 Hz TIMERTICK: 100 Hz (default, could be changed with "-t" argument when starting AROS)
Some things like that AHI driver do not work well if it only happens at a rate of 50 Hz. Also a general timer precision of 50 Hz is bad. That's what the TIMERTICK hack fixed.
It was caused by the fact that sound chip did not have correctly set interrupt number. I managed to get correct IRQ by fiddling with BIOS settings.
If you look with PCITool your sound chips information and if it says something that IRQ is 255 or 0 then it is not correctly set.
I have posted about this IRQ thing before, at the moment PCI.hidd just takes the IRQ number from pci config space and does not check it's integrity. Bios may or may have not set the irq number, it all depends of your Bios settings.
the generic AC97 code separated out into an OO class which AHI drivers may utilise to provide the necessary functionality. (fwiw - an es137x driver for vmware/real hardware would also need AC97 "support")
/* SIS7012 handles the pcm data in bytes, others are in samples *
Ac97 driver supports 48 kHz audio only (this one is default to the ac97 codecs). Mixing does work (tried to run 3 copies of madahi at once with different mp3's). The driver's task works with priority 30 in order to override the input.device (well, sound should be played nicely when user moves/resizes the window, shouldn't it?) and fully utilizes interrupt :)
everybody likes to use the device interface to stream audio? In that case can you cache the sound until you have enough to send to the sound card on a hard interrupt?
Even with the low level library interface, which is made for module playing really, the driver caches the audio stream for each module interrupt (soft interrupt if you will), which is then sent to the sound card on the hardware interrupt.
Of course, this breaks if the module data plays faster than the card can handle, such as the OS4 EMU10K driver. Which was set to a 80 Hz hardware interrupt because the A1 had a problem IIRC with the normal value of 1000 Hz which worked on all other Amiga related drivers including the real thing. A module with a sound interrupt going over 80 Hz breaks and messed up the audio causing looping.