A92: Re: Simple Sound Routine


[Prev][Next][Index][Thread]

A92: Re: Simple Sound Routine




>Hi there...I'm writing a program for composing music on a '92, and I'd love
>it if someone could help me out with the sound routine.  I just need to
>know how to produce a sound (a simple square wave works) at a specific
>frequency for a specific length.  (Basically an ASM version of the old
>BASIC sound hz, len command.)  I'd hope to put this into a separate program
>to be called by my TI-BASIC editor.  (Eventually I'll migrate the whole
>thing into ASM, but for now it's BASIC-based.)  Any help is appreciated!
>--Cliff Biffle


This should give you a good start, as the nature of this project requires
extensive EXPERIMENTATION!!

You are wanting to emulate SOUND freq,len.  So the program would need to be
passed two parameters.  "Freq" would obviously be in Hz, and "len" would
most likely be in ms (milliseconds).  But please experiment with other
lengths.  You may want to work in something based in binary, like 1/64's of
a second.  At the start of the program, you will convert the "human"
parameters to workable values.  And it is this conversion that depends on
the program itself.

The generation of sound is made by connecting the I/O In and Out data wires
(RED and WHITE) to one wire of a piezo buzzer (or a speaker, but requires
some amplification), and then connecting the I/O GROUND to the other wire
of the buzzer.  The I/O signal will then be made HIGH, then LOW, and back
again.  This repetition causes a sound to be produces.  The only sound we
can produce is a square wave (if you know anything about waveforms, you
would recognize that the HIGH to LOW and LOW to HIGH with no interpolation
_IS_ the square wave).

Here is a skeleton program:

;========================================================================
;========================================================================

    xdef _library
    xdef sound@0000

; SOUND freq, len -- Emulates the BASIC SOUND routine
sound@0000:
    ; Store registers used in the routine
    movem.l ??,-(a7)
    ; Convert parameters to values usable by the loops
    ...

    ...
    ; Loop for the duration
    move    ??,d0  ; D0 - Number of loops to equal duration
Loop_Length:
    ; Switch the VOLTAGE of the I/O port
    ...

    ...
    ; Now loop for one half the period of the note
    move    ??,d1  ; D1 - Number of loops to equal period/2
Loop_Period:
    dbra    d1,Loop_Period
    dbra    d0,Loop_Length
    ; Cleanup, restore registers
    movem.l (a7)+,??
    end

_library    dc.b    "sound",0

;========================================================================
;========================================================================

Now it is up to you to fill in the blanks.  This program will switch the
I/O port from HIGH to LOW (or back) and then wait a little bit.  Since
the waiting occurs after each switch from HIGH to LOW (or back), that is
only one half of the period of the wave.  The conversion of "freq" and
"len" require knowing how fast the TI will execute your program.  There
are lots of guides out there (Motorola's manuals are good, and FREE) that
contain the number of cycles for each instruction.  The TI runs at 10MHz
AFAIK.  After calculating the number of cycles required to switch the
I/O port and then the loop, you can find out how many loops it takes to
make a specific frequency.  You can even get fancy enough to take in
account the time it takes for the conversion.  Even though it is only
done once, you could ensure that the lengths are very accurate.

As I said before, this requires a LOT of EXPERIMENTING!  Have fun!

P.S.  Someone has already done a sound routine.  Perhaps you might want
to take a look at his/her code.  I believe the rountine he/she wrote
doesn't allow you to specify a freq, but a note number.  There was a
look-up table of the frequencies or whatever his/her program needed to
produce that note.

====
Aaron Hill (Redmond, WA)
E-Mail: SeracOhw24@msn.com
IRC-Nick: Serac (EF-Net) (was SeracOhw)