Metropoli BBS
VIEWER: sound.doc MODE: TEXT (ASCII)
SOUND.DOC -- Description of the Sound Generation Routines in SOUND.ASM
======================================================================

  From `BLUEBOOK of ASSEMBLY ROUTINES for the IBM PC & XT'
        by Christopher L. Morgan
        Copyright (C) 1984 by The Waite Group, Inc.

  Purpose:
  -------- 
         The routines in SOUND.ASM are useful for producing sound on the
    PC via the speaker and associated timer chip. The routines named 
    TONExxxx are primitives that directly access the speaker and timer.
    All other routines call these routines to produce any sound.
 
   Contents:
   ---------
   DELAY	--  Delay for a specified time interval	
   FREQ		--  Convert from frequency to period
   GLISSNDO	--  Make a glissando (sliding tone)
   LINSCALE	--  Provide linear scaling
   PITCH	--  Convert from pitch number	
   PLAY		--  Play music from a table
   TONE		--  Make a tone
   TONE_INIT	--  Initialize speaker timer
   TONE_OFF	--  Turn off tone
   TONE_ON	--  Turn on tone
   TONE_SET	--  Set the tone on the speaker
 
  Overview:
  ---------
	The speaker is connected to the output of timer 2, which produces a 
  square wave whose frequency can be set using the TONE_SET routine.  TONE_SET
  assumes the timer has been properly initialized, as is done during normal
  boot-up.  TONE_INIT can also be used to initialize the timer.
	The frequency of the square wave from the timer is determined by the
  formula, f=F/n, where f is the frequency of the square wave, F is 1,193,182
  and n is a 16-bit integer that is input to the routine.  The constant, F, is
  exactly 1/3 the frequency of the NTSC subcarrier used for color encoding by
  the Color/Graphics Adapter.  F is derived by hardware from a main clock
  signal that runs at 14,317,800 Hertz and supplies the timing for most of the
  computer.
	TONE_ON and TONE_OFF provide control over whether the square wave
  reaches the speaker, thus turning the sound on or off.  There are actually
  two bits involved, one to control the connection between the clock signal
  and the timer, and one to control the connection between the timer and the
  speaker.  Both routines switch both connections simultaneously.  There is
  no provision to control the bits independently.
	The routine, DELAY, provides timing for the duration of musical notes
  in milliseconds.  The routine, FREQ, uses the formula, n=F/f, to compute
  the input parameter for TONE_SET from a given frequency.  Using this just
  before TONE_SET permits working directly with frequencies rather than clock
  cycles of the 1,193,182 Hertz clock.
	The routine, TONE, uses the other routines to produce tones of a
  given frequency and duration.  The frequency is input as a 16-bit integer
  and the duration is in milliseconds using the DELAY routine.
	The rest of the routines provide special sound effects.  SCALE converts
  numbers between 0 and 1 into numbers within the range of X1 and X2, which
  are any specified 16-bit integers.  This is used with RANDOM to produce
  pseudo-random numbers between 0 and 1.  The routine, WHITE, uses these 
  pseudo-random numbers along with SCALE to generate white noise.  The routine,
  GUN shows how to shape white noise into a machine gun sound.
	The routine, GLISSANDO, makes a tone that slides smoothly from one
  frequency, X1, to another, X2.  RED shows how to shape glissandos into red
  alert sirens.
	PITCH and PLAY are music routines.  PITCH converts the pitch number
  to a value useable by TONE_SET to set the frequency.  PLAY plays music from
  a "playlist" of notes.

__________________________ Descriptions of Routines __________________________

DELAY -- Delay for a specified number of milliseconds
-----------------------------------------------------
  Function: This routine provides a time delay for specifying the 
    duration of a sound, a wait, etc.  

  Input: Upon input, CX contains the no. of milliseconds to delay.

  Output: None

  Register used: CX is first saved and then restored.
_______________________________________________________________________________

FREQ -- Convert from Frequency to Period
----------------------------------------
  Function: This routine  converts from frequency to the number required
    by TONE_SET to set the frequency.  The routine evaluates the formula,
    N = F/f, where f is the frequency input to this routine, n is the number 
    output by this routine, and F is 1,193,182. In other words, this routine
    divides the specified frequency, f, into the 1,193,182 hertz clock
    frequency that drives the timer.  Use this routine just before TONE_SET.

  Input: Upon entry, the frequency is in CX.

  Output: Upon exit, F/f is in CX.

  Registers used: CX is modified, AX & DX are first saved and then restored.
_______________________________________________________________________________

GLISSNDO -- Make a Glissando
----------------------------
  Function: This routine makes a glissando; i.e., a sound that slides from
    one frequency to another.  The rate of change can be controlled.

  Input: Upon entry, the starting frequency is in BX, the ending frequency
    is in CX, and the control parameter for the rate increase is in DX.
    Increasing the value in DX slows down the rate of change.

  Output: To the speaker and timer only.

  Registers used: All registers are saved and then restored.

  Segments referenced: The data segment must contain the variables,
    F_START & F_END.

  Routines called: TONE_SET, TONE_ON, TONE_OFF, DELAY

  Special note: The speaker timer must already have been initialized.  If
    necessary, use TONE_INIT to initialize before calling this routine.
_______________________________________________________________________________

PITCH -- Convert from Pitch Number
----------------------------------
  Function: This routine converts from pitch number to the value required
    by TONE_SET to set the frequency. The pitch numbers refer to an 
    extended chromatic scale. The notes of this scale are numbered from
    0 to 95 with 12 notes/octave. 0 corresponds to a C at 16.35 hertz.

  Input: Upon entry the pitch number of the note is in AL.

  Output: Upon exit, the DX register has the proper value for TONE_SET.

  Registers used: DX has value; AX, BX, & CX are saved and then restored.

  Segments Referenced: The data segment must contain the
                        following pitch table:

	NOTES	DW	4186			;C
		DW	4435			;C#/D-
		DW	4699			;D
		DW	4978			;D#/E-
		DW	5274			;E
		DW	5588			;F
		DW	5920			;F#/G-
		DW	6272			;G
		DW	6645			;G#/A-
		DW	7040			;A
		DW	7459			;A#/B-
		DW	7902			;B

  Routines called: FREQ
_______________________________________________________________________________

LINSCALE -- Do Linear Scaling
-----------------------------
  Function: This routine performs a linear scaling, converting a fixed
    point number between 0 and 1 into an integer between X1 and X2, 
    where X1 and X2 are 16-bit integers.

  Input: Upon entry, CX has a binary fixed point number between 0 and 1.
    The binary point is to the left of the leftmost bit. X1 and X2 are
    variables stored in memory.

  Output: Upon exit, CX contains the 16-bit integer result.

  Registers used: CX is modified, AX & DX are first saved and then restored.

  Segments referenced: The data segment must contain the variables, X1 & X2.
_______________________________________________________________________________

PLAY -- Play Music
------------------
  Function: This program plays music.  It reads a binary "play" list
    that contains instructions to make the tune.  This list consists
    of a series of music instructions: Tempo, Note, Rest, and End.

    The syntax for the instructions are:

      Tempo Command
        first byte  = ASCII "T"
        second byte = tempo in whole notes/minute

      Note Command
        first byte  = ASCII "N"
        second byte = pitch number (integer 0-95)
        third byte  = length (8-bit binary fixed point - scale 1)
        fourth byte = style (8-bit binary fixed point - scale 0)

      Rest Command
        first byte  = ASCII "R"
        second byte = length (8-bit binary fixed point - scale 1)

      End Command
        first byte  = ASCII "X"

    The scaling is:
      scale 0 has the binary point to the left of the leftmost digit
      scale 1 has the binary point to the right of the leftmost bit

  Input: Upon entry, the address of the "play" list is in DS:SI

  Output: To the speaker and timer only

  Registers Used: Entry registers are saved and restored

  Segments Referenced: The data segment contains the "play" list and
                         the variables WHOLE, ACCOUNT, and RCOUNT

  Routines Called: PITCH, TONE_OFF, DELAY
_______________________________________________________________________________

TONE -- Make a Tone
-------------------
  Function: This routine makes a tone of a given frequency and given length.

  Input: Upon entry, the frequency is in CX and the length in no. of
    milliseconds is in DX.

  Output: To the speaker and timer only.

  Registers used: AX, CX, & DX are first saved and then restored.

  Segments referenced: The data segment must contain the variable, COUNT.

  Routines called: TONE_SET, TONE_ON, TONE_OFF, DELAY

  Special note: The speaker timer must already have been properly initialized.
    This should normally occur during boot-up.
_______________________________________________________________________________

TONE_INIT -- Initialize Speaker Timer
-------------------------------------
  Function: This routine initializes the part of the 8253 timer chip used
    by the speaker system.  Particularly, it sets up channel 2 of this 
    timer as a square wave generator. This routine does not select the 
    frequency, nor does it turn on the tone.  Use TONE_SET to select the
    frequency, TONE_ON to turn the tone on, and TONE_OFF to turn it off.

  Input: None

  Output: Only to the timer 2 of the speaker circuit.

  Registers used: AX is first saved and then restored.
_______________________________________________________________________________

TONE_OFF -- Turn off Tone
-------------------------
  Function: This routine turns of the timer and speaker.

  Input: None

  Output: To the timer and speaker only.

  Registers Used: AX register is first saved and then restored.
_______________________________________________________________________________

TONE_ON -- Turn on Tone
-----------------------
  Function: This routine turns on the timer and speaker to produce a tone.
    The frequency of the tone must have already been selected on the timer.
    you can use TONE_SET to set the frequency of the tone.

  Input: None

  Output: To the timer and speaker only.

  Register used: AX is first saved and then restored.
_______________________________________________________________________________

TONE_SET -- Set the Tone on the Speaker
---------------------------------------
  Function: This routine selects the frequency of the square wave tone to 
    the speaker.  The input to this routine is a 16-bit integer n which 
    determines the frequency, f, according to the following formula:
      f = F/n
    where F is 1,193,182, the frequency of a clock signal which feeds the
    timer.  The value, n, is the number of cycles of the clock signal per
    cycle of the resulting square wave.  This routine does not actually 
    turn on the tone.  Use TONE_ON to turn on the tone, and TONE_OFF to turn
    it off. This routine assumes the speaker timer has already been properly
    initialized.  This happens during normal boot-up, or you can use 
    TONE_INIT to initialize the timer.

  Input: Upon entry, the 16-bit integer, n, is in the CX register.

  Output: Only to the timer 2.

  Register used: AX is first saved and then restored.
_______________________________________________________________________________
 >>>Physical EOF SOUND.DOC<<<

[ RETURN TO DIRECTORY ]