Confusing documentation for sref

I’m trying to use sounds as disguised arrays to get Nyquist to do some inner loops for me without Lisp overhead. The docs for sref ought to tell me how to retrieve the nth array element. But the example code uses a function

global-to-local

which does not exist elsewhere in the documentation and which the Nyquist prompt tells me is undefined!

I want to use sref-inverse too to do a fast linear search of a nondecreasing array, but without a proper understanding of the interconversion of array index and sound parameter, i’m getting nowhere, and just relying on my slow Lisp loops.

Yes, this is for the speech segmentation experiments. I have a pleasing tool so far but want to make it faster.

It should of course be written as “local-to-global”.
However, this differenciation is seldom needed within Nyquist for Audacity since local is in most cases also global time.
However, in “sref” the actual Duration has to be considered too (i.e. current length of selection).
You can use snd-sref instead for “absolute” behaviour.

;; we search for the 20th element (index 19) 
;; Sound is a ramp from 0 to 44100
;; High Level
(print (sref 
   (snd-pwl 0 44100 '(0 0.0 44100 44100.0 44101))
   (/ 19  (get-duration *sound-srate*)) ))
;; Low Level
(print (snd-sref 
   (snd-pwl 0 44100 '(0 0.0 44100 44100.0 44101))
   (/ 19  *sound-srate*) ))

Your example depends on the coincidence that sound-srate equals the 44100 used to construct the sounds. This appears to be the correct expression independent of the global variables:

(let*(
 (snd (snd-pwl 0
       ;; vary this:
        44100
       '(0 0.0 44100 44100.0 44101)))
)

 (print (sref snd
         (/ 19 (get-duration (snd-srate snd)))
  ))
 (print (snd-sref snd
         (/ 19 (snd-srate snd))
  ))
)

I can “vary this” to 1 but get 19 for both results.

However my expression still assumes a t0 value of 0.

Vary that as well as the sample rate. This works as expected:

 (print (snd-sref snd
     (+
         (snd-t0 snd)
         (/ 19 (snd-srate snd))
     )
  ))

But I still haven’t figured out the correct way to get sref to return 19 when the start time argument to snd-pwl is not 0. The following is the code in the documentation, corrected, but still not doing what the documentation says it should.

 (sref sound (local-to-global (+ (/ n (snd-srate sound)) (snd-t0 sound))))

Aha, here is a working example.

(let*(
 (snd (snd-pwl
       ;; vary the start time:
       100
       ;; vary the sample rate:
        100
       '(0 0.0 44100 44100.0 44101)))
)

 (print (sref snd
     (*
         (+ (snd-t0 snd) (/ 19 (snd-srate snd)))
         (/ (local-to-global 1))
     )
  ))
 (print (snd-sref snd
     (+ (snd-t0 snd) (/ 19 (snd-srate snd)) )
  ))
)

But the factor (/ (local-to-global 1)) is funny looking and suggests to me the documenter of sref really meant a (non-existent) inverse function to local-to-global.

The Nyquist manual was written for standalone Nyquist, not for Nyquist in Audacity,
In Audacity the environment is different.
If you’re working with effects, the start of the selection is always 0, and the end of the selection is 1 (local time) and returned sounds always start at 0 (regardless of any start time that you may set in Nyquist.
“Global time” only has limited meaning for Nyquist in Audacity because there are no absolute points of reference. In standalone Nyquist you can start a sound at (for example) 3 seconds after “now”, but in Audacity there is no “now”, there is just the start of the sound (which is “time = 0”).

By the way, Your ‘(local-to-global 1)’ is not used properly.
Your time in seconds is divided by the Output of this function - that’s exact the same Output you get with ‘(get-duration 1)’. In other words you simply Stretch the time such that it is measured in absolute time Units (s) and not in multiples of the selection length.
The only difference between ‘get-duration’ and ‘local-to-global’ arises when you Play with Stretch and sustain for behaviours that you might describe.
Additionally, ‘local-to-global’ can be fed with negative values to generate negative time shifts.

I remain incurably ignorant. What I used “improperly” just happens to be the correct correction factor for the badly document sref.

I just want to use sounds as disguised arrays of data. I have the working indexing fomula for snd-sref. Good enough.

But you can’t have a negative start time.

Is there an easy way to reverse a sound?

Not really.
Probably the easiest way, if the sound is not too long, is to read the sound into an array (Snd-fetch-array), then loop through the array and write it in reverse order to a new array, then Snd-from-array.

You an also reverse a Sound with ‘fmos’ and a negative frequency Modulation. Works with chunks of 100000 samples.
By the way, local-to-global with negative time is used in get-duration to control if the Duration is negative.
That causes an error of course. The question arises if negative Durations shouldn’t be appropriate for reversed sounds.
Like ‘(Stretch -1 (osc-note c5))’.
That would be very Handy.

I just discovered that I can speed up the selection very simply with the Nyquist prompt:

(force-srate 44100 (scale-srate s 2))

Or change 2 to 0.5 to slow it.

So what if I try -1?

BAM! Audacity crashes!

:smiley: Not surprising.

If you’re interested you could perhaps look into the problem and see if it is due to Nyquist crashing or Audacity crashing, and perhaps suggest a way to throw an error rather than crash.

Sounds like a C++ debugging job, which I may be competent to do, but not inclined right now.