mirror of
https://github.com/irmen/prog8.git
synced 2025-01-28 17:33:13 +00:00
cx16: added a polling pcm streaming example
This commit is contained in:
parent
17f7b11148
commit
0ec719e429
@ -108,7 +108,8 @@ class TestCompilerOnExamplesCx16: FunSpec({
|
|||||||
"vtui/testvtui",
|
"vtui/testvtui",
|
||||||
"pcmaudio/play-adpcm",
|
"pcmaudio/play-adpcm",
|
||||||
"pcmaudio/stream-wav",
|
"pcmaudio/stream-wav",
|
||||||
"pcmaudio/stream-pcm-simple",
|
"pcmaudio/stream-simple-aflow",
|
||||||
|
"pcmaudio/stream-simple-poll",
|
||||||
"pcmaudio/vumeter",
|
"pcmaudio/vumeter",
|
||||||
"sprites/dragon",
|
"sprites/dragon",
|
||||||
"sprites/dragons",
|
"sprites/dragons",
|
||||||
|
@ -3,6 +3,16 @@ TODO
|
|||||||
|
|
||||||
See open issues on github.
|
See open issues on github.
|
||||||
|
|
||||||
|
Asm peephole optimizer: while cx16.VERA_AUDIO_CTRL & %01000000 == 0 { } compiles into the following. Replace the bne+bra into a beq. Similar for !=0 I guess?
|
||||||
|
p8l_label_5_whileloop
|
||||||
|
lda cx16.VERA_AUDIO_CTRL
|
||||||
|
and #$40
|
||||||
|
bne p8l_label_6_afterwhile
|
||||||
|
bra p8l_label_5_whileloop
|
||||||
|
p8l_label_6_afterwhile
|
||||||
|
|
||||||
|
Codegen: use BIT instruction for memory location bit 7 and 6 tests (use N and V flags)
|
||||||
|
|
||||||
Re-generate the skeletons doc files.
|
Re-generate the skeletons doc files.
|
||||||
|
|
||||||
Improve register load order in subroutine call args assignments:
|
Improve register load order in subroutine call args assignments:
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
; This program can stream a simple uncompressed PCM file from the sdcard.
|
; This program can stream a simple uncompressed PCM file from the sdcard.
|
||||||
; Currently it has been set up to play a 16 bit stereo PCM file,
|
|
||||||
; and it plays it in the given sample frequency typed in by the user.
|
|
||||||
;
|
;
|
||||||
; It uses a AFLOW irq handler to refill the vera's PCM fifo buffer,
|
; It is hardwired to play a 16 bit stereo PCM file,
|
||||||
; and sets a flag that signals the main program to load the next block of
|
; but you can type in the sample rate you want to play it in.
|
||||||
|
;
|
||||||
|
; It uses a AFLOW irq handler to refill the vera's PCM fifo buffer.
|
||||||
|
;
|
||||||
|
; The irq handler sets a flag that signals the main program to load the next block of
|
||||||
; data from disk. It is problematic to call kernal I/O routines inside an irq handler,
|
; data from disk. It is problematic to call kernal I/O routines inside an irq handler,
|
||||||
; otherwise the aflow handler itself could have loaded the pcm data straight into
|
; otherwise the aflow handler itself could have loaded the pcm data straight into
|
||||||
; the vera's fifo buffer. But this could lead to race conditions so we need explicit buffering.
|
; the vera's fifo buffer. But this could lead to race conditions so we need explicit buffering.
|
106
examples/cx16/pcmaudio/stream-simple-poll.p8
Normal file
106
examples/cx16/pcmaudio/stream-simple-poll.p8
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
; This program can stream a simple uncompressed PCM file from the sdcard.
|
||||||
|
;
|
||||||
|
; It is hardwired to play a 16 bit stereo PCM file,
|
||||||
|
; but you can type in the sample rate you want to play it in.
|
||||||
|
;
|
||||||
|
; It uses simple polling on the AFLOW flag rather than actually using a IRQ hander,
|
||||||
|
; to see when to refill the FIFO buffer.
|
||||||
|
;
|
||||||
|
; The sample data is simply read using diskio.f_read() routine, but that uses MACPTR internally for fast loads.
|
||||||
|
|
||||||
|
|
||||||
|
%import diskio
|
||||||
|
%import textio
|
||||||
|
%option no_sysinit
|
||||||
|
|
||||||
|
main {
|
||||||
|
|
||||||
|
sub start() {
|
||||||
|
str MUSIC_FILENAME = "?"*32
|
||||||
|
txt.print("what sample rate (hz) do you want to play at: ")
|
||||||
|
void txt.input_chars(MUSIC_FILENAME)
|
||||||
|
music.vera_rate_hz = conv.str2uword(MUSIC_FILENAME)
|
||||||
|
if music.vera_rate_hz==0
|
||||||
|
music.vera_rate_hz=44100
|
||||||
|
music.calculate_vera_rate(music.vera_rate_hz)
|
||||||
|
|
||||||
|
txt.print("\nname of raw .pcm file to play on drive 8: ")
|
||||||
|
while 0==txt.input_chars(MUSIC_FILENAME) {
|
||||||
|
; until user types a name...
|
||||||
|
}
|
||||||
|
|
||||||
|
if diskio.f_open(MUSIC_FILENAME) {
|
||||||
|
cx16.rombank(0)
|
||||||
|
void diskio.fastmode(1)
|
||||||
|
music.start()
|
||||||
|
while music.stream() {
|
||||||
|
txt.chrout('.')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
txt.print("\nio error")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
music {
|
||||||
|
uword audio_buffer = memory("audiobuffer", 1024, 0)
|
||||||
|
|
||||||
|
uword vera_rate_hz
|
||||||
|
ubyte vera_rate
|
||||||
|
|
||||||
|
sub start() {
|
||||||
|
cx16.VERA_AUDIO_RATE = 0 ; halt playback
|
||||||
|
cx16.VERA_AUDIO_CTRL = %10111011 ; stereo 16 bit, volume 11
|
||||||
|
sys.memset(audio_buffer, 1024, 0)
|
||||||
|
cx16.VERA_AUDIO_RATE = vera_rate ; start playback
|
||||||
|
}
|
||||||
|
|
||||||
|
sub calculate_vera_rate(uword sample_rate) {
|
||||||
|
const uword vera_freq_factor = 25_000_000 / 65536
|
||||||
|
vera_rate = (sample_rate / vera_freq_factor) as ubyte + 1
|
||||||
|
vera_rate_hz = vera_rate * vera_freq_factor
|
||||||
|
}
|
||||||
|
|
||||||
|
sub stream() -> bool {
|
||||||
|
while cx16.VERA_ISR & %00001000 == 0 {
|
||||||
|
; poll until AFLOW is raised ("fifo is less than 25% full, feed me more data soon!")
|
||||||
|
}
|
||||||
|
|
||||||
|
; Reading directly from disk into the audio fifo is possible, but can result in hick ups.:
|
||||||
|
; diskio.reset_read_channel()
|
||||||
|
; void, cx16.r14 = cx16.MACPTR(0, &cx16.VERA_AUDIO_DATA, true)
|
||||||
|
; void, cx16.r15 = cx16.MACPTR(0, &cx16.VERA_AUDIO_DATA, true)
|
||||||
|
; return cx16.r14+cx16.r15 == 1024
|
||||||
|
|
||||||
|
; so instead: copy current buffer to Vera audio FIFO and immediately read the next 1 KB block from disk into the buffer.
|
||||||
|
fill_fifo()
|
||||||
|
return diskio.f_read(audio_buffer, 1024) == 1024
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub fill_fifo() {
|
||||||
|
; copy 1024 bytes of audio data from the buffer into vera's fifo, quickly!
|
||||||
|
%asm {{
|
||||||
|
lda p8v_audio_buffer
|
||||||
|
sta _loop+1
|
||||||
|
sta _lp2+1
|
||||||
|
lda p8v_audio_buffer+1
|
||||||
|
sta _loop+2
|
||||||
|
sta _lp2+2
|
||||||
|
ldx #4
|
||||||
|
ldy #0
|
||||||
|
_loop lda $ffff,y
|
||||||
|
sta cx16.VERA_AUDIO_DATA
|
||||||
|
iny
|
||||||
|
_lp2 lda $ffff,y
|
||||||
|
sta cx16.VERA_AUDIO_DATA
|
||||||
|
iny
|
||||||
|
bne _loop
|
||||||
|
inc _loop+2
|
||||||
|
inc _lp2+2
|
||||||
|
dex
|
||||||
|
bne _loop
|
||||||
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user