Wikia

Doom Wiki

PC speaker sound effects

3,479pages on
this wiki
Talk1
Chocolate Doom PC speaker00:24

Chocolate Doom PC speaker

Chocolate Doom running with emulated PC speaker sound effects.

When Doom was released, digital sound cards had not yet become as ubiquitous as they now are. Therefore, a large number of the computers playing Doom did not have sound cards. As a workaround for this, id Software included two sets of sound effects: alongside each of the digital sound effects that are played on sound cards, there is an equivalent PC speaker sound effect that plays through the PC speaker found on all PCs.

While digital sound effects have the prefix "DS" inside the Doom IWAD, PC speaker sound effects have the prefix "DP". For example, the sound of a pistol firing is stored in the lump named "DSPISTOL"; the corresponding PC speaker sound effect is named "DPPISTOL".

The format is notable in that it was the last WAD lump format to be properly decoded and understood. The Doom source code release did not include the PC speaker code, as it was part of the proprietary DMX sound code that was removed from the source code before its release (evidence of this can be seen in the Heretic source code). As PC speaker sound effects were no longer necessary by this time, little effort was made in properly determining the format.

The format was finally properly reverse-engineered in 2007 by Andrew Apted and Simon "Fraggle" Howard.

Format

PC speaker sound effects have a four byte header that is used to specify the length of the sound. That many bytes then follow.

Each byte corresponds to a tone that is played for 1/140th of a second (this corresponds to 4*35, where 35 is the number of frames per second in Doom). The frequency values used are on a musical scale; there are 24 notes per octave, which corresponds to double that of the western musical scale (12 notes per octave). The values are therefore a superset of the western musical scale, with an extra microtone inserted between each note.

Because of this, the frequencies increase exponentially with respect to the byte values. Adding 24 to the value doubles the frequency. A value of 0 causes silence.

Following simple program (Turbo/Borland Pascal for DOS is required; it might not be operable unless within raw DOS execution environment) can be used as example player of PC speaker sound effects lump.

 USES Dos, CRT;

 TYPE HugeArray=PACKED ARRAY [0..65519] OF Byte;
      DynamicArray=^HugeArray;

 VAR oldTimer:Pointer; curBreak,ready:Boolean; curPos, dataLength: LongInt;
     data:DynamicArray; i:Integer; inFile:FILE; curFile:SearchRec;
     PredExitHandler:Pointer;

 CONST clocker=1193180;
       ReCalc=15;
       Skip:Boolean=FALSE;

 PROCEDURE RestoreEnv; FAR;
 BEGIN
  Port[$43]:=$36;                                { 00 11 011 0 }
  Port[$40]:=0;
  Port[$40]:=0;
  SetIntVec(8, oldTimer);
  SetCBreak(curBreak);
  ExitProc:=PredExitHandler
 END;

 PROCEDURE chainTimer;
  INLINE($9c/$ff/$1e/oldTimer);         {pushf ^ call ds:}

 PROCEDURE Help;
  VAR HelpScreen:Text; Dir: DirStr; Name: NameStr; Ext: ExtStr;
 BEGIN
  Assign(HelpScreen, 'CON');
  ReWrite(HelpScreen);
  FSplit(ParamStr(0), Dir, Name, Ext);
  WriteLn(HelpScreen, 'Usage:', Chr(9), Concat(Name, Ext), Chr(9), 'RAW_File');
  Close(HelpScreen);
  Halt
 END;

 PROCEDURE newTimer; INTERRUPT;
  CONST counter:Byte=0;
 BEGIN
  Inc(counter);
  IF counter=6
   THEN BEGIN
    chainTimer;
    counter:=0 END
   ELSE Port[$20]:=$20;
  IF ready
   THEN BEGIN
    IF curPos=dataLength
     THEN BEGIN
      Port[$61]:=Port[$61] AND NOT 3;
      ready:=FALSE END
     ELSE IF data^[curPos]=0
           THEN Port[$61]:=Port[$61] AND NOT 3
           ELSE BEGIN
            Port[$43]:=$b6;                     { 10110110 }
            Port[$42]:=clocker DIV (data^[curPos]*ReCalc) MOD 256;
            Port[$42]:=Byte(clocker DIV (data^[curPos]*ReCalc) DIV 256);
            Port[$61]:=Port[$61] OR 3
           END;
    Inc(curPos)
   END
 END;
BEGIN
 IF ParamCount<1
  THEN Help;

 PredExitHandler:=ExitProc;
 GetCBreak(curBreak);
 SetCBreak(FALSE);
 CheckBreak:=FALSE;
 GetIntVec(8, oldTimer);
 PredExitHandler:=ExitProc;
 ExitProc:=Addr(RestoreEnv);
 SetIntVec(8, Addr(newTimer));
 Port[$43]:=$36;                                { 00 11 011 0 }
 Port[$40]:=Byte(clocker DIV (18*6) AND 256);
 Port[$40]:=Byte(clocker DIV (18*6) SHR 8);
 FileMode:=0;

 FOR i:=1 TO ParamCount DO BEGIN
  FindFirst(ParamStr(i), AnyFile AND NOT(Directory AND VolumeID), curFile);
  IF Skip THEN Break;
  WHILE (DosError=0) AND NOT Skip DO BEGIN
   Write(curFile.Name, '...');
   Assign(inFile, curFile.Name);
   Reset(inFile, 1);
   GetMem(data, 4);
   BlockRead(inFile, data^, 4);
   dataLength:=data^[2]+data^[3] SHL 8;
   FreeMem(data, 4);
   GetMem(data, dataLength);
   BlockRead(inFile, data^, dataLength);
   ready:=TRUE;
   curPos:=0;
   WHILE ready DO;
   FreeMem(data, dataLength);
   Close(inFile);
   WriteLn(^H^H^H' done.');
   Delay(500);
   WHILE KeyPressed DO
    Skip:=Skip OR (ReadKey=#27);
   FindNext(curFile)
  END
 END
END.

Source ports with PC speaker sound effects support

In addition to the original DOS versions of Doom, several source ports can play back the PC speaker sound effects. These include the following ports:

External links

Around Wikia's network

Random Wiki