Jump to content
Heaven/TQA

Playing Samples

Recommended Posts

ok...here are my first tests with the Space Harrier XE set...

 

Sample1 is done with this:

; sample test #1
; sample taken from Space Harrier XE project
org $3000

init: 
lda #0
sta $c6
lda #$40
sta $c7

play_sample: 
ldy #0
play2 
lda ($c6),y
lsr
lsr
lsr
lsr
ora #$10
tax
jsr play_smpl
play1 	lda ($c6),y
and #$0f
ora #$10
tax
jsr play_smpl
inc $c6
bne play4
inc $c7
play4 lda $c7
cmp #$4f
bcs no_sound
jmp play_sample
no_sound: lda 53770
sta $d01a
lda 53279
cmp #6
bne no_sound
jmp init

play_smpl: 
wait: sta $d40a
sta $d40a
sta $d40a
sta $d40a
 stx $d205
 stx $d01a
 rts
 
org $4000
ins "samples.dat"

 

so that's the mentioned done via a loop.

 

the second attempt uses DLIs instead but they sound different... so I am not 100% sure what I am doing wrong here...

 

Sheddy mentioned 4kHz sample rate so I made following (maybe not correct) consumption:

 

on PAL we have 50 Hz therefore to achieve the 4000 Hz we would need 80 DLIs... so I have done this with

 

; sample test #2
; now with DLIs

; sample data taken from Space Harrier XE
org $3000

init: jsr wait_vbl
lda #0
sta $d40e
lda #<dlist
sta 560
lda #>dlist
sta 561
lda #<dli
sta 512
lda #>dli
sta 513
lda #$c0
sta $d40e
init2 lda #0
sta $c6
lda #$40
sta $c7

main: lda 53279
cmp #6
bne main
jmp init2

dli	pha
tya
pha
ldy #0
sta $d40a
lda ($c6),y
sta $d01a
lsr
lsr
lsr 
lsr
ora #$10
sta $d205
; inc $c6
; bne dli0
; inc $c7
dli0 lda #<dli1
sta 512
lda #>dli1
sta 513
pla
tay
pla
rti

dli1 pha
tya
pha
sta $d40a
lda ($c6),y
sta $d01a
and #$0f
ora #$10
sta $d205
inc $c6
bne dli10
inc $c7
dli10 lda $c7
cmp #$4f
bcc dli11
lda #$4f
sta $c7
dli11 lda #<dli
sta 512
lda #>dli
sta 513
pla
tay
pla
rti


wait_vbl: lda $20
wait_vbl0	cmp $20
bne wait_vbl0
rts

dlist:	
:80	dta $80,0,0	
dta $41,a(dlist)
	
org $4000
ins "samples.dat"

 

but this could be wrong as I miss the VBL time?

 

now I will make a try with the mentioned pokey timers... haven't coded ever one...

 

Thanks to Rybags and his Basic examples here is my Pokey Timer version:

 

; sample test #3
; sample taken from Space Harrier XE project
org $3000

init: 
lda #0
sta $c6
sta $c8 ;sample flag
lda #$40
sta $c7
lda #$ff
sta 53760
sta 53762
lda #80
sta 53768
lda #0
sta 53760
lda #1
sta 53762

lda #$f0
sta $d200 ;audf1
lda $10 ;pokemsk
ora #2
sta $10
sta $d20e
ldx $216 ;vimirq
ldy $217
stx temp
sty temp+1
ldx #<irq
ldy #>irq
stx $216
sty $217
sta $d209
main	lda 53770
sta $d018
jmp main

temp dta 0,0
irqnull: pla 
	cld
	jmp (temp)
	
irq: pha
lda $d20e ;irqst
and #2
bne irqnull
tya
pha
jsr play_sample
lda $c7
cmp #$50
bne irq0
lda #$40
sta $c7
irq0 lda $10 ;pokeymask
and #$fd
sta $d20e ;irqen
ora #2
sta $d20e
pla
tay
pla
rti

play_sample:  
ldy #0
play2 lda $c8 ;flag
beq play1
eor #1
sta $c8
lda ($c6),y
lsr
lsr
lsr
lsr
ora #$10
sta $d201
sta $d01a
bne play4
play1 eor #1
sta $c8
lda ($c6),y
and #$0f
ora #$10
sta $d201
inc $c6
bne play4
inc $c7
play4 rts

org $4000
ins "samples.dat"

 

still I need to know how this example would look like with DLIs...

sample2.zip

Edited by Heaven/TQA

Share this post


Link to post
Share on other sites

btw. does anybody know a good sample converter (freeware, opensource) which can convert standard 16 bit wav samples to 4bit samples?

Share this post


Link to post
Share on other sites
btw. does anybody know a good sample converter (freeware, opensource) which can convert standard 16 bit wav samples to 4bit samples?

It would be easy to write one. Just skip past the 52 bytes of header info on the .WAV file then read a (signed) 16-bit sample, add 32K to make it unsigned, then drop the 12 bottom bits.

Share this post


Link to post
Share on other sites

Thanks DamageX...I thought exactly the same and started to write a converter... unfortunatly I am not familiar with C++ so I have to stick to Turbo Basic XL but thanks to the warp mode...

Share this post


Link to post
Share on other sites

I've found the following free PC tools helpful to convert to low speed 4-bit samples. I don't know of anything that can do it all in one go though.

 

SoX (Sound eXchange)

This can do most anything with PC sound files! AFAIK PC's never used 4-bit sound samples so it doesn't do that. But it can do everything up to that last step of making into 4-bit. EG from the attached example, I created an 4KHz 8-bit PCM WAV without a header like this:

 

c:\>sox raygun-01.wav -r 4000 -1 raygun48.raw

 

now it just needs converting to 4-bit. It is not too hard to write a program to do that, but it would seem that GameBoy developers have exactly the same problem, and "MegaMan_X" has created a program to do it, which you can get from here:

 

MegaMan_X's GameBoy Wave Converter

 

It's not very sophisticated, but it does the job. NB only 8 character filenames can be used. The input file must be 8-bit mono raw (no header). EG in the attached example I created the 4-bit version of the sound like this:

 

c:\>snd2gbw raygun48.raw raygun44.raw

 

here's some example code that will use an IRQ to play a sample without the OS, showing some DLI's on a blank Antic D screen (ATasm assembler). sample44.exe in the attached zip is the assembled Atari program.

 

[Edit: changed trigger button code to fix buzzing]

 

	ATARI=0
.include "equates.asm"

; variables

*=$f0

sample 		.ds 2
sample_nybble	.ds 1
sample_value	.ds 1
sample_size	.ds 1
dli_colour	.ds 1


*=$02e0

.byte <run,>run			; initial run address

; main code

*=$2000

run
lda #0
sta NMIEN			; turn off NMI's
sei
sta IRQEN			; disable IRQ's
lda #128+32+16+2		; bit 7 on - ram at $5000, bits 4&5 on - 130XE compatible
sta PORTB			; bit 1 on - disable os & rom, bit 0 off - disable basic  
lda #<nmi			; setup custom NMI handler
sta $fffa
lda #>nmi
sta $fffa+1
lda #<irq			; setup custom IRQ handler
sta $fffe
lda #>irq
sta $fffe+1
lda #<dlist			; set up a display list
sta DLISTL
lda #>dlist
sta DLISTH
lda #2+32			; enable normal width screen+screen dma
sta DMACTL
lda #128+64
sta NMIEN			; turn on NMI's - DLI's and VBI
cli				; enable IRQ's	

; initialize sample play irq

play	jsr init			; initialize the sample to play
wait1	lda TRIG0			; any other stuff can go here, but...
beq wait1			; just wait until fire button is pressed
wait2	lda TRIG0
bne wait2
beq play

; end of main code

init
lda #<sample_start
sta sample
lda #>sample_start
sta sample+1
lda #[>sample_end->sample_start]
sta sample_size			; sample size in 256 byte pages
lda #15				; 64KHz pokey clock divided by 16 = 4Khz timer
sta AUDF1			; in timer 1
lda #1
sta IRQEN			; enable timer 1
lda #0
sta sample_nybble		; initialize nybble
ldx #$18
stx sample_value		; an initial sample value (with volume only bit)
lda #115
is	cmp VCOUNT
bne is				; sync to a scanline for a precise start
stx STIMER			; start timers (must be non-zero value)
rts

; IRQ

irq
pha				; save a
lda sample_value
sta AUDC1			; play sample ASAP to minimise DMA lag
tya
pha				; save y
ldy #0
lda #1
sty IRQEN			; reset interrupt
sta IRQEN			; re-enable only timer 1
eor sample_nybble		; switch between 0 and 1 (right and left nybble)
sta sample_nybble
beq irq1
lda (sample),y
lsr a
lsr a
lsr a
lsr a				; left nybble of sample
bpl irq2			; always branch
irq1	lda (sample),y
and #$0f			; right nybble of sample
inc sample			; next lo byte of sample
bne irq2
inc sample+1			; next hi byte of sample
dec sample_size			; check if at end of sample
bne irq2			; branch if not
tya
sta IRQEN			; end of sample - reset interrupt
beq irq3			; always branch
irq2	ora #$10			; turn on volume only bit
irq3	sta sample_value		; save sample to play next irq
pla
tay
pla				; restore y and a
rti

; NMI

nmi
pha
bit NMIST			; check for cause of interrupt
bvs vbi 			; branch if a VBI

; DLI

dli
lda dli_colour
clc
adc #2
sta dli_colour			; just rainbow colours down screen
sta WSYNC
sta COLBK
pla
rti

; VBI

; critical vbi

vbi
sta NMIRES			; reset interrupt
txa
pha				; save x
lda #0
sta dli_colour			; reset dli colour
tsx
lda $104,x
and #$04
bne vbiexit			; exit VBI if VBI interrupted an IRQ
cli				; allow IRQ to interrupt from now on

; deferred VBI here

vbiexit	pla
tax
pla				; restore x and a
rti

; display list

*=$2400

dlist
.byte $70,$70,$70
.byte $8D+$40,<screen_start,>screen_start
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D
.byte $41,<dlist,>dlist

; sample data

*=$2800

; NB start on a 256 byte page boundary
; sample will stop playing at nearest page boundary if not a multiple of 256 bytes

sample_start
.incbin "raygun44.raw"		; 4KHz, 4-bit raw sample data
sample_end

; screen data

*=$8000

screen_start

samples.zip

Edited by Sheddy

Share this post


Link to post
Share on other sites

Nifty.

 

It's amazing though, that aside from your SH, I don't think I've ever seen a game that bothered to attempt to play samples in such fashion, allowing screen updates to proceed normally.

 

From memory, Kennedy Approach ground to a halt, didn't it, when speech was taking place?

 

And, you don't necessarily have to make it XL specific - it should work almost as well by just using the Immediate IRQ vector, and simply disabling all other IRQ types except the Timer you're using.

Share this post


Link to post
Share on other sites
Nifty.

 

It's amazing though, that aside from your SH, I don't think I've ever seen a game that bothered to attempt to play samples in such fashion, allowing screen updates to proceed normally.

 

From memory, Kennedy Approach ground to a halt, didn't it, when speech was taking place?

 

And, you don't necessarily have to make it XL specific - it should work almost as well by just using the Immediate IRQ vector, and simply disabling all other IRQ types except the Timer you're using.

 

the only one I can think of is Dynakillers, but I don't know if it is using IRQ's. Brilliantly fun game BTW! Of course you do see it in some demos, although they usually don't have DLI's as well.

Share this post


Link to post
Share on other sites

that's cool! great!

 

so...so many "standard" coders here can now use samples in a simple way... :) another miracle saved!

 

great!

Share this post


Link to post
Share on other sites

Afaik,

the Sounds Utility (a *.WAV player for the A8) by Tom Hunt included two programs to convert 8bit WAV-samples into 4bit samples (compatible to the Parrot *.DIG format)... I have also a TB XL file that converts 8Bit into 4 bit and last not least there is a polish "Sample Converter" program that converts 8Bit into 4 Bit...

 

Afaik, Windows 3.x contains a program that lets you record, play and convert samples with 16 Bit and 8Bit, maybe other WIN versions have a similar tool. Nero also has a tool to play and convert WAV, then there is the freeware tool Wavosaur and many many others... Not sure what WAV converters there are for Linux or for the Mac, but I guess quite many...

 

So, first convert a 16Bit sample on the PC to 8Bit, then convert the 8Bit sample on the Atari into 4Bit - thats how I did it... -Andreas Koch.

 

P.S.: - SMPCONV.ATR is the mentioned polish sample converter program;

- SNDPLAY2.ATR contains the three WAV 8Bit to 4bit converters (1x *.TUR, 2x *.COM)

- WAVPLAY.ATR is the sound utility by Tom Hunt (works best in Sparta DOS format; works also in DOS 2 format,

but some options, like DIR and Quit are buggy then...)

Share this post


Link to post
Share on other sites
that's cool! great!

 

so...so many "standard" coders here can now use samples in a simple way... :) another miracle saved!

 

great!

 

I have an application: SPS for Windows at http://www.krishnasoft.com/sps.htm that I can email to you that will convert the 16-bit WAV into 8-bit raw files and also lets you play them on the Atari and Amiga through the joystick port (using a custom cable). It lets you play 5-bit samples on the Atari.

Share this post


Link to post
Share on other sites
since you guys are still talking about converting WAVs on the A8... how about a nice dos/windows program to do it in a few seconds instead?

 

http://www.hyakushiki.net/convert4.exe

 

nice! much easier than the GameBoy converter - no need to strip the headers and a lot more progs support 16-bit samples than 8-bit.

 

And, you don't necessarily have to make it XL specific - it should work almost as well by just using the Immediate IRQ vector, and simply disabling all other IRQ types except the Timer you're using.

 

you're right! I should have tried that first as it makes for a more straightforward example. here's the same code but using the OS. (Atari program is sampleOS.exe in the zip file). (remembered to put the Equates file in the zip as well this time)

 

ATARI=0
.include "equates.asm"

; variables

*=$f0

sample 		.ds 2
sample_nybble	.ds 1
sample_value	.ds 1
sample_size	.ds 1
dli_colour	.ds 1


*=$02e0

.byte <run,>run			; initial run address

; main code

*=$2000

run
lda #0
sta NMIEN			; turn off NMI's
sei
sta IRQEN			; disable IRQ's
lda #<irq			; use immediate IRQ vector (no other OS IRQ's will happen)
sta VIMIRQ			; 534
lda #>irq
sta VIMIRQ+1			; 535
lda #<dlist			; set up a display list
sta SDLSTL			; 560
lda #>dlist
sta SDLSTH			; 561
lda #<vbi			; set up an immediate VBI
sta VVBLKI			; 546
lda #>vbi
sta VVBLKI+1			; 547
lda #<dli			; set up a DLI
sta VDSLST			; 512
lda #>dli
sta VDSLST+1			; 513
lda #128+64			; turn on NMI's - DLI's and VBI
sta NMIEN			; 54286
cli				; enable IRQ's	

; initialize sample play irq

play	jsr init			; initialize the sample to play
wait1	lda TRIG0			; any other stuff can go here, but...
beq wait1			; just wait until fire button is pressed
wait2	lda TRIG0			; 
bne wait2
beq play

; end of main code

init
lda #<sample_start
sta sample
lda #>sample_start
sta sample+1
lda #[>sample_end->sample_start]
sta sample_size			; sample size in 256 byte pages
lda #15				; 64KHz pokey clock divided by 16 = 4Khz timer
sta AUDF1			; in timer 1
lda #1
sta IRQEN			; enable timer 1
lda #0
sta sample_nybble		; initialize nybble
ldx #$18
stx sample_value		; an initial sample value (with volume only bit)
lda #115
init1	cmp VCOUNT
bne init1			; sync to a scanline for a precise start
stx STIMER			; start timers (must be non-zero value)
rts

; IRQ

irq
pha				; save a
lda sample_value
sta AUDC1			; play sample ASAP to minimise DMA lag
tya
pha				; save y
ldy #0
lda #1
sty IRQEN			; reset interrupt
sta IRQEN			; re-enable only timer 1
eor sample_nybble		; switch between 0 and 1 (right and left nybble)
sta sample_nybble
beq irq1
lda (sample),y
lsr a
lsr a
lsr a
lsr a				; left nybble of sample
bpl irq2			; always branch
irq1	lda (sample),y
and #$0f			; right nybble of sample
inc sample			; next lo byte of sample
bne irq2
inc sample+1			; next hi byte of sample
dec sample_size			; check if at end of sample
bne irq2			; branch if not
tya
sta IRQEN			; end of sample - reset interrupt
beq irq3			; always branch
irq2	ora #$10			; turn on volume only bit
irq3	sta sample_value		; save sample to play next irq
pla
tay
pla				; restore y and a
rti

; DLI

dli
pha
lda dli_colour
clc
adc #2
sta dli_colour			; just rainbow colours down screen
sta WSYNC
sta COLBK
pla
rti

; VBI

vbi

lda #0
sta dli_colour			; reset dli colour
jmp SYSVBV			; 58463 - do system vertical blank processes

; display list

*=$2400

dlist
.byte $70,$70,$70
.byte $8D+$40,<screen_start,>screen_start
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D
.byte $41,<dlist,>dlist

; sample data

*=$2800

; NB start on a 256 byte page boundary
; sample will stop playing at nearest page boundary if not a multiple of 256 bytes

sample_start
.incbin "raygun44.raw"		; 4KHz, 4-bit raw sample data
sample_end

; screen data

*=$8000

screen_start

 

NB if the DLI's cause sound quality problems you can "waste" another pokey voice to make a 16-bit timer running at 1.79MHz timer to more precisely "miss" the DLI's.

 

[Edit] Unfortunately IRQ's don't seem to be much good if you want to use a lot of DLI's and 192 vertical resolution. :( Try changing the code to use Antic E instead of Antic D and the DLI's just mess up the timing of the sample playing and it sounds awful. [Another Edit!] Of course it will, because there are no "gaps" for the IRQ to fit into if there are DLI's every scanline. As long as the DLI's are spaced out and not too bunched together, it should be fine.

samplesOS.zip

Edited by Sheddy

Share this post


Link to post
Share on other sites

did you ever tried to use DLIs instead of IRQs?

 

btw. here is the converted MADS source of the sample4 demo:

 

;sample #4 test 
;code by Sheddy



sample equ $f0 ;ds 2
sample_nybble equ $f2 ;.ds 1
sample_value equ $f3 ;.ds 1
sample_size equ $f4 ;.ds 1
dli_colour equ $d5 ;.ds 1

nmien	equ $d40e
irqen	equ $d20e
portb	equ $d301
dlistl	equ $d402
dlisth	equ $d403
dmactl	equ $d400
audf1	equ $d200
audc1	equ $d201
wsync	equ $d40a
trig0	equ $d010
vcount	equ $d40b
stimer	equ $d209
colbk	equ $d01a
nmist	equ $d40f 
nmires	equ $d40f
; main code

ORG $2000

start:	lda #0
sta NMIEN ; turn off NMI's
sei
sta IRQEN ; disable IRQ's
lda #128+32+16+2 ; bit 7 on - ram at $5000, bits 4&5 on - 130XE compatible
sta PORTB ; bit 1 on - disable os & rom, bit 0 off - disable basic 
lda #<nmi ; setup custom NMI handler
sta $fffa
lda #>nmi
sta $fffa+1
lda #<irq ; setup custom IRQ handler
sta $fffe
lda #>irq
sta $fffe+1
lda #<dlist ; set up a display list
sta DLISTL
lda #>dlist
sta DLISTH
lda #2+32 ; enable normal width screen+screen dma
sta DMACTL
lda #128+64
sta NMIEN ; turn on NMI's - DLI's and VBI
cli ; enable IRQ's 

; initialize sample play irq

play: jsr init ; initialize the sample to play
wait1 lda TRIG0 ; any other stuff can go here, but...
beq wait1 ; just wait until fire button is pressed
wait2 lda TRIG0
bne wait2
beq play

; end of main code

init:
lda #<sample_start
sta sample
lda #>sample_start
sta sample+1
lda #[>sample_end->sample_start]
sta sample_size ; sample size in 256 byte pages
lda #15 ; 64KHz pokey clock divided by 16 = 4Khz timer
sta AUDF1 ; in timer 1
lda #1
sta IRQEN ; enable timer 1
lda #0
sta sample_nybble ; initialize nybble
ldx #$18
stx sample_value ; an initial sample value (with volume only bit)
lda #115
is 	cmp VCOUNT
bne is ; sync to a scanline for a precise start
stx STIMER ; start timers (must be non-zero value)
rts

; IRQ

irq:
pha ; save a
lda sample_value
sta AUDC1 ; play sample ASAP to minimise DMA lag
tya
pha ; save y
ldy #0
lda #1
sty IRQEN ; reset interrupt
sta IRQEN ; re-enable only timer 1
eor sample_nybble ; switch between 0 and 1 (right and left nybble)
sta sample_nybble
beq irq1
lda (sample),y
lsr
lsr
lsr
lsr ; left nybble of sample
bpl irq2 ; always branch
irq1: lda (sample),y
and #$0f ; right nybble of sample
inc sample ; next lo byte of sample
bne irq2
inc sample+1 ; next hi byte of sample
dec sample_size ; check if at end of sample
bne irq2 ; branch if not
tya
sta IRQEN ; end of sample - reset interrupt
beq irq3 ; always branch
irq2: ora #$10 ; turn on volume only bit
irq3: sta sample_value ; save sample to play next irq
pla
tay
pla ; restore y and a
rti

; NMI
nmi:
pha
bit NMIST ; check for cause of interrupt
bvs vbi ; branch if a VBI

; DLI
dli:
lda dli_colour
clc
adc #2
sta dli_colour ; just rainbow colours down screen
sta WSYNC
sta COLBK
pla
rti

; VBI

; critical vbi

vbi:
sta NMIRES ; reset interrupt
txa
pha ; save x
lda #0
sta dli_colour ; reset dli colour
tsx
lda $104,x
and #$04
bne vbiexit ; exit VBI if VBI interrupted an IRQ
cli ; allow IRQ to interrupt from now on

; deferred VBI here

vbiexit: pla
tax
pla ; restore x and a
rti

; display list

org $2400

dlist:
.byte $70,$70,$70
.byte $8D+$40,<screen_start,>screen_start
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D,$8D
.byte $8D,$8D,$8D,$8D,$8D
.byte $41,<dlist,>dlist

; sample data

org $2800

; NB start on a 256 byte page boundary
; sample will stop playing at nearest page boundary if not a multiple of 256 bytes

sample_start
ins "raygun44.raw" ; 4KHz, 4-bit raw sample data
sample_end

; screen data

org $8000

screen_start

Edited by Heaven/TQA

Share this post


Link to post
Share on other sites
did you ever tried to use DLIs instead of IRQs?

I haven't tried much, but I always thought they could be made to work. There are big problems to work through though.

Unless you do something in a VBI to continue to play samples during vertical blank, you get a nasty sounding 50Hz/60Hz gap of no sample being played during vertical blank. Your display list would probably need to be longer than the recommended length too, because for just a 4KHz sample you need to output a sample every other VCOUNT (every 4 scanlines at 192 resolution). If you miss some samples, or play them at the wrong time, it soon becomes obvious to the ear. Maybe slower samples would work with DLI's though? NRV said he'd got some sample playing going with DLI's in the past.

Edited by Sheddy

Share this post


Link to post
Share on other sites

Thanks Sheddy, I assumed the same when playing with the DLIs as well... see above my first post...

Share this post


Link to post
Share on other sites

DamageX... how can i modify the sox commands so it works with your converter4.exe as it seems needs another input format?

Share this post


Link to post
Share on other sites
DamageX... how can i modify the sox commands so it works with your converter4.exe as it seems needs another input format?

 

sox raygun-01.wav -r 4000 -2 -c 1 raygun48.wav

 

-2 makes Sox output 2 byte sample - 16 bit

-c 1 will make sure it is converted to mono if it isn't already

Edited by Sheddy

Share this post


Link to post
Share on other sites

Thanks! i had just some evil screams for an "unknew game" i am developing. now it will be interesting how many RAM i can dedicate to samples... ;)

Share this post


Link to post
Share on other sites

And now you have to put it together with RMT and make it playable as an instrument. :ponder:

Using Samples till the computer's memory flows over :D

Share this post


Link to post
Share on other sites
I haven't tried much, but I always thought they could be made to work. There are big problems to work through though.

Unless you do something in a VBI to continue to play samples during vertical blank, you get a nasty sounding 50Hz/60Hz gap of no sample being played during vertical blank. Your display list would probably need to be longer than the recommended length too, because for just a 4KHz sample you need to output a sample every other VCOUNT (every 4 scanlines at 192 resolution). If you miss some samples, or play them at the wrong time, it soon becomes obvious to the ear. Maybe slower samples would work with DLI's though? NRV said he'd got some sample playing going with DLI's in the past.

 

you are correct in all that!

 

hehe I was about to use my LineUp game as an example, and I realized that probably most of the people that use the emulator in the PAL setting never saw the "presentation" part (because I jump over it if PAL is detected, the different number of scanlines wouldn't play nice with the sample timings)

 

so.. play this in in NTSC

 

lineup.zip

 

if I don't remember bad (it was 15 years ago!), the sample used was between 12 and 16Khz, and to fill the "vbi gap" i used some counters fine tuned by trial and error, until it sounds "correct"..

 

if you press and hold the Atari key (END key in the Atari800WinPlus emulator) you can see the sound wave

 

NRV

Share this post


Link to post
Share on other sites

oh I forgot to mention, I convert the data so that the low nibble should be played before the high nibble.

 

I was thinking that since VCOUNT is still working during VBI (or wsync also?), a program could play samples using DLIs during the display, and then continue to play outside the display using a loop that polls VCOUNT.

Share this post


Link to post
Share on other sites

Very interesting stuff and I have been requested to incorporate this stuff into a project I am involved with. One issue is my game is using a graphics 31 (gr.15, with text box) and a several DLIs to split up the player missile graphics and the game is all done in a VBI routine. One problem is with trying to play a wave sound during game play is that there may not be enough time to complete the VBIs when its playing one of these sound effects. Have to consider that Antic is going to be stealing main bus cycles for all the Antic 14 lines there.

 

I did examine the source code that uses the IRQ vectors. There were several obvious ways I can get these routines to take up less time. One is instead of doing a LDA (sample),y is do a LDA $ffff and modify the address (self modifying code). The second thing is not store 2 nibbles per byte, but what the volume + the force out. I know it will double the memory size, but will play quicker. Also I would remove the JSR Playsample and make it a single routine. If you don't intend to run it from Basic and don't need the floating point registers, you can use most of page 0. Instead of pushing and restoring the registers, save them somewhere in page 0.

Share this post


Link to post
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.

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