adding pref for rsound package

19 views
Skip to first unread message

John Clements

unread,
Dec 13, 2016, 6:10:23 PM12/13/16
to Racket Users, Robby Findler
The RSound package generates sounds. It generates a bunch of them at startup, and in general, there’s no way to know exactly what frame rates the machine supports. Historically, 44.1KHz has been the standard, but recently, 48K has been gaining traction, and many of my students’ machines no longer support 44.1K at all.

After waffling for a while on how best to solve this, I think that the right solution is to add a preference for this. I investigated the interface, and thanks to the exceptional DrRacket docs, I had no trouble implementing the preference. I have two questions/concerns:

1) I notice that I don’t seem to have any other packages that have preferences, and I feel a bit funny about adding a top-level preference pane to DrRacket. Currently, my preference panel contains exactly one choice box, with the choices 44100 and 48000. Should I attach this to some other preference panel?

2) Should I be adding this preference pane in the phase1 or phase2 callbacks of the tool interface, or in the base module invocation? I picked phase1, and it seems to work. Based on my reading of the phase1 and phase2 docs, it seems like… it shouldn’t matter, and maybe I should just put it in the unit invocation.

Finally, here’s the source code for the tool.rkt file. Any comments much appreciated!

Best,

John

https://github.com/jbclements/RSound/blob/forty-eight-k/rsound/tool.rkt

or simply as inline text:

#lang racket/gui
(require drracket/tool
framework)

(provide tool@)

;; the list of permissible default frame rates.
;; This is used for generation of all built-in sounds, and is the
;; default for pstreams and in other places. You can change it with
;; the default-frame-rate parameter, but this won't affect the sounds
;; that are already generated.
;; For ease of use, we limit this setting to one of a few possibilities.
;; there's really no reason not to allow anything between 8K and 48K except
;; that it would confuse people. I don't know whether 96K would present
;; problems... it might slow down sound generation unacceptably.
(define LEGAL-DEFAULT-FRS '(44100 48000))

;; if the existing preference is not one of the legal ones, reset to this:
(define RESET-FR 44100)

(define tool@
(unit
(import drracket:tool^)
(export drracket:tool-exports^)
(define (phase1)
(define FR-pref-from-file (get-preference 'rsound:default-frame-rate))
(define FR-pref (cond [(member FR-pref-from-file LEGAL-DEFAULT-FRS)
FR-pref-from-file]
[else
(put-preferences '(rsound:default-frame-rate)
(list RESET-FR))
RESET-FR]))
(define FR-pref-idx (for/first ([i (in-naturals)]
[fr (in-list LEGAL-DEFAULT-FRS)]
#:when (= FR-pref fr))
i))
(preferences:add-panel
"RSound"
(λ (parent)
(define vpanel
(new vertical-panel% (parent parent) (alignment '(left top))))
(new choice%
[label "default frame rate"]
[choices (map number->string LEGAL-DEFAULT-FRS)]
[parent vpanel]
[selection FR-pref-idx]
[callback
(λ (choicebox evt)
(when (equal? (send evt get-event-type) 'choice)
(match (send choicebox get-selection)
[#f (error 'choice-callbox
"internal error: no default frame rate selected (should be impossible?)")]
[n (put-preferences '(rsound:default-frame-rate)
(list (list-ref LEGAL-DEFAULT-FRS n)))])))])
vpanel)))
(define (phase2) (void))))



Robby Findler

unread,
Dec 13, 2016, 8:17:07 PM12/13/16
to John Clements, Racket Users
The phase1/phase2 stuff isn't really for preference initialization.
You should be able to just do it when the module require'd (ie at its
toplevl) or when the tool@ unit is invoked. Either phase would also be
fine.

Also, you might want to use the preference directly in the part of the
library that doesn't depend on DrRacket (so you can run it, say, from
the command-line), in which case you'd want to move the preferences
initialization to that library.

And you might want to use framework/preferences, a preferences library
that builds on top of get-preference and adds some conveniences.

Robby

John Clements

unread,
Dec 14, 2016, 10:32:27 PM12/14/16
to Robby Findler, Racket Users

> On Dec 13, 2016, at 17:17, Robby Findler <ro...@eecs.northwestern.edu> wrote:
>
> The phase1/phase2 stuff isn't really for preference initialization.
> You should be able to just do it when the module require'd (ie at its
> toplevl) or when the tool@ unit is invoked. Either phase would also be
> fine.

Okay, excellent.

>
> Also, you might want to use the preference directly in the part of the
> library that doesn't depend on DrRacket (so you can run it, say, from
> the command-line), in which case you'd want to move the preferences
> initialization to that library.

Yep, already did that.
>
> And you might want to use framework/preferences, a preferences library
> that builds on top of get-preference and adds some conveniences.

Oh, that looks nice! Many thanks!

John
> --
> You received this message because you are subscribed to the Google Groups "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to racket-users...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



Reply all
Reply to author
Forward
0 new messages