Sound Blaster Driver

Unit: SBDSP

Sound Blaster DSP driver with DMA-based digital audio (1995, Romesh Prakashpalan).

Types

type
  BaseSoundType = Record
    Frequency: Word;      { Sample rate (11025, 22050 Hz) }
    DACType: Byte;        { EightBitDMA, HighSpeedDMA, etc. }
    Phase: PhaseType;     { Mono, Stereo, Surround }
    Buffer: Pointer;
    BufferSize: Word;     { Max 64KB }
  end;

  RPDHeader = Record
    Sig: Array[0..2] of Char;  { "RPD" }
    Version: Word;
    DAC: Byte;
    Phase: PhaseType;
    Freq: Word;
    Size: LongInt;
    { ... }
  end;

  PhaseType = Mono..Surround;

Constants

const
  { Volume levels (use with ChangeVolumeLevel) }
  SilentVol    = 10;   { 0.00x }
  HalfVol      = 3;    { 0.50x }
  NormalVol    = 0;    { 1.00x }
  DoubleVol    = 1;    { 2.00x }
  QuadrupleVol = 2;    { 4.00x - may distort }

  { DMA transfer types }
  EightBitDMA     = $14;  { Standard 8-bit PCM }
  HighSpeedDMA    = $91;  { >22 kHz }
  SixteenBitDMA   = $B6;  { SB16 only }

  { Input sources }
  Mic1Input = 0;
  CDInput   = 1;
  LineInput = 3;

Globals

var
  Playing: Boolean;         { True if sound is playing }
  Recording: Boolean;
  CurrentSound: SoundType;

Functions

Initialization

function ResetDSP(Base, IRQ, DMAChannel, HighDMA: Byte): Boolean;
procedure InstallHandler;
procedure UninstallHandler;  { CRITICAL: Call before exit }

Base values: 1=$210, 2=$220 (most common), 3=$230, 4=$240 IRQ: 5 or 7 DMA: 1 (8-bit), 5 (16-bit)

Playback

procedure PlaySound(Sound: BaseSoundType);
procedure PlaySoundRPD(Filename: String);  { Streaming, no size limit }
procedure PlaySoundDSK(Filename: String; Frequency: Word; SoundType: Byte);
procedure LoadSoundRPD(Filename: String; var Sound: BaseSoundType; MemAlloc: Boolean);

Recording

procedure RecordSoundRPD(Filename: String; Freq: Word);
function StopRecording: Boolean;

Control

function SpeakerOn: Byte;
function SpeakerOff: Byte;
procedure DMAStop;
procedure DMAContinue;
procedure ChangeVolumeLevel(Amnt: Byte);  { Use volume constants }
function GetVolumeLevel: Byte;
function ChangeBufferSize(Size: Word): Boolean;
function CheckBufferSize: Word;

Mixer (SB Pro)

procedure ResetMixer;
procedure SetVocVolume(Left, Right: ProVolumeType);    { 0-15 }
procedure SetFMVolume(Left, Right: ProVolumeType);
procedure SetMasterVolume(Left, Right: ProVolumeType);
procedure SetMicVolume(Volume: MicVolumeType);         { 0-7 }
procedure SetInputSource(Filter: FilterType; TheInputs: InputSourceType);

Example

uses SBDSP;

var
  Explosion: BaseSoundType;

begin
  { Initialize }
  if not ResetDSP(2, 5, 1, 0) then  { Port $220, IRQ 5, DMA 1 }
  begin
    WriteLn('Sound Blaster not found!');
    Halt(1);
  end;

  { Play RPD file (streaming) }
  PlaySoundRPD('DATA\EXPLODE.RPD');
  while Playing do asm nop end;

  { Or preload for instant playback }
  LoadSoundRPD('LASER.RPD', Explosion, True);
  PlaySound(Explosion);
  while Playing do asm nop end;

  { Cleanup }
  FreeMem(Explosion.Buffer, Explosion.BufferSize);
  UninstallHandler;  { MUST call before exit }
end.

Critical Notes

  1. UninstallHandler - MUST call before exit or system hangs

  2. ResetDSP first - Call before any other functions

  3. 64KB limit - PlaySound limited to 64KB, use PlaySoundRPD for larger

  4. HSC conflict - Don’t use while Playing loop with HSC music (freezes)

  5. DMA boundaries - Handled automatically by driver

  6. Base port - Most cards use Base=2 ($220)

Creating RPD Files

VOC2RPD INPUT.VOC OUTPUT.RPD
WAV2RPD INPUT.WAV OUTPUT.RPD

Utilities in VENDOR/SBDSP2B/.

Notes

  • Double-buffered streaming for smooth playback

  • Minimal CPU usage (~1% on 386)

  • Compatible with SB Pro, SB16, AWE32

  • Real-time volume control during playback

  • See SNDBANK.PAS for XMS-based sound library manager