Jump to content
IGNORED

Tricks for XB Percussion Programming?


Cheung

Recommended Posts

Hey all, was just wondering if anyone had any tricks to programming basic percussion for the TI in Basic/XB?

 

I'm just trying to get a basic snare and kick drum going on a main theme without sounding terrible.

 

I'm currently using -5 for the snare and -7 for the kick (kick on 1 and 3 and snare in 2 and 4) with a steep decay on it (first half of the 40 millisecond length is set to 9 volume second half to 20).

 

It still doesn't sound great so I was wondering if anyone had any tips or knew of any resources that could help.

 

Thanks!

  • Like 2
Link to comment
Share on other sites

Tough problem. 

 

Maybe you know these already:


Use negative duration to make CALL SOUND more continuous. 
 

In BASIC I thought 20 ms was faster than the interpreter could keep up? Try a longer but negative duration. 

Try using -3 tone with attenuation -28, and  -8 (or -4!) noise. This lets you control the rate with the frequency on tone 3. You can reproduce the white noise of -5,-6,or -7 and any  rate in between. 

(But CALL SOUND only fills channel 3 if you supply 1 and 2 first.) 

 

 

 

Chariots of Fire (in Forth) uses -5 for the percussion, with a short attack and decay. But it's assembly language and updates the attenuation every 1/60th second to get that. 
 

I kinda like the Munch Man "chomp" effect with -6 and a sharp roll off. 

 

 

  • Like 4
Link to comment
Share on other sites

RXB has a unique feature of CALL IO for running GPL sound lists like you hear in many games.

For example this program will play crash sound from Edit mode or Program mode.

          IO             subprogram                            PAGE  I3
          -------------------------------------------------------------
 
          Format         CALL IO(type,address[,...])
 
                         CALL IO(type,bits,cru-base,variable,variable
                         [,...])
 
                         CALL IO(type,length,vdp-address[,...])
 
          Description
 
          The IO subprogram allows access to and control of any chip in
          the console or peripheral cards. The type refers to different
          access methods like playing sound from GROM or VDP memory
          automatically. The type can also specify reading or writing
          directly to a Control Register Unit (CRU) address. Thereby
          allowing direct chip control, or direct chip bypass if the
          user wishes. The IO subprogram is a Graphics Programming        
          Language (GPL) command. So the function is exactly like GPL 
          despite being run from the XB environment. As most of XB is                            
          written in GPL the user gains greater GPL like control.
          After all the Operating System is written in GPL for a 
          good reason.*Note these docs are from GPL Manuals.
 
                 type             address specifications
                ~~~~~~            ~~~~~~~~~~~~~~~~~~~~~~
                  0   ----------  GROM sound list address.
                  1   ----------  VDP  sound list address.
                  2   ----------  CRU input.
                  3   ----------  CRU output.
                  4   ----------  VDP address of Cassette write list.
                  5   ----------  VDP address of Cassette read list.
                  6   ----------  VDP address of Cassette verify list.
 
           The length specifies the number of bytes. The length can be
          from -32768 to 32767 depending on the amount of VDP memory
          that is available. Of course a value of -32768 is HEX >8000
          and 32767 is HEX >7FFF and VDP normally in a TI is only 16384
          or HEX >4000 of VDP. So be careful or lock-up will result.
          The cru-base is the CRU address divided by 2  in decimal form
          as the command automatically doubles the value input. The CRU
          -base ranges from 0 to 8191 or HEX >0000 to >1FFF with a EVEN
          address for 8 bits or more being scanned. That means that a
          value of 8191 will lock-up the system as it is looking for a
          bit in 8192 that does not exist.
          IO  (SOUND LIST)                                     PAGE  I4
          -------------------------------------------------------------
          The variable can input or output values ranging from 0 to 255
          as that is equivalent to a single byte value. As there are
          two variables 16 bits can be represented in the two 8 bit
          variables. If CRU input reads less than 8 bits, the unused
          bits in the byte are reset to zero. If CRU input reads less
          then 16 but more than 8 bits, the unused bits in the word
          will be reset to zero. The bits range from 1 to 16 for input
          or output.
 
          AUTO-SOUND INSTRUCTION GROM/GRAM/VDP
 
          Format         CALL IO(type,address[,...])
 
           Control of the Sound Generator Chip (SGC) in the system
          console is through a pre-defined table in GROM/GRAM or VDP
          memory. Sound output is controlled by the table and the VDP
          Interrupt Service Routine (ISR). A control byte at the end of
          the table can cause control to loop back up in the table to
          continue, or end sound output. The format of the table is the
          same regardless of where it resides. The table consists of a
          series of blocks, each of which contains a series of bytes
          which are directly output to the SGC.
           Since the VDP generates 60 interrupts per second, the
          interrupt count is expressed in units of one-sixtieth of a
          second.
           When the IO command is called, upon the next occurring
          VDP interrupt, the first block of bytes is output to the SGC.
          The interpreter (Operating System) waits the requested number
          of interrupts (for example, if interrupt counts are 1, every
          interrupt causes the next block to be output). Remember that
          interpretation of XB continues normally while the SGC control
          is enabled.
           The sound control can be terminated by using an interrupt
          count of 0 in the last block of the table. Alternatively, a
          primitive looping control is provided by using a block whose
          first byte is 0, and the next 2 bytes indicate an address in
          the same memory space of the next sound block to use. (That
          means one block points to another block only in the same type
          of memory).
          IO (SOUND LIST)                                      PAGE  I5
          -------------------------------------------------------------
           If the first byte is hex FF or decimal 255, the next two
          bytes indicate an address in the other memory space. (That
          means one block points to another block but in another type
          of memory.) These allow switching sound lists from GROM/GRAM
          to VDP or VDP to GRAM/GROM. By making this the beginning of
          the entire table, the sound sequence can be made to repeat
          indefinitely.
           The type 0 indicates sound lists in GROM or GRAM and type 1
          indicates sound lists in VDP.
           Executing a sound list while table-driven sound control is
          already in progress (from a previous sound list) causes the
          old sound control to be totally supplanted by the new sound
          instruction. (That means any sound chip command will over-
          ride old sound chip commands).
           The SGC has 3 tone (square wave) generators - 0, 1, and 2
          all of which can be working simultaneously or in combination.
          The frequency (pitch) and attenuation (volume) of each
          generator can be independently controlled. In addition, there
          is a noise generator which can output white or periodic
          noise. For more information on controlling the SGC, see the             
          TSM9919 SGC specification.                                                
 
          ATTENUATION CONTROL (for generators 0, 1, 2 or 3)
 
          One byte must be transmitted to the SGC:
 
          Binary     1-REG#-1-Attenuation
 
                REG# = register number (0,1,2,3)
                Attenuation = Attenuation/2
                      (e.g. A=0000 0  db = highest volume;
                            A=1000 16 db = medium volume;
                            A=1111 30 db = off. )
 
          EXAMPLE: 1 10 1 0000 : turn on gen. #2 highest volume.
                   1 01 1 0100 : turn on gen. #1 medium high volume.
                   1 11 1 1111 | turn off gen. #3 (noise generator).

          IO (SOUND LIST)                                      PAGE  I6
          -------------------------------------------------------------
          
          FREQUENCY CONTROL   (for generators 0, 1, 2)
          -----------------
          Two bytes must be transmitted to the SGC for a given register
          and to compute the number of counts from the frequency F
          use: N = 111860 / F
 
          Binary     1-REG#-N(1s 4 bits)-00-N(ms 6 bits)
                            Note that N must be split up into its least
                            significant 4 bits and most significant 6
                            bits (10 bits total).
 
           The lowest frequency possible is 110 Hz and the highest is
          55938 Hz.
 
          NOISE CONTROL                 |
          -------------                 |
          One byte must be transmitted to the SGC:
 
          Binary     1-1-1-0-0-T-S
 
                T = 0 for white noise, 1 for periodic noise;
                S = Shift rate (0,1,2,3) = frequency center of noise.
                    S=3=frequency dependent on the frequency of tone
                    generator #3.
          IO (SOUND LIST)                                      PAGE  I8
          -------------------------------------------------------------
 
          Programs
 
          Line 100 clears the screen.   | >100 CALL CLEAR ! CRASH
          Line 110 to ...               | >110 DATA 2,228,242,5
                                        | >120 DATA 2,228,240,18
                                        | >130 DATA 2,228,241,16
                                        | >140 DATA 2,228,242,14
                                        | >150 DATA 2,228,243,12
                                        | >160 DATA 2,228,244,10
                                        | >170 DATA 2,229,245,9
                                        | >180 DATA 2,229,246,8
                                        | >190 DATA 2,229,247,7
                                        | >200 DATA 2,229,248,6
                                        | >210 DATA 2,229,249,5
                                        | >220 DATA 2,230,250,4
                                        | >230 DATA 2,230,251,3
                                        | >240 DATA 2,230,252,2
                                        | >250 DATA 2,230,253,1
                                        | >260 DATA 2,230,254,1
          Line 270 ends sound list.     | >270 DATA 1,255,0,0
          Line 280 AD is VDP address to | >280 FOR AD=4096 TO 4160 STE
          start with and ends with.     |  P 4
          Line 290 reads list.          | >290 READ V1,V2,V3,V4
          Line 300 moves them into VDP. | >300 CALL POKEV(AD,V1,V2,V3,V
                                        |  4)
          Line 310 continues AD loop.   | >310 NEXT AD
          Line 320 executes sound list. | >320 CALL IO(1,4096)
          Line 330 prints out suggestion| >330 PRINT "CRASH": :"TYPE:":
          on how to test IO.            |  "CALL IO(1,4096)"
 
           All data values must converted to Binary in order to see
          what is going on. You now have all the data that I have as
          to this phase of IO types 0 and 1. See Editor Assembler
          Manual also for more data on sound lists and sound chip.
          IO (SOUND LIST)                                      PAGE  I9
          -------------------------------------------------------------
          Sound table creator for conversion of sound data.

          100 CALL CLEAR :: PRINT "*SOUND DATA TABLE CREATOR*"
          110 Q$="0123456789ABCDEF"
          120 INPUT "GENERATOR # ?":GN
          130 INPUT "DURATION ?":DUR
          140 INPUT "FREQUENCY ?":FREQ
          150 INPUT "VOLUME ?":VOL :: PRINT : : :
          160 IF DUR>17 THEN 180
          170 DUR=17
          180 REM  DURATION 
          190 DUR=INT((DUR*255)/4250) :: CONV=DUR :: GOSUB 400
          200 DUR$=SEG$(HX$,3,2) :: IF FREQ>-1 THEN 290
          210 REM   NOISE FREQUENCY  
          220 FR=ABS(FREQ)-1 :: FR$="E"&STR$(FR)
          230 REM  NOISE VOLUME 
          240 VOL=INT(VOL/2) :: CONV=VOL
          250 GOSUB 430 :: VOL$="F"&SEG$(HX$,4,1)
          260 PRINT "DATA>02";FR$;",>";VOL$;DUR$: : :
          270 GOTO 360
          280 REM  TONE FREQUENCY 
          290 FR=INT((111860.8/FREQ)+.5)
          300 CONV=FR :: GOSUB 400
          310 FR$=SEG$(Q$,GN*2+7,1)&SEG$(HX$,4,1)&SEG$(HX$,2,2)
          320 REM  TONE VOLUME 
          330 VOL=INT(VOL/2) :: CONV=VOL :: GOSUB 400
          340 VOL$=SEG$(Q$,GN*2+8,1)&SEG$(HX$,4,1)
          350 PRINT "DATA>03";SEG$(FR$,1,1)&SEG$(FR$,2,1);",>";
          SEG$(FR$,3,2);VOL$;",>";DUR$;"00": : :
          360 PRINT: :"ANOTHER SOUND (Y/N)?"
          370 CALL ONKEY("YN",3,K,S) GOTO 100,390
          380 GOTO 370
          390 CALL CLEAR :: END
          400 REM  DECIMAL TO HEX 
          410 AY=INT(CONV)/16 :: BY=INT(AY)/16 
          420 CY=INT(BY)/16 :: DY=INT(CY)/16
          430 AP=(AY-INT(AY))*16 :: BP=(BY-INT(BY))*16
          440 CP=(CY-INT(CY))*16 :: DP=(DY-INT(DY))*16
          450 HX$=SEG$(Q$,DP+1,1)&SEG$(Q$,CP+1,1)&
          SEG$(Q$,BP+1,1)&SEG$(Q$,AP+1,1) :: RETURN
         
          Use this program to create Hex strings that can use
          CALL MOVES to move strings into VDP to be played from
          a CALL IO(1,VDP-address)

 

  • Like 3
Link to comment
Share on other sites

5 hours ago, RXB said:

RXB has a unique feature of CALL IO for running GPL sound lists like you hear in many games.

 

Wow, that's a really great feature in RXB!  

 

I guess you could also input your sound list with CALL CHAR, then calculate the VDP address of the character definition.

 

 

CALL CHAR(96, "02E5F50F02E5F00502E5F30A02E5F61402E5FA1001FF00")

 

that would be a white noise -5 with a short attack and a slower decay.  Or garbage if there's a typo :)

  • Like 3
  • Haha 1
Link to comment
Share on other sites

3 hours ago, FarmerPotato said:

I guess you could also input your sound list with CALL CHAR, then calculate the VDP address of the character definition.

 

CALL CHAR(96, "02E5F50F02E5F00502E5F30A02E5F61402E5FA1001FF00")

 

that would be a white noise -5 with a short attack and a slower decay.  Or garbage if there's a typo :)

This is something I have done, as have others.   CALL CHAR is the easiest (only)* way to move data into VDP RAM from console TI BASIC or Extended BASIC without help from assembly.  The bummer for native TI Extended BASIC is you still cannot do anything without a 32k expansion as CALL LOAD cannot be called without CALL INIT, which requires 32k.

 

* Technically, HCHAR and VCHAR move data into VDP RAM, too.  I guess, PRINT and DISPLAY do, as well, but probably not entirely useful for sound purposes.

  • Like 3
Link to comment
Share on other sites

Didn't Tursi make some sort of sound sampling thing that used the speech synthesizer module?  I mean I wouldn't have a clue where to start with it so I'm literally no help at all here.  

But I'd investigate that, specially if it can be used in XB and more so if it still can be used with compiled XB.  I forget the name of his project.

  • Like 3
  • Thanks 1
Link to comment
Share on other sites

17 hours ago, OLD CS1 said:

This is something I have done, as have others.   CALL CHAR is the easiest (only)* way to move data into VDP RAM from console TI BASIC or Extended BASIC without help from assembly.  The bummer for native TI Extended BASIC is you still cannot do anything without a 32k expansion as CALL LOAD cannot be called without CALL INIT, which requires 32k.

 

* Technically, HCHAR and VCHAR move data into VDP RAM, too.  I guess, PRINT and DISPLAY do, as well, but probably not entirely useful for sound purposes.

RXB CALL IO works from with or without 32K.

It is not a Assembly Language routine it is using Console ROM and GPL GROM built into the TI99/4A.

RXB runs from a Final GROM or older versions also would work 2000 to 2024 versions.

  • Like 3
Link to comment
Share on other sites

20 hours ago, Retrospect said:

Didn't Tursi make some sort of sound sampling thing that used the speech synthesizer module?  I mean I wouldn't have a clue where to start with it so I'm literally no help at all here.  

I don't work with the speech synth.

 

In doing a lot of sound conversion, though, the most convincing drum sounds I've heard use both noise AND tone at the same time, both fading rapidly at the same rate. I don't know if Basic/XB is fast enough to make a good one, but that's the only advice I have.

 

  • Like 7
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...