;;; Snd extensions for lint (require lint.scm) ;;; *lint* is the lint environment, so everything in lint.scm is accessible here ;;; -------------------------------- ;;; this sends lint's output to the Snd repl's widget (define (snd-lint file) (lint file (openlet (inlet :name "lint-output-port" :format (lambda (p str . args) (snd-print (apply format #f str args))) :write (lambda (obj p) (snd-print (object->string obj #t))) :display (lambda (obj p) (snd-print (object->string obj #f))) :write-string (lambda (str p) (snd-print str)) :write-char (lambda (ch p) (snd-print (string ch))) :newline (lambda (p) (snd-print (string #\newline))) :close-output-port (lambda (p) #f) :flush-output-port (lambda (p) #f))))) ;;; ---------------- deprecated funcs ---------------- ;;; Snd deprecated funcs, to be reported by lint (let ((deprecated-ops '((data-format . sample-type) (mus-sound-frames . mus-sound-framples) (mus-sound-data-format . mus-sound-sample-type) (mus-data-format-name . mus-sample-type-name) (mus-data-format->string . mus-sample-type->string) (default-output-data-format . default-output-sample-type) (channel->vct . channel->float-vector) (vct->channel . float-vector->channel) (region->vct . region->float-vector) (mix->vct . mix->float-vector) (transform->vct . transform->float-vector) (make-vct . make-float-vector) (vct-add! . float-vector-add!) (vct-subtract! . float-vector-subtract!) (vct-copy . copy) (vct-length . length) (vct-multiply! . float-vector-multiply!) (vct-offset! . float-vector-offset!) (vct-ref . float-vector-ref) (vct-scale! . float-vector-scale!) (vct-abs! . float-vector-abs!) (vct-fill! . fill!) (vct-set! . float-vector-set!) (vct-peak . float-vector-peak) (vct-peak-and-location . float-vector-peak-and-location) (vct-equal? . equal?) (vct? . float-vector?) (list->vct . list->float-vector) (vct->list . float-vector->list) (vector->vct . vector->float-vector) (vct->vector . float-vector->vector) (vct-move! . float-vector-move!) (vct-subseq . float-vector-subseq) (vct-reverse! . reverse!) (vct->string . float-vector->string) (vct* . float-vector*) (vct+ . float-vector+)))) (define (snd-lint-deprecate caller head form env) ((*lint* 'lint-format) "~A is deprecated; use ~A" caller head (cond ((assq head deprecated-ops) => cdr)))) (for-each (lambda (op) (hash-table-set! (*lint* 'special-case-functions) (car op) snd-lint-deprecate)) deprecated-ops)) ;;; ---------------- snd-display ---------------- ;;; check snd-display using format's lint code (hash-table-set! (*lint* 'special-case-functions) 'snd-display (hash-table-ref (*lint* 'special-case-functions) 'format)) ;;; ---------------- defgenerator ---------------- ;;; a lint walker for defgenerator (it defines various functions in the current environment) (let () (define (get-generator caller form env) (with-let (sublet *lint* :caller caller :form form :env env) (when (pair? (cdr form)) (let ((name (symbol->string ((if (pair? (cadr form)) caadr cadr) form)))) (if (and (pair? (cadr form)) (pair? (cdadr form))) (lint-walk caller (cdadr form) env)) (let ((gen? (symbol name "?")) (gen-make (symbol "make-" name))) (list (make-fvar gen? 'define (list 'x) `(define (,gen? x) (let? x)) env) (make-fvar gen-make 'define* (list :rest 'x :allow-other-keys) `(define* (,gen-make :rest x :allow-other-keys) (apply inlet x)) env))))))) (hash-table-set! (*lint* 'walker-functions) 'defgenerator (lambda (caller form env) (append (get-generator caller form env) env)))) ;;; ---------------- no side effect Snd functions ---------------- ;;; Snd functions that don't affect anything outside or mess with their arguments (let ((h (*lint* 'no-side-effect-functions))) (for-each (lambda (s) (hash-table-set! h s #t)) '(all-chans all-pass-bank? all-pass? apropos array-interp ask-about-unsaved-edits ask-before-overwrite asymmetric-fm? axis-color axis-info axis-label-font axis-numbers-font basic-color beats-per-measure beats-per-minute bes-i0 bes-i1 bes-in bes-j0 bes-j1 bes-jn bes-k0 bes-k1 bes-kn bes-y0 bes-y1 bes-yn bold-peaks-font channel-amp-envs channel-data channel-properties channel-property channel-style channel-sync channel-widgets channels channels-equal? channels=? chans clipping clm-table-size color->list color-cutoff color-inverted color-scale color? colormap colormap-name colormap-ref colormap-size colormap? comb-bank? comb? combined-data-color comment contrast-control contrast-control-amp contrast-control-bounds contrast-control? contrast-enhancement convolve? count-matches current-font current-time cursor cursor-color cursor-location-offset cursor-position cursor-size cursor-style cursor-update-interval dac-combines-channels dac-size data-color data-location data-size db->linear default-output-chans default-output-header-type default-output-sample-type default-output-srate degrees->radians delay? dialog-widgets disk-kspace dot-product dot-size edit-fragment edit-fragment-type-name edit-list->function edit-properties edit-property edit-tree edits edot-product env? enved-base enved-clip? enved-envelope enved-filter enved-filter-order enved-in-dB enved-power enved-style enved-target enved-wave? enved-waveform-color envelope-interp eps-bottom-margin eps-file eps-left-margin eps-size erf erfc even-multiple even-weight expand-control expand-control-bounds expand-control-hop expand-control-jitter expand-control-length expand-control-ramp expand-control? feql ffeql fffneq ffneq fft-log-frequency fft-log-magnitude fft-window fft-window-alpha fft-window-beta fft-with-phases file->frample? file->sample? file-name file-write-date filter-control-coeffs filter-control-envelope filter-control-in-dB filter-control-in-hz filter-control-order filter-control-waveform-color filter-control? filter? filtered-comb-bank? filtered-comb? find-dialog find-mark find-sound fir-filter? firmant? float-vector-equal? float-vector-max float-vector-min float-vector-peak float-vector-peak-and-location fneq foreground-color formant-bank? formant? frample framples ftell fveql get-internal-real-time getcwd getpid granulate? graph-color graph-cursor graph-style graphs-horizontal grid-density gsl-ellipj gsl-ellipk gsl-roots header-type html-dir html-program hz->radians identity iir-filter? initial-beg initial-dur integer->mark integer->mix integer->region integer->sound integer->transform just-sounds key-binding ladspa-dir left-sample lgamma linear->db lisp-graph-style lisp-graph? listener-color listener-colorized listener-font listener-prompt listener-selection listener-text-color little-endian? localtime locsig-ref locsig-reverb-ref locsig-type locsig? log-freq-start main-menu main-widgets make-env make-pulsed-env make-one-pole make-fir-coeffs make-formant make-all-pass-bank make-iir-filter make-filter make-comb make-polywave make-bezier make-delay make-nrxycos make-moving-norm make-nrxysin make-firmant make-sawtooth-wave make-color make-graph-data make-oscil make-oscil-bank make-two-zero make-fft-window make-moving-max make-filtered-comb-bank make-filtered-comb make-nsin make-rand-interp make-one-pole-all-pass make-rand make-formant-bank make-all-pass make-table-lookup make-one-zero make-notch make-square-wave make-moving-average make-polyshape make-triangle-wave make-comb-bank make-ncos make-rxyk!sin make-fir-filter make-two-pole make-asymmetric-fm make-rxyk!cos make-pulse-train mark->integer mark-color mark-home mark-hook mark-name mark-properties mark-property mark-sample mark-sync mark-sync-max mark-tag-height mark-tag-width mark? marks max-regions max-transform-peaks maxamp maxamp-position menu-widgets min-dB mix->integer mix-color mix-dialog-mix mix-drag-hook mix-home mix-length mix-name mix-properties mix-property mix-sampler? mix-sync mix-sync-max mix-tag-height mix-tag-width mix-tag-y mix-waveform-height mix? mixes move-sound? moving-average? moving-max? moving-norm? mus-alsa-buffer-size mus-alsa-buffers mus-alsa-capture-device mus-alsa-device mus-alsa-playback-device mus-alsa-squelch-warning mus-array-print-length mus-bytes-per-sample mus-channel mus-channels mus-chebyshev-t-sum mus-chebyshev-tu-sum mus-chebyshev-u-sum mus-clipping mus-data mus-describe mus-error-type->string mus-expand-filename mus-file-buffer-size mus-file-clipping mus-file-name mus-float-equal-fudge-factor mus-frequency mus-generator? mus-header-raw-defaults mus-header-type->string mus-header-type-name mus-header-writable mus-hop mus-increment mus-input? mus-interp-type mus-interpolate mus-length ;mus-location mus-max-malloc mus-max-table-size mus-name mus-offset mus-order mus-output? mus-phase mus-ramp mus-sample-type->string mus-sample-type-name mus-scaler mus-sound-chans mus-sound-comment mus-sound-data-location mus-sound-datum-size mus-sound-duration mus-sound-frames mus-sound-framples mus-sound-header-type mus-sound-length mus-sound-loop-info mus-sound-mark-info mus-sound-maxamp mus-sound-maxamp-exists? mus-sound-path mus-sound-sample-type mus-sound-samples mus-sound-srate mus-sound-type-specifier mus-sound-write-date mus-srate mus-type mus-width mus-xcoeff mus-xcoeffs mus-ycoeff mus-ycoeffs mus_header_t? ncos? notch? nrxycos? nrxysin? nsin? odd-multiple odd-weight one-pole-all-pass? one-pole? one-zero? oscil-bank? oscil? partials->polynomial partials->wave pausing peak-env-dir peaks-font phase-partials->wave phase-vocoder-amp-increments phase-vocoder-amps phase-vocoder-freqs phase-vocoder-phase-increments phase-vocoder-phases phase-vocoder? phases-get-peak play-arrow-size player-home player? players playing polyshape? polywave? position->x position->y position-color pulse-train? pulsed-env? radians->degrees radians->hz rand-interp? rand? readin? region->integer region-chans region-framples region-graph-style region-home region-maxamp region-maxamp-position region-position region-sample region-sampler? region-srate region? regions reverb-control-decay reverb-control-feedback reverb-control-length reverb-control-length-bounds reverb-control-lowpass reverb-control-scale reverb-control-scale-bounds reverb-control? right-sample rxyk!cos? rxyk!sin? sample sample-type sampler-at-end? sampler-home sampler-position sampler? samples samples->seconds sash-color sawtooth-wave? script-arg script-args search-procedure seconds->samples selected-channel selected-data-color selected-graph-color selected-sound selection selection-chans selection-creates-region selection-framples selection-maxamp selection-maxamp-position selection-member? selection-position selection-srate selection? short-file-name sinc-width singer-filter singer-nose-filter snd->sample? snd-gcs snd-global-state snd-help snd-tempnam snd-url snd-urls snd-version sound->integer sound-file-extensions sound-file? sound-files-in-directory sound-loop-info sound-properties sound-property sound-widgets sound? soundfont-info sounds spectro-hop spectro-x-angle spectro-x-scale spectro-y-angle spectro-y-scale spectro-z-angle spectro-z-scale spectrum-end spectrum-start speed-control speed-control-bounds speed-control-style speed-control-tones square-wave? srate src? ssb-am? strftime sync-max sync-style syncd-marks table-lookup? tap? temp-dir text-focus-color time-graph-style time-graph-type time-graph? tiny-font tmpnam tracking-cursor-style transform->integer transform-graph-style transform-graph-type transform-graph? transform-normalization transform-sample transform-size transform-type transform? triangle-wave? two-pole? two-zero? variable-graph? wave-train? wavelet-type wavo-hop wavo-trace widget-position widget-size widget-text window-height window-width window-x window-y with-background-processes with-file-monitor with-gl with-inset-graph with-interrupts with-menu-icons with-mix-tags with-pointer-focus with-relative-panes with-smpte-label with-toolbar with-tooltips with-tracking-cursor with-verbose-cursor x->position x-axis-label x-axis-style x-bounds x-position-slider x-zoom-slider y->position y-axis-label y-bounds y-position-slider y-zoom-slider zoom-color zoom-focus-style zoom-one-pixel))) ;;; ---------------- Snd makers ---------------- (let ((h (*lint* 'makers))) (for-each (lambda (s) (hash-table-set! h s #t)) '(make-env make-pulsed-env make-one-pole make-fir-coeffs make-convolve make-wave-train make-formant make-all-pass-bank make-iir-filter make-filter make-comb make-sample->file make-polywave make-bezier make-delay make-nrxycos make-moving-norm make-nrxysin make-firmant make-sawtooth-wave make-color make-player make-graph-data make-oscil make-oscil-bank make-two-zero make-fft-window make-moving-max make-filtered-comb-bank make-filtered-comb make-nsin make-rand-interp make-one-pole-all-pass make-rand make-formant-bank make-readin make-all-pass make-phase-vocoder make-table-lookup make-one-zero make-notch make-square-wave make-file->frample make-moving-average make-granulate make-polyshape make-locsig make-triangle-wave make-mix-sampler make-move-sound make-comb-bank make-ncos make-rxyk!sin make-variable-graph make-fir-filter make-file->sample make-ssb-am make-two-pole make-region-sampler make-frample->file make-asymmetric-fm make-sampler make-region make-snd->sample make-src make-rxyk!cos make-pulse-train))) ;;; ---------------- Snd booleans ---------------- ;;; add Snd/clm type checkers to lint's table (lint assumes that these take one argument) (for-each (lambda (tchk) (hash-table-set! (*lint* 'booleans) tchk #t)) '(all-pass? all-pass-bank? asymmetric-fm? comb? comb-bank? convolve? delay? env? file->sample? filter? filtered-comb? filtered-comb-bank? fir-filter? firmant? formant-bank? formant? granulate? iir-filter? locsig? move-sound? moving-average? moving-max? moving-norm? mus-generator? mus-input? mus-output? ncos? notch? nrxycos? nrxysin? nsin? one-pole? one-pole-all-pass? one-zero? oscil? oscil-bank? phase-vocoder? polyshape? polywave? pulse-train? pulsed-env? rand-interp? rand? readin? rxyk!cos? rxyk!sin? sample->file? sawtooth-wave? square-wave? src? ssb-am? table-lookup? tap? triangle-wave? two-pole? two-zero? wave-train? file->frample? frample->file? mark? mix? mix-sampler? region?)) #| ;;; a more complicated search: (let ((old-do-walker (hash-table-ref (*lint* 'walker-functions) 'do))) ;; look for forms like (do ((i 0 (+ i 1))) ((= i 123)) (float-vector-set! v i (* .2 (float-vector-ref v i)))) (hash-table-set! (*lint* 'walker-functions) 'do (lambda (caller form env) (when (and (pair? (cdr form)) (pair? (cddr form))) (let ((vars (cadr form)) (end+res (caddr form)) (body (cdddr form))) (when (and (pair? vars) (null? (cdr vars)) (pair? body) (null? (cdr body)) (pair? (car body)) (eq? (caar body) 'float-vector-set!) ;(eqv? 0 (cadar vars)) -- we'll use subvector if not 0 (pair? (cddar vars)) (eqv? (length (caddar vars)) 3)) (let ((stepper (caddar vars)) (expr (cdar body)) (end (car end+res))) (when (and (eq? (car stepper) '+) (memq (caar vars) stepper) (memv 1 stepper) (eqv? (length end) 3) (memq (caar vars) end) (memq (car end) '(= >=)) (symbol? (car expr)) (eq? (cadr expr) (caar vars)) (pair? (caddr expr))) (let ((ref (caddr expr))) (when (and (eq? (car ref) '*) (or (and (pair? (cadr ref)) (eq? (caadr ref) 'float-vector-ref) (eq? (cadadr ref) (car expr)) (eq? (caddr (cadr ref)) (caar vars))) (and (pair? (caddr ref)) (eq? (caaddr ref) 'float-vector-ref) (eq? (cadr (caddr ref)) (car expr)) (eq? (caddr (caddr ref)) (caar vars))))) (format *stderr* "possible float-vector-scale: ~A~%" form)))))))) (old-do-walker caller form env)))) |#