Jump to content
IGNORED

Call Sound in Turbo Forth?


matthew180

Recommended Posts

Is there an instruction in TF that is the same as CALL SOUND in XB?

 

I need the TF equivalent of:

 

CALL SOUND(1, 20000, 30)

 

This clears the sound table or makes tone 20000 CPS or something like that, the ADC board's description is rather vague on this point, but it works. There is a quirk in the ADC board's addressing scheme which needs this statement to keep the machine from making tones when addressing the ADC card.

 

Thanks!

 

John (via Matthew)

Link to comment
Share on other sites

Is there an instruction in TF that is the same as CALL SOUND in XB?

 

I need the TF equivalent of:

 

CALL SOUND(1, 20000, 30)

 

This clears the sound table or makes tone 20000 CPS or something like that, the ADC board's description is rather vague on this point, but it works. There is a quirk in the ADC board's addressing scheme which needs this statement to keep the machine from making tones when addressing the ADC card.

 

Thanks!

 

John (via Matthew)

 

 

You will find a file describing how to use sound in the yahoo group for TurboForth at this location

 

http://tech.groups.yahoo.com/group/turboforth/files/Data%20Sheets/

Link to comment
Share on other sites

Thanks! Also, Willsy sent me this via email. Seems to do the trick:

 

From that, it looks like you need to make a very high frequency sound (so that we can't hear it) and also minimum volume.

 

The following add-on words give sound capabilities to TurboForth:

: VOLUME ( ch# vol  -- )
 $F AND SWAP 2* 1+ 8 + 4 << OR $8400 C! ;

: TONE ( ch# tone -- )
 SWAP 2* 8 + 4 << SWAP DUP $F AND ROT OR SWAP 4 >> SWAP
 $8400 C! $8400 C! ;

: NOISE ( n -- ) 7 AND $E0 OR $8400 C! ;

Enter those words into TF (you probably do not need NOISE)

 

Then enter:

 

0 2 TONE

1 2 TONE

2 2 TONE

 

That gives all three sound channels a very high frequency.

 

Now, set the volume to minimum:

 

0 15 VOLUME

1 15 VOLUME

2 15 VOLUME

 

And that should keep your machine nice and quiet!

  • Like 1
Link to comment
Share on other sites

  • 5 years later...

For my CAMEL99 Forth kernel I wanted a way to implement those magic TI sounds.

But it had to be small. So here is BEEP and HONK sending raw machine codes to the TMS9919 chip.

I put HONK into my ABORT word and it gets very nostalgic when Forth reports an error... ;-)

 

I just tested these in Turbo Forth and they work perfectly.

: SND! ( c -- ) 8400 C!  ;        \ write a byte to address of TMS9919 chip
: DLY  ( n -- ) 0 DO LOOP ;

: BEEP ( -- )   80 SND! 5 SND!    \ pre-calculated values for OSC1 1328Hz
                91 SND!           \ turn on sound at -2 dB
                0F00 DLY          \ Delay ~ 170 mS
                9F SND! ;         \ turn off OSC1

: HONK ( -- )   81 SND! 20 SND!   \ pre-calculated values for OSC1 218Hz
                90 SND!           \ turn on sound at 0 dB
                0F00 DLY          \ Delay ~ 170 mS
                9F SND! ;         \ turn off OSC1
  • Like 2
Link to comment
Share on other sites

 

Well since we are publishing code...

 

I kind of went crazy when I did a sound interface. It's too big, but it works well.

This code is written for my XASM99 cross-compiler but it mostly reads like Forth,

The biggest difference is the search order control words. (Cross-Assembling, Target-Compiling, Cross-Compiling with shortforms: [TC] [CC] )

Also defining words like CONSTANT have a ':' in the name. I will be changing that.

It was my way of staying sane while writing the cross-compiler. :-)

 

When naming Forth words for controlling things, I like to use "units" names if I can, because the syntax looks like English.

So that gave rise to and Hz and dB. Note: I did not pay much attention to getting the noise generator correct. That needs work.

 

Not sure if this is of any value to the readers here but this might provide some further ideas for sound control, or maybe how NOT to do it.

BF

\ TMS9919 SOUND CHIP DRIVER and CONTROL LEXICON      Jan 2017 BJF

\ need a good timer for sound control
MIRROR [undefined] TMR!  [if] [CC] include cc9900\ticktock.hsf   [then]

\ ==========================================================================
\ C H I P   C O N T R O L   C O N S T A N T S

[CC] HEX

TARGET-COMPILING
\ TMS9919 is a memory mapped device on the TI-99 @ >8400
\  8400 constant: sndport  \ only used once so no need to take up name space

\ frequency code must be ORed with these numbers to create a sound
\ The number is then split into 2 bytes and each one is sent to the chip
  8000 constant: osc1
  A000 constant: osc2
  C000 constant: osc3
  E000 constant: noise

\ Attenuation values are ORed with these values to change volume (0= max, 15 = off)
    90 constant: ATT1
    B0 constant: ATT2
    D0 constant: ATT3
    F0 constant: ATT4  ( noise volume adjust)

[cc] decimal [tc]

\ I don't have 2constants in the CAMEL compiler so we are doing it manually

: f(clk) ( -- d)  4496 17 ;    \ this returns 111,860.8 Hz the ACTUAL f(clk)

[cc] hex
\ ===================================================================
\ A S M   H E L P E R S   F O R   S P E E D

CROSS-ASSEMBLING
\ >FCODE re-arranges Freq. nibbles (4bits) for the TMS9919
\ A HEX frequency value of >0145 must be converted to  >0514
CODE: >FCODE ( 0xyz -- 0zxy)    \ an fcode is the 12 bits needed to create freq.
        TOS   R1 MOV,           \ make copy
        R1    04 SRL,           \ shift 0xyz  to 00xy
        TOS  SWPB,              \ 0xyz  yz0x
        TOS  0F00 ANDI,         \ 0z00
        R1   TOS ADD,           \ 0zxy)
        NEXT,
        END-CODE

CODE: SPLIT ( AABB --  BB AA )
        TOS R1 MOV,             \ make a copy
        TOS 8 SRL,              \ slide 'AA' to the right
        R1 00FF ANDI,           \ mask out AA from the copy
        R1 PUSH,
        NEXT,
        END-CODE

TARGET-COMPILING
\ for simplicity we will use an "ACTIVE DEVICE" concept using variables
variable: THE-OSC              \ holds the active OSC value
variable: THE-ATT              \ holds the active attenuator value

\ ==================================================================
\ S O U N D   P R I M I T I V E S

TARGET-COMPILING

: hz>fcode ( freq -- fcode )
       f(clk) rot UM/MOD NIP 0A /   \ convert freq. to bytes and divide by 10)
       >fcode ;                     \ fix the nibbles so the work on 9919)

[UNDEFINED] SND! [IF] : SND! ( c -- )  8400 c!  ;   [THEN]

\ : SND!  ( c -- )  cr t." >"  HEX U. ;  \ **for testing**  dumps sound data to screen

\ ==================================================================
\ Set the sound "GENerator that is active.
\ Once selected they are used by Hz and db to set the freq and attenuation level.
\ The osc and attentuator are selected at the same time

: GEN! ( osc att -- )  THE-ATT !  THE-OSC ! ;

\ ==================================================================
\ S C I E N T I F I C   S O U N D   C O N T R O L   L E X I C O N

: GEN1 ( -- )  osc1  att1  gen! ;
: GEN2 ( -- )  osc2  att2  gen! ;
: GEN3 ( -- )  osc3  att3  gen! ;
: GEN4 ( -- )  noise att4  gen! ;

: Hz   ( n -- )                \ set the freq. in Herz (lowest = 110Hz
        hz>fcode               \ convert n to Fcode#
        the-OSC @ OR           \ OR in the oscillator to use
        split snd!  snd! ;     \ split and write bytes to chip

\ dB has a range of  0 to -30 in 2 db increments
: dB   ( level -- )            \  usage: -6 db
        abs  2/  0F min        \ clip max value to F
        the-att @ OR snd! ;    \ OR new value with the current attenuator and write to chip

: MUTE ( -- )  -30 db ;        \ mutes active generator
: SILENT ( --)  9F snd!  BF snd!  DF snd!  FF snd! ;  \ turn off all sounds

[cc] decimal [tc]
\ Code the classic TI-99 sounds defined in our new language
: BEEP  ( -- ) GEN1  1398 Hz  -4 dB  170 MS  MUTE ;
: HONK  ( -- ) GEN1   218 Hz   0 dB  170 MS  MUTE  ;
[cc] hex [tc]
  • Like 1
Link to comment
Share on other sites

Well since we are publishing code...

 

I kind of went crazy when I did a sound interface. It's too big, but it works well. ...

 

Very nice.

 

fbForth 2.0’s code is a bit bloated, I suppose (see my fbForth205_Speech&Sound.a99 of my source code). A large part of that is the inclusion of playing sound lists, which you will likely be doing ere long. As the result of a challenge from Mark, I implemented the ability to interrupt the current sound list with a second, presumably shorter, sound list, which mutes the first sound list and picks up the first where it would be had it not been interrupted. The fbForth 2.0 ISR (see my fbForth101_LowLevelSupport.a99) manages this as well as speech.

 

I don't know whether this would be useful to your implementation of a timer for sound duration, but the counter for each sound list is decremented at each interrupt.

 

I will stop talking now ...

 

...lee

Link to comment
Share on other sites

 

Very nice.

 

fbForth 2.0’s code is a bit bloated, I suppose (see my fbForth205_Speech&Sound.a99 of my source code). A large part of that is the inclusion of playing sound lists, which you will likely will be doing ere long. As the result of a challenge from Mark, I implemented the ability to interrupt the current sound list with a second, presumably shorter, sound list, which mutes the first sound list and picks up the first where it would be had it not been interrupted. The fbForth 2.0 ISR (see my fbForth101_LowLevelSupport.a99) manages this as well as speech.

 

I don't know whether this would be useful to your implementation of a timer for sound duration, but the counter for each sound list is decremented at each interrupt.

 

I will stop talking now ...

 

...lee

 

I am not sure I want to use sound lists like the TI system does. I have built a simple music playing system using the PC loudspeaker in Forth that used a defining word called NOTE:

It lets you define notes like this : 440 NOTE: A. They I created note definitions that set the time duration as whole notes, half notes etc...

So my sound list then becomes a Forth list of words. It's code based solution rather than a data based solution.

 

It's actually up on Rosetta. http://rosettacode.org/wiki/Musical_scale#Forth

 

I figure with the multi-tasker and a lexicon like this I should be able to play 3 part music, but I may need to add a "conductor" type function to keep everybody synced.

That's the plan anyway.

 

Please don't stop talking. There are very few people in the world with whom one can share Forth ideas for the TI-99.

 

BF

Link to comment
Share on other sites

...

Please don't stop talking. There are very few people in the world with whom one can share Forth ideas for the TI-99.

 

Yes! Don't stop talking! The more Forth the better!

 

I see how you may have thought I meant no more contributions. That will never happen! I was just trying to be cute |:) about ceasing my rambling in that particular post. I very much appreciate encouragement from the two of you, believe me. There are a handful of others around here who talk about Forth occasionally. I always hope to engage them a little more often than currently, but Forth is not central to their programming universe as it variously is to ours.

 

...lee

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...