Sound Blaster 16: Difference between revisions

From OSDev.wiki
Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content added Content deleted
(editing tables, Code, Programing DMA)
Line 8: Line 8:
==Digital Signal Processor==
==Digital Signal Processor==
The DSP built into the Sound Blaster 16 supports playing and recording audio in 8-bit and 16-bit PCM encoded samples, along with playing several other formats (ADPCM, etc.). The base I/O register address can be found using the PCI bus for PCI models, or by detecting the presence of an older ISA Sound Blaster by issuing a Get Version command to one of several common I/O port addresses (0x220, 0x240, etc.) and waiting for a response.
The DSP built into the Sound Blaster 16 supports playing and recording audio in 8-bit and 16-bit PCM encoded samples, along with playing several other formats (ADPCM, etc.). The base I/O register address can be found using the PCI bus for PCI models, or by detecting the presence of an older ISA Sound Blaster by issuing a Get Version command to one of several common I/O port addresses (0x220, 0x240, etc.) and waiting for a response.
To play audio, the ISA DMA controller must be programmed, then the DSP must be issued a Set Output Sample Rate command, and a Play command that includes the format of the audio (mono/stereo, signed, etc.) and a sample count.

Base port for DSP ports is 0x220.


{| {{wikitable}}
{| {{wikitable}}
! Offset
! Port
! Description
! Description
|-
|-
| 0x226 || DSP Reset
| 0x04 || Mixer Port (Set to 0x82 for Interrupt Status)
|-
|-
| 0x05 || Mixer Data (Read to get Interrupt Status)
| 0x22A || DSP Read
|-
|-
| 0x22C || DSP Write (Read this port for Write Status)
| 0x06 || DSP Reset
|-
|-
| 0x22E || DSP Read Status (Read this port to acknowledge 8-bit interrupt)
| 0x0a || DSP Read
|-
|-
| 0x0c || DSP Write (Read this port for Write Status)
| 0x22F || DSP 16-bit Interrupt Acknowledge (Read this port to acknowledge 16-bit interrupt) (DSP Version 4.0+ Only)
|-
| 0x0e || DSP Read Status (Read this port to acknowledge 8-bit interrupt)
|-
| 0x0f || 16-bit Interrupt Acknowledge (Read this port to acknowledge 16-bit interrupt) (DSP Version 4.0+ Only)
|-
|-
|}
|}
Line 39: Line 31:
| 0x41 || Set Output Sample Rate
| 0x41 || Set Output Sample Rate
|-
|-
| 0xa6 || Play PCM (Auto Initialize DMA, FIFO Enabled)
| 0xB6 || Auto transfer mode
|-
|-
| 0xd9 || Stop PCM (Auto Initialize DMA)
| 0xD5 || Stop playing
|-
|-
| 0xe1 || Get DSP Version
| 0xE1 || Get DSP version
|-
|-
|}
|}
Line 51: Line 43:
Because you only have a single DMA buffer to transfer data, it is recommended that you issue the Play PCM command with a sample count of half of the data buffer. This will fire an interrupt when the buffer is half played, allowing you to refill the segment that was just played, while the DSP continues playing the other half, and so on.
Because you only have a single DMA buffer to transfer data, it is recommended that you issue the Play PCM command with a sample count of half of the data buffer. This will fire an interrupt when the buffer is half played, allowing you to refill the segment that was just played, while the DSP continues playing the other half, and so on.


===Reading or writing===
===Reading and writing===
Until you write to the DSP write port, check the DSP write port is 0x00. Until reading the DSP read port, check the DSP status for 0x80.
Until you write to the DSP write port, check the DSP write port for 0x00. Until reading the DSP read port, check the DSP status port for 0x80.


==Detecting DSP==
==Detecting DSP==
Line 61: Line 53:
# Load sound data to memory
# Load sound data to memory
# Program ISA DMA
# Program ISA DMA
# Set output sample rate(0x41/Low byte/High byte eg 22050 hz 0x56/0x22)
# Set output sample rate(command/High byte/Low byte)
# Write DMA transfer type to DSP
# Write DMA transfer type to DSP(command)
# Write data lenght to DSP(low byte/high byte)
# Write data lenght to DSP(Low byte/High byte)


===Programming ISA DMA===
===Programming DMA===
{| {{wikitable}}

! Port
==Transfer modes==
! Description
ISA DMA can transfer in two modes: Single or Auto.
|-
| 0xC4 || Address
|-
| 0xC6 || Count
|-
| 0x8B || Page
|-
| 0xD4 || Single mask
|-
| 0xD6 || Transfer mode
|-
| 0xD8 || Clear pointer
|-
|}


==Code==
==Code==
<source lang="C">
<source lang="C">
//Digital Sound Processor ports
#define DSP_RESET 0x226
#define DSP_RESET 0x226
#define DSP_READ 0x22A
#define DSP_READ 0x22A
Line 78: Line 85:
#define DSP_STATUS 0x22E
#define DSP_STATUS 0x22E
#define DSP_INTERRUPT 0x22F
#define DSP_INTERRUPT 0x22F

//Digital Sound Processor commands
#define DSP_CMD_OUTPUT_RATE 0x41
#define DSP_CMD_TRANSFER_MODE 0xB6
#define DSP_CMD_STOP 0xD5
#define DSP_CMD_VERSION 0xE1

//DMA ports
#define DMA_ADDRES 0xC4
#define DMA_COUNT 0xC6
#define DMA_PAGE 0x8B
#define DMA_SINGLE_MASK 0xD4
#define DMA_TRANSFER_MODE 0xD6
#define DMA_CLEAR_POINTER 0xD8


void reset_DSP(void) {
void reset_DSP(void) {
outb(DSP_RESET, 1);
outb(DSP_RESET, 1);
sleep(3); //wait 3 microseconds
outb(DSP_RESET, 0);
outb(DSP_RESET, 0);
Line 97: Line 119:


//get DSP version
//get DSP version
write_DSP(0xE1);
write_DSP(DSP_CMD_VERSION);
sb16_version_major=read_DSP();
sb16_version_major=read_DSP();
sb16_version_minor=read_DSP();
sb16_version_minor=read_DSP();

Revision as of 14:57, 17 September 2018

This page is a work in progress.
This page may thus be incomplete. Its content may be changed in the near future.

The Sound Blaster series is a family of sound cards made by Creative. For many years they were the standard audio cards on IBM PC's.

Introduction

The Sound Blaster 16 is the successor to the Sound Blaster Pro audio card found in many older computers. It was first brought out in 1992. The main improvement over the Pro is its 16-bit digital audio sampling (hence the name). Most SB16 cards are PCI compatible, as Creative made this improvement shortly after releasing the card, upgrading from ISA.

Digital Signal Processor

The DSP built into the Sound Blaster 16 supports playing and recording audio in 8-bit and 16-bit PCM encoded samples, along with playing several other formats (ADPCM, etc.). The base I/O register address can be found using the PCI bus for PCI models, or by detecting the presence of an older ISA Sound Blaster by issuing a Get Version command to one of several common I/O port addresses (0x220, 0x240, etc.) and waiting for a response.

Port Description
0x226 DSP Reset
0x22A DSP Read
0x22C DSP Write (Read this port for Write Status)
0x22E DSP Read Status (Read this port to acknowledge 8-bit interrupt)
0x22F DSP 16-bit Interrupt Acknowledge (Read this port to acknowledge 16-bit interrupt) (DSP Version 4.0+ Only)
Command Description
0x41 Set Output Sample Rate
0xB6 Auto transfer mode
0xD5 Stop playing
0xE1 Get DSP version

When the samples have been played, an interrupt will be fired, and the OS/Driver will have the chance to refill the buffer, or to issue a Stop command.

Because you only have a single DMA buffer to transfer data, it is recommended that you issue the Play PCM command with a sample count of half of the data buffer. This will fire an interrupt when the buffer is half played, allowing you to refill the segment that was just played, while the DSP continues playing the other half, and so on.

Reading and writing

Until you write to the DSP write port, check the DSP write port for 0x00. Until reading the DSP read port, check the DSP status port for 0x80.

Detecting DSP

Detecting DSP is really easy. You must send to DSP reset port 1, wait 3 microseconds, send to DSP reset 0 and read DSP read port. If in it is 0xAA, DSP exist.

Playing sound

  1. Detect DSP
  2. Load sound data to memory
  3. Program ISA DMA
  4. Set output sample rate(command/High byte/Low byte)
  5. Write DMA transfer type to DSP(command)
  6. Write data lenght to DSP(Low byte/High byte)

Programming DMA

Port Description
0xC4 Address
0xC6 Count
0x8B Page
0xD4 Single mask
0xD6 Transfer mode
0xD8 Clear pointer

Code

//Digital Sound Processor ports
#define DSP_RESET 0x226
#define DSP_READ 0x22A
#define DSP_WRITE 0x22C
#define DSP_BUFFER 0x22A
#define DSP_STATUS 0x22E
#define DSP_INTERRUPT 0x22F

//Digital Sound Processor commands
#define DSP_CMD_OUTPUT_RATE 0x41
#define DSP_CMD_TRANSFER_MODE 0xB6
#define DSP_CMD_STOP 0xD5
#define DSP_CMD_VERSION 0xE1

//DMA ports
#define DMA_ADDRES 0xC4
#define DMA_COUNT 0xC6
#define DMA_PAGE 0x8B
#define DMA_SINGLE_MASK 0xD4
#define DMA_TRANSFER_MODE 0xD6
#define DMA_CLEAR_POINTER 0xD8

void reset_DSP(void) {
          outb(DSP_RESET, 1);
          sleep(3); //wait 3  microseconds
          outb(DSP_RESET, 0);
          
          if(read_DSP()==0xAA) { 
                    sound_blaster=TRUE; 
          }
}

void sb16_init(void) {
          reset_DSP();

          //if DSP doesnt exist
          if(sound_blaster==FALSE) {
                    return;
          }

          //get DSP version
          write_DSP(DSP_CMD_VERSION);
          sb16_version_major=read_DSP();
          sb16_version_minor=read_DSP();

}

See Also

External Links