rsound-compat.rkt
#lang racket

(require "vorbisfile.rkt")

;; I don't want clements/rsound to be a dependency of vorbisfile
;; unless this file is run.

;; Replace all this junk with (require (planet clements/rsound)) to
;; see what's going on here. (Sorry for all the verbosity!)
(define mono-signal->rsound (dynamic-require '(planet clements/rsound) 'mono-signal->rsound))
(define signals->rsound (dynamic-require '(planet clements/rsound) 'signals->rsound))
(define s16max/i (dynamic-require '(planet clements/rsound)
                                  's16max/i))
(define default-sample-rate (dynamic-require '(planet clements/rsound)
                                  'default-sample-rate))

(provide vorbis->rsound)

(define (vorbis->rsound vf)
  (define rs-bytes
    (port->bytes
     (make-vorbis-input-port vf 0 2 1)))

  (define (s16->real x)
    (/ (exact->inexact x) s16max/i))

  (define (left-sig fr)
    (s16->real
     (integer-bytes->integer rs-bytes #t #f
                             (* 4 fr)
                             (+ 2 (* 4 fr)))))

  (define (right-sig fr)
    (s16->real
     (integer-bytes->integer rs-bytes #t #f
                             (+ 2 (* 4 fr))
                             (+ 4 (* 4 fr)))))
  (define (mono-sig fr)
    (s16->real
     (integer-bytes->integer rs-bytes #t #f
                             (* 2 fr) (* 2 (add1 fr)))))

  (parameterize ([default-sample-rate (vorbis-frequency vf)])
    (case (vorbis-channels vf)
      [(1) (mono-signal->rsound (sub1 (vorbis-length-samples vf)) mono-sig)]
      [(2) (signals->rsound (sub1 (vorbis-length-samples vf))
                            left-sig
                            right-sig)]
      [else (raise-type-error 'vorbisfile->rsound "We only support files with 1 or 2 channels.")])))