I have not followed up on your suggestion of implementing a version of AudioBuffer_read but I followed your hint that "AudioBuffer_read_interp (and friends) look like they do".
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; AudioBuffer_read_interp has looping built-in
;; I opened the file "tmp/Tom&Greg_Devil_Deal.wav" in Audacity.app and found
;; starting points (frames) of 7 phrases
;; Laboriously copied the starting point and the length of each spoken phrase.
;; In xtlang I generated two vectors: one with 7 i64 integer starting points and
;; one with 7 i64 phrase lengths.
;; Then I randomly chose one of these starting points and the corresponding
;; phrase length.
;; Using AudioBuffer_set_loop_start and AudioBuffer_set_loop_frames I could
;; repeatedly play the selected phrase.
;; On re-evaluating the dsp:DSP code a different phrase may be selected and will
;; loop until another re-evaluation
(bind-func dsp:DSP
(let ((ab dealWthDevl)
(vStart:|7,i64|* (alloc)) ;; starting points (frames)
(vFrame:|7,i64|* (alloc)) ;; representing loop-lengths (frames)
(array-index (imp_rand1_i64 7))) ;;
(afill! vStart 24073 332207 505532 852183 1283089 1791028 2019721)
(afill! vFrame 308134 175732 187769 334614 286468 113043 247951)
(AudioBuffer_set_phase ab 0.0)
(lambda (in time chan dat)
(AudioBuffer_set_loop_start ab (aref vStart array-index)) ; silent pos
(AudioBuffer_set_loop_frames ab (aref vFrame array-index)) ;; match length
(AudioBuffer_read_interp ab (* 1.0 261.6) chan))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
I have attempted to run a callback loop that re-evaluates the dsp:DSP code at regular intervals without success.
Also attempted to generate the arrays once only outside the dsp:DSP but ran into trouble with bad types.
Would appreciate some help with that.