home *** CD-ROM | disk | FTP | other *** search
- Here is a routine that *SHOULD* sum two sample fragments together. You
- feed it the address of the beginning of each sample fragment, as well as
- the address of the destination buffer. The Playback Lengths are the
- Playback Rate of the sample (I.e. how many bytes per second) times the
- vertical blank length (1/60 or 1/50). You should use a lookup table to
- calculate the fragment length from the hardware playback period values
- that most Trackers use. Just load the registers, BSR to the routine, and
- when it returns, the address registers will point to the start of the NEXT
- sample fragment. That is, you can just save the registers, and drop them
- back in when you call next time.
-
- It should be fast enough to do this for four voices within 1/60 second at
- maximum playback rate. I hope. Well, the worst-possible case is for two
- samples at NoiseTracker's highest frequency over a 1/50 second length; the
- sample fragment length is 314 bytes AT WORST for realtime. If you don't
- care about realtime, then samples of length up to 65536 bytes can be summed
- at arbitrary frequencies.
-
- However, this routine does NOT handle independent hardware volume!!! This
- could be implemented by having a "shiftdown" value for each sample. each
- byte of the sample would then be shifted down by this much. That's for
- next time. Theoretically, a similar routine could handle the multiplexing
- of four voices (not just summing the summed output), but that could get
- extremely ugly... ;^)
-
- Well, if there's anything wrong with it please let me know and I'll fix it.
- Remember, this is *UNTESTED*, so if somebody wants to test it, let me know.
-
- -----
-
- ; ADDSAMPLES
- ; Copyright 1992 Kenneth D. Miller III
- ; inputs: d0 Playback Length of first sample (for 1 VBlank cycle)
- ; d1 Playback Length of second sample (for 1 VBlank cycle)
- ; a0 Address of first sample
- ; a1 Address of second sample
- ; a2 Address of destination buffer (chip RAM!)
-
- AddSamp:
- moveq #0, d5 ;note: d5 is the Update register
- moveq #0, d6
- moveq #0, d7
- cmp d0, d1
- bpl.s ASInit
- beq.s ASFast ;if playback rates are the same, use fast
- exg d0, d1 ;make sure Sample 1 is the fast one
- exg a0, a1
- ASInit: move d0, d4 ;load counter
- move.b (a1)+, d7 ;pre-load first byte of sample 2
- ASLoop: move.b (a0)+, d6 ;load byte from sample 1
- add.w d7, d6 ;add 'em, preserving byte from sample2
- asr.w #1, d6 ;divide by 2
- move.b d6, (a2)+ ;jam the summed byte to the output buffer
- add d1, d5 ;increment Update register
- cmp d5, d0
- bmi ASLp2 ;if it's greater than playback length 1
- sub d0, d5 ; then drop the Update register back
- move.b (a1)+, d7 ; and load another byte from Sample 2
- ASLp2: dbra d4, ASLoop
- rts
- ASFast: move.l #$FEFEFEFE,d5 ;load mask into d5
- move.l d0, d4 ;load loop counter
- btst #1, d0
- beq ASFas2
- move.w (a0)+, d6 ;if length mod 4 != 0, pick off first word
- move.w (a1)+, d7
- and.w d5, d6
- and.w d5, d7
- lsr.w #1, d6
- lsr.w #1, d7
- add.w d6, d7
- move.w d7, (a2)+
- subq #2, d4
- ASFas2: move.l (a0)+, d6 ;sum 4 bytes worth of samples
- move.l (a1)+, d7
- and.l d5, d6
- and.l d5, d7
- lsr.l #1, d6
- lsr.l #1, d7
- add.l d6, d7
- move.l d7, (a2)+
- subq #4, d4
- bpl.s ASFas2
- rts
-
- --
- kdmiller@athena.mit.edu | Kenny Miller, sole member of Digital Horizons USA
- /// | UPCOMING COOL STUFF: KMUS music format, BrotBusters
- \\\/// Amiga Makes | Demo, Scrolly Roller Demo, Columns, Psycho Ball,
- \XX/ It Possible! | AmigAtaxx, etc. (don't hold your breath ;^)
-