tweak audio.vorbis to queue up a fixed-sized preallocated buffer instead of taking ogg packets in whatever bizarre size they come

db4
Joe Groff 2010-01-24 21:28:59 -08:00
parent 14de77d435
commit 841e267f0a
1 changed files with 51 additions and 30 deletions

View File

@ -1,6 +1,6 @@
! (c)2007, 2010 Chris Double, Joe Groff bsd license ! (c)2007, 2010 Chris Double, Joe Groff bsd license
USING: accessors alien.c-types audio.engine byte-arrays classes.struct USING: accessors alien.c-types audio.engine byte-arrays classes.struct
combinators destructors fry gpu.buffers io io.files io.encodings.binary combinators destructors fry io io.files io.encodings.binary
kernel libc locals make math math.order math.parser ogg ogg.vorbis kernel libc locals make math math.order math.parser ogg ogg.vorbis
sequences specialized-arrays specialized-vectors ; sequences specialized-arrays specialized-vectors ;
FROM: alien.c-types => float short void* ; FROM: alien.c-types => float short void* ;
@ -10,6 +10,7 @@ IN: audio.vorbis
TUPLE: vorbis-stream < disposable TUPLE: vorbis-stream < disposable
stream stream
{ buffer byte-array }
{ packet ogg-packet } { packet ogg-packet }
{ sync-state ogg-sync-state } { sync-state ogg-sync-state }
{ page ogg-page } { page ogg-page }
@ -19,8 +20,7 @@ TUPLE: vorbis-stream < disposable
{ block vorbis-block } { block vorbis-block }
{ comment vorbis-comment } { comment vorbis-comment }
{ temp-state ogg-stream-state } { temp-state ogg-stream-state }
{ #vorbis-headers integer initial: 0 } { #vorbis-headers integer initial: 0 } ;
{ stream-eof? boolean } ;
CONSTANT: stream-buffer-size 4096 CONSTANT: stream-buffer-size 4096
@ -61,8 +61,10 @@ ERROR: no-vorbis-in-ogg ;
: retrieve-page ( vorbis-stream -- ? ) : retrieve-page ( vorbis-stream -- ? )
[ sync-state>> ] [ page>> ] bi ogg_sync_pageout 0 > ; inline [ sync-state>> ] [ page>> ] bi ogg_sync_pageout 0 > ; inline
: sync-pages ( vorbis-stream -- ) : (sync-pages) ( vorbis-stream ? -- ? )
dup retrieve-page [ [ queue-page ] [ sync-pages ] bi ] [ drop ] if ; over retrieve-page [ [ drop queue-page ] [ drop t (sync-pages) ] 2bi ] [ nip ] if ;
: sync-pages ( vorbis-stream -- ? )
f (sync-pages) ; inline
: standard-initial-header? ( vorbis-stream -- bool ) : standard-initial-header? ( vorbis-stream -- bool )
page>> ogg_page_bos zero? not ; inline page>> ogg_page_bos zero? not ; inline
@ -152,23 +154,28 @@ ERROR: no-vorbis-in-ogg ;
: get-pending-decoded-audio ( vorbis-stream -- pcm len ) : get-pending-decoded-audio ( vorbis-stream -- pcm len )
dsp-state>> f <void*> [ vorbis_synthesis_pcmout ] keep *void* swap ; dsp-state>> f <void*> [ vorbis_synthesis_pcmout ] keep *void* swap ;
:: make-pcm-buffer ( vorbis-stream pcm len -- short-array ) : float>short-sample ( float -- short )
vorbis-stream info>> channels>> :> #channels -32767.5 * 0.5 - >integer -32768 32767 clamp ; inline
pcm #channels <direct-void*-array> :> channel*s
#channels len * <short-vector> :> output
len iota [| sample | :: write-pcm-to-buffer ( vorbis-stream offset pcm len -- offset' )
vorbis-stream buffer>> :> buffer
buffer length -1 shift :> buffer-length
offset -1 shift :> sample-offset
buffer buffer-length <direct-short-array> sample-offset short-vector boa :> short-buffer
vorbis-stream info>> channels>> :> #channels
buffer-length sample-offset - #channels /i :> max-len
len max-len min :> len'
pcm #channels <direct-void*-array> :> channel*s
len' iota [| sample |
#channels iota [| channel | #channels iota [| channel |
channel channel*s nth len <direct-float-array> :> samples channel channel*s nth len <direct-float-array>
sample samples nth sample swap nth
-32767.0 * >integer -32767 32767 clamp float>short-sample short-buffer push
output push
] each ] each
] each ] each
output >short-array ; inline vorbis-stream dsp-state>> len' vorbis_synthesis_read drop
short-buffer length 1 shift ; inline
: read-samples ( vorbis-stream pcm len -- )
[ dsp-state>> ] [ drop ] [ ] tri* vorbis_synthesis_read drop ; inline
: queue-audio ( vorbis-stream -- ? ) : queue-audio ( vorbis-stream -- ? )
dup [ stream-state>> ] [ packet>> ] bi ogg_stream_packetout 0 > [ dup [ stream-state>> ] [ packet>> ] bi ogg_stream_packetout 0 > [
@ -177,18 +184,34 @@ ERROR: no-vorbis-in-ogg ;
] [ drop ] if t ] [ drop ] if t
] [ drop f ] if ; ] [ drop f ] if ;
: decode-audio ( vorbis-stream -- short-array/f length/f ) : (decode-audio) ( vorbis-stream offset -- offset' )
dup get-pending-decoded-audio dup 0 > [ over get-pending-decoded-audio dup 0 > [ write-pcm-to-buffer ] [
[ make-pcm-buffer dup byte-length ] [ read-samples ] 3bi 2drop over queue-audio [ (decode-audio) ] [ nip ] if
] [
2drop dup queue-audio [ decode-audio ] [ drop f f ] if
] if ; ] if ;
: decode-audio ( vorbis-stream offset -- offset' )
2dup (decode-audio) {
{
[ 3dup [ buffer>> length ] [ drop ] [ ] tri* = ]
[ 2nip ]
}
{
[ 2dup = ]
[
drop
[ drop buffer-data-from-stream drop ]
[ over sync-pages [ decode-audio ] [ nip ] if ] 2bi
]
}
[ nip decode-audio ]
} cond ;
PRIVATE> PRIVATE>
: <vorbis-stream> ( stream -- vorbis-stream ) :: <vorbis-stream> ( stream buffer-size -- vorbis-stream )
[ [
vorbis-stream new-disposable vorbis-stream new-disposable
swap >>stream stream >>stream
buffer-size <byte-array> >>buffer
ogg-packet malloc-struct |free >>packet ogg-packet malloc-struct |free >>packet
ogg-sync-state malloc-struct |free >>sync-state ogg-sync-state malloc-struct |free >>sync-state
ogg-page malloc-struct |free >>page ogg-page malloc-struct |free >>page
@ -206,8 +229,8 @@ PRIVATE>
} cleave } cleave
] with-destructors ; ] with-destructors ;
: read-vorbis-stream ( filename -- vorbis-stream ) : read-vorbis-stream ( filename buffer-size -- vorbis-stream )
binary <file-reader> <vorbis-stream> ; inline [ binary <file-reader> ] dip <vorbis-stream> ; inline
M: vorbis-stream dispose* M: vorbis-stream dispose*
{ {
@ -225,6 +248,4 @@ M: vorbis-stream dispose*
M: vorbis-stream generator-audio-format M: vorbis-stream generator-audio-format
[ info>> channels>> ] [ drop 16 ] [ info>> rate>> ] tri ; [ info>> channels>> ] [ drop 16 ] [ info>> rate>> ] tri ;
M: vorbis-stream generate-audio M: vorbis-stream generate-audio
dup decode-audio [ buffer>> ] [ 0 decode-audio ] bi ;
[ [ drop ] 2dip ]
[ drop [ buffer-data-from-stream drop ] [ sync-pages ] [ decode-audio ] tri ] if* ;