summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chickadee/audio/vorbis.scm317
1 files changed, 157 insertions, 160 deletions
diff --git a/chickadee/audio/vorbis.scm b/chickadee/audio/vorbis.scm
index ab85187..74dd768 100644
--- a/chickadee/audio/vorbis.scm
+++ b/chickadee/audio/vorbis.scm
@@ -21,11 +21,10 @@
(define-module (chickadee audio vorbis)
#:use-module (chickadee config)
+ #:use-module (chickadee data bytestruct)
#:use-module (ice-9 format)
#:use-module (ice-9 match)
#:use-module (rnrs bytevectors)
- #:use-module (srfi srfi-9)
- #:use-module (srfi srfi-9 gnu)
#:use-module (system foreign)
#:export (vorbis-open
vorbis-clear
@@ -56,134 +55,153 @@
(define name
(vorbis-func return-type func-name arg-types)))
-(define ogg-sync-state
- (list '* ; data
- int ; storage
- int ; fill
- int ; returned
- int ; unsynced
- int ; headerbytes
- int ; bodybytes
- ))
-
-(define ogg-stream-state
- (list '* ; body_data
- long ; body_storage
- long ; body_fill
- long ; body_returned
- '* ; lacing_vals
- '* ; granule_vals
- long ; lacing_storage
- long ; lacing_fill
- long ; lacing_packet
- long ; lacing_returned
- (make-list 282 uint8) ; header
- int ; header_fill
- int ; e_o_s
- int ; b_o_s
- long ; serialno
- long ; pageno
- int64 ; packetno
- int64 ; granulepos
- ))
-
-(define oggpack-buffer
- (list long ; endbyte
- int ; endbit
- '* ; buffer
- '* ; ptr
- long ; storage
- ))
-
-(define vorbis-dsp-state
- (list int ; analysisp
- '* ; vi
- '* ; pcm
- '* ; pcmret
- int ; pcm_storage
- int ; pcm_current
- int ; pcm_returned
- int ; preextrapolate
- int ; eofflag
- long ; lW
- long ; W
- long ; nW
- long ; centerW
- int64 ; granulepos
- int64 ; sequence
- int64 ; glue_bits
- int64 ; time_bits
- int64 ; floor_bits
- int64 ; res_bits
- '* ; backend_state
- ))
-
-(define vorbis-block
- (list '* ; pcm
- oggpack-buffer ; opb
- long ; lW
- long ; W
- long ; nW
- int ; pcmend
- int ; mode
- int ; eofflag
- int64 ; granulepos
- int64 ; sequence
- '* ; vd
- '* ; localstore
- long ; localtop
- long ; localalloc
- long ; totaluse
- '* ; reap
- long ; glue_bits
- long ; time_bits
- long ; floor_bits
- long ; res_bits
- '* ; internal
- ))
-
-(define %vorbis-info
- (list int ; version
- int ; channels
- long ; rate
- long ; bitrate_upper
- long ; bitrate_nominal
- long ; bitrate_lower
- long ; bitrate_window
- '* ; codec_setup
- ))
-
-(define ov-callbacks
- (list '* ; read_func
- '* ; seek_func
- '* ; close_func
- '* ; tell_func
- ))
-
-(define ogg-vorbis-file
- (list '* ; datasource
- int ; seekable
- int64 ; offset
- int64 ; end
- ogg-sync-state ; oy
- int ; links
- '* ; offsets
- '* ; dataoffsets
- '* ; serialnos
- '* ; pcmlengths
- '* ; vi
- '* ; vc
- int64 ; pcm_offset
- int ; ready_state
- long ; current_serialno
- int ; current_link
- double ; bittrack
- double ; samptrack
- ogg-stream-state ; os
- vorbis-dsp-state ; vd
- vorbis-block ; vb
- ov-callbacks ; callbacks
- ))
+(define-bytestruct <ogg-sync-state>
+ (struct
+ (data (* u8))
+ (storage int)
+ (fill int)
+ (returned int)
+ (unsynced int)
+ (headerbytes int)
+ (bodybytes int)))
+
+(define-bytestruct <ogg-stream-state>
+ (struct
+ (body-data (* u8))
+ (body-storage long)
+ (body-fill long)
+ (body-returned long)
+ (lacing-vals (* int))
+ (granule-vals (* s64))
+ (lacing-storage long)
+ (lacing-fill long)
+ (lacing-packet long)
+ (lacing-returned long)
+ (header (array 282 u8))
+ (header-fill int)
+ (e_o_s int)
+ (b_o_s int)
+ (serialno long)
+ (pageno long)
+ (packetno s64)
+ (granulepos s64)))
+
+(define-bytestruct <oggpack-buffer>
+ (struct
+ (endbyte long)
+ (endbit int)
+ (buffer (* u8))
+ (ptr (* u8))
+ (storage long)))
+
+(define-bytestruct <vorbis-info>
+ (struct
+ (version int)
+ (channels int)
+ (rate long)
+ (bitrate-upper long)
+ (bitrate-nominal long)
+ (bitrate-lower long)
+ (bitrate-window long)
+ (codec-setup (* void))))
+
+(define-bytestruct-predicate vorbis-info? <vorbis-info>)
+(define-bytestruct-getter vorbis-info-version <vorbis-info> (version))
+(define-bytestruct-getter vorbis-info-channels <vorbis-info> (channels))
+(define-bytestruct-getter vorbis-info-sample-rate <vorbis-info> (rate))
+
+(define-bytestruct <vorbis-comment>
+ (struct
+ (user-comments (* (* u8)))
+ (comment-lengths (* int))
+ (comments int)
+ (vendor (* u8))))
+
+(define-bytestruct <vorbis-dsp-state>
+ (struct
+ (analysisp int)
+ (vi (* <vorbis-info>))
+ (pcm (* (* f32)))
+ (prcmret (* (* f32)))
+ (pcm-storage int)
+ (pcm-current int)
+ (pcm-returned int)
+ (preextrapolate int)
+ (eofflag int)
+ (lW long)
+ (W long)
+ (nW long)
+ (centerW long)
+ (granulepos s64)
+ (sequence s64)
+ (glue-bits s64)
+ (time-bits s64)
+ (floor-bits s64)
+ (res-bits s64)
+ (backend-state (* void))))
+
+(define-bytestruct <alloc-chain>
+ (struct
+ (ptr (* void))
+ (next (* <alloc-chain>))))
+
+(define-bytestruct <vorbis-block>
+ (struct
+ (pcm (* (* f32)))
+ (opb <oggpack-buffer>)
+ (lW long)
+ (W long)
+ (nW long)
+ (pcmend int)
+ (mode int)
+ (eofflag int)
+ (granulepos s64)
+ (sequence s64)
+ (vd (* <vorbis-dsp-state>))
+ (localstore (* void))
+ (localtop long)
+ (localalloc long)
+ (totaluse long)
+ (reap (* <alloc-chain>))
+ (glue-bits long)
+ (time-bits long)
+ (floor-bits long)
+ (res-bits long)
+ (internal (* void))))
+
+(define-bytestruct <ov-callbacks>
+ (struct
+ ;; These are actually function pointers, but we don't use them so
+ ;; void pointers are fine.
+ (read-func (* void))
+ (seek-func (* void))
+ (close-func (* void))
+ (tell-func (* void))))
+
+(define-bytestruct <ogg-vorbis-file>
+ (struct
+ (datasource (* void))
+ (seekable int)
+ (offset s64)
+ (end s64)
+ (oy <ogg-sync-state>)
+ (links int)
+ (offsets (* s64))
+ (dataoffsets (* s64))
+ (serialnos (* long))
+ (pcmlengths (* s64))
+ (vi (* <vorbis-info>))
+ (vc (* <vorbis-comment>))
+ (pcm-offset s64)
+ (ready-state int)
+ (current-seialno long)
+ (current-link int)
+ (bittrack f64)
+ (samptrack f64)
+ (os <ogg-stream-state>)
+ (vd <vorbis-dsp-state>)
+ (vb <vorbis-block>)
+ (callbacks <ov-callbacks>)))
(define OV_FALSE -1)
(define OV_EOF -2)
@@ -235,49 +253,28 @@
;;; High-level public API
;;;
-(define-record-type <vorbis-file>
- (wrap-vorbis-file bv ptr)
- vorbis-file?
- (bv vorbis-file-bv)
- (ptr unwrap-vorbis-file))
-
-(define (display-vorbis-file vf port)
- (format port "#<vorbis-file ~x>" (pointer-address (unwrap-vorbis-file vf))))
-
-(set-record-type-printer! <vorbis-file> display-vorbis-file)
-
(define (vorbis-open file-name)
"Open the OGG Vorbis audio file located at FILE-NAME."
- (let* ((bv (make-bytevector (sizeof ogg-vorbis-file)))
- (ptr (bytevector->pointer bv)))
- (ov-fopen (string->pointer file-name) ptr)
- (wrap-vorbis-file bv ptr)))
+ (let ((vf (bytestruct-alloc <ogg-vorbis-file>)))
+ (ov-fopen (string->pointer file-name)
+ (bytestruct->pointer <ogg-vorbis-file> vf))
+ vf))
(define (vorbis-clear vf)
"Clear the buffers of the Vorbis file VF."
- (ov-clear (unwrap-vorbis-file vf)))
-
-(define-record-type <vorbis-info>
- (make-vorbis-info version channels sample-rate)
- vorbis-info?
- (version vorbis-info-version)
- (channels vorbis-info-channels)
- (sample-rate vorbis-info-sample-rate))
+ (ov-clear (bytestruct->pointer <ogg-vorbis-file> vf)))
(define (vorbis-info vf)
- (match (parse-c-struct (ov-info (unwrap-vorbis-file vf) -1)
- %vorbis-info)
- ((version channels sample-rate _ _ _ _ _)
- (make-vorbis-info version channels sample-rate))))
+ (pointer->bytestruct <vorbis-info> (bytestruct-ref <ogg-vorbis-file> (vi) vf)))
(define (vorbis-time-total vf)
- (ov-time-total (unwrap-vorbis-file vf) -1))
+ (ov-time-total (bytestruct->pointer <ogg-vorbis-file> vf) -1))
(define (vorbis-time-seek vf t)
- (ov-time-seek (unwrap-vorbis-file vf) t))
+ (ov-time-seek (bytestruct->pointer <ogg-vorbis-file> vf) t))
(define* (vorbis-read vf buffer #:optional (start 0))
- (ov-read (unwrap-vorbis-file vf)
+ (ov-read (bytestruct->pointer <ogg-vorbis-file> vf)
(bytevector->pointer buffer start)
(- (bytevector-length buffer) start)
0 ; little endian