Ensoniq AudioPCI

From OSDev Wiki
Jump to navigation Jump to search

The Ensoniq AudioPCI is a low-cost PCI sound card that notably used software to emulate a MIDI synthesizer using a proprietary wave table format. It also supported up to 48kHz PCM input and output and up to 4 channels in some configurations. It is also one of the sound card models currently supported in VMWare virtual machines.

After the AudioPCI was released, Ensoniq was acquired by Creative Labs, which re-labeled the AudioPCI as the SoundBlaster PCI 64, and later the SoundBlaster PCI 128. The PCI Subclass and Revision registers can be used to detect exactly which model is installed, and each model has similar (but not identical) register sets.

I/O Registers

The following I/O mapped registers can be found by reading the BAR0 address of the Ensoniq AudioPCI device. These registers are used by the ES1371 and later models. (The earlier ES1370 model did not include an AC '97 Codec Read/Write register, and instead provided its own proprietary Codec register.)

Offset (Hex) Description
0x00 Control
0x04 Status
0x08 UART Data
0x09 UART Status/Control
0x0a UART Test Mode
0x0c Memory Page
0x10 Sample Rate Converter Read/Write
0x14 Codec Read/Write
0x18 Legacy
0x20 Serial Interface
0x24 Playback 1 Frame Count
0x28 Playback 2 Frame Count
0x2c Record Frame Count
0x30 (Page 0x0c) Playback 1 Buffer Address
0x34 (Page 0x0c) Playback 1 Buffer Definition
0x38 (Page 0x0c) Playback 2 Buffer Address
0x3c (Page 0x0c) Playback 2 Buffer Definition
0x30 (Page 0x0d) Record Buffer Address
0x34 (Page 0x0d) Record Buffer Definition
0x30 (Page 0x0e) UART FIFO Data

Playing Audio

To play PCM audio on the AudioPCI, the following registers must be configured:

  • Ensure that the PCI Bus Master flag is enabled for the device by setting bit 2 on the PCI Command register (0x04).
  • Reset the controller by writing 0x20 to the Status register (0x04). This flag will automatically reset back to 0 when the reset is complete.
  • Reset the CODEC by writing 0xff to the Codec register (0x14). This only applies to the 1371 AC 97 model and later.
  • Program the Sample Rate Converter to the appropriate sample rate using register 0x10. The specific values needed here must be calculated. See below.
  • Set the Master Volume and PCM Out Volume levels on the CODEC. These are muted by default.
  • Set the Memory Page register (0x0c) to 0x0c. This is the only page needed for audio playback.
  • Set the Playback 2 Buffer Address register (0x38) to the physical address of your audio buffer.
  • Set the Playback 2 Buffer Definition register (0x3c) to the size of the audio buffer, in DWORDS, minus one. This gives a maximum buffer size of 256K.
  • Set the Playback 2 Frame Count register (0x28) to the number of frames to play, minus one. After the last frame is played, an IRQ will be raised.
  • Set the Serial Interface register (0x20) to 0x0020020C to enable 16-bit stereo, interrupts and looped mode on Playback 2.
  • Set the Control register (0x00) to 0x00000020 to enable the Playback 2 DAC.

At this point, the audio should begin playing. You will receive an IRQ when the last requested frame is played. However, in looped mode, the audio will continue playing, and will loop around to the start of the audio buffer when the end of the buffer is reached. By setting the Frame Count register to play half of the audio buffer, you will receive an interrupt when the first half of the buffer has been played. This will allow you to fill the first half of the buffer while the second half is being played, and vice versa. After receiving an interrupt and filling the audio buffer, you must re-enable interrupts by clearing the interrupt enable flag in the Serial Interface register, and then setting it again.

The steps above use the Playback 2 channel to play PCM audio. The Playback 1 channel should work in a similar fashion. However, according to the documentation, it was designed to be used as a software MIDI synthesizer channel.

Sample Rate Converter

The Sample Rate Converter allows audio data to be converted to 48 kHz on the fly, and must be programmed with the proper values to perform the conversion from lower sample rates (8, 22, 44.1 kHz, etc.). This process is not well documented in the Ensoniq spec sheets. However, the formulas used to calculate the proper values can be found in various open source drivers for Linux and Windows CE.

The Sample Rate Converter is programmed using the Sample Rate Controller register (0x10). This single 32-bit I/O register is used to both read and write values in several registers located in the Sample Rate Converter's memory on the AudioPCI card.

Offset (Hex) Description
0x6c Record Volume
0x70 Playback 1 TruncN
0x71 Playback 1 IntRegs
0x72 Playback 1 AccumFrac
0x73 Playback 1 VFreqFrac
0x74 Playback 2 TruncN
0x75 Playback 2 IntRegs
0x76 Playback 2 AccumFrac
0x77 Playback 2 VFreqFrac
0x78 Record TruncN
0x79 Record IntRegs
0x7a Record AccumFrac
0x7b Record VFreqFrac
0x7c Playback 1 Volume
0x7e Playback 2 Volume

The following pseudo-code is used to program the Sample Rate Converter to a specific sample rate.

void SetPlayback2SampleRate(short rate)
{
    long frequency = (rate << 16) / 3000;

    SampleRateConverter[0x75] = (frequency >> 6) & 0xfc00;
    SampleRateConverter[0x77] = (frequency >> 1);
}

External Links