Track sampling rate question.

In Audacity 1.3.7 on Windows, I import a 10 second 8000Hz sound file then (rms s 62.5 128) and this shows on the track incorrectly as a dramatically shortened (about 0.1 second) signal.
I have to VIEW → “Fit In Window” to see the new signal but the time scale is wrong. I think I’m doing my RMS right but it seems that the new sampling rate of 62.5 is being mapped onto the tracks 8000 sample rate by sample to sample in succession. If so then how do I change the tracks rate so this new signal appears correctly?

I had to read this twice - this is about Nyquist isn’t it.

(rms sound [rate window-size])
Computes the RMS of sound using a square window of size window-size. The result has a sample rate of rate. The default value of rate is 100 Hz, and the default window size is 1/rate seconds (converted to samples). The rate is a FLONUM and window-size is a FIXNUM.

So, yes, the audio is being resampled to 62.5 with your code. To keep the sample rate at 8000 Hz the code should be

(rms s 8000 128)

Except that the function “rms” does not seem to work in Audacity 1.3.7 (Nyquist has been updated in Audacity 1.3.8 alpha, and it works in that), but you can use “snd-avg” instead.
Something like this should work:

(snd-resample (snd-avg (snd-abs s) 128 128 OP-AVERAGE) 8000)

Depending on what you are doing it may not be necessary to resample the sound. For example, if you are wanting to use the rms value to modulate a tone you could do it like this:

(mult (hzosc 1000) (snd-avg (snd-abs s) 128 128 OP-AVERAGE))

Hi again Steve.

No I do not want successive square windows positioned so they overlap. I may be wrong but my understanding is that window overlapping is not always done for energy estimates of a waveform and if overlap is done then there are many different degrees of possible overlap. For instance, a speech that’s sampled at 16 kHz, may have a frame size for analysis that’s 20 ms (320 samples) and frames are analyzed every 10 ms. So typically the RMS signal has a lower sampling rate than the input signal but it’s not a shorter signal.

The “fix” to RMS is that the (round …) function is missing in 1.3.7.
Here is what’s needed:

;; Audacity 1.3.7 doesn’t have the (round …) function that (rms …) needs.
;; So add the following “round” to the beginning of your Audacity code.
;; This “round” was taken from the stand alone version of Nyquist.
;; ROUND – rounds a floating point number.
(defun round (x)
((> x 0) (truncate (+ x 0.5)))
((= (- x 0.5) (truncate (- x 0.5))) (truncate x))
(t (truncate (- x 0.5)))

So far, all I need is a way to display the new track of the signal energy without having to manually “Fit-to-window” for an expansion of the time axis. I can see why Audacity may not be able to create tracks that aren’t at sampling rates shown in Audacity’s drop down menu. After all, it’s not a graphing program but an audio editor. I guess I’ll have to fudge it a bit just for display reasons with some Nyquist function.


Ah yes, that does nicely, thanks. You can add it to the "nyquist.lisp file so that it is always available and you can use

(resample (rms s) *sound-srate*)

Yes, and that’s where the slightly more complex (snd-avg …) comes in as it provides much greater control of how you select your windows - the “stepsize” and “blocksize” parameters allow you to specify not only the window size, but their spacing too, whereas (rms …) is specifically for square windows.

It’s shorter because it is at a much lower sample rate. Taking into account the difference in sample rate it is the same length.

All you need to do is to change it’s sample rate back to the same sample rate of the track and it will be the same length as the original track. You can do that with either (force-srate …) or (resample …)

It can. The sampling rate in Nyquist can be anything you like, but when the sound is returned to the track it has to fit into the sampling rate of the track. So for example, if you have a 1 second sound with a sample rate of 80 Hz, then there will be 80 samples. If you then put those 80 samples into a track which is set to a sampling rate of 8000 Hz, then the sound will now play in 0.01 seconds. The sound hasn’t changed, it is simply playing back 100 times too fast because the track is set to a sample rate 100 times greater. The thing that you can’t do with Nyquist is to change the sample rate of the track as this is outside of Nyquist.

I’m not sure why you’re saying the Nyquist RMS function doesn’t have as much control with overlapping square windows. The RMS code below is based on (sng-avg …OP-AVERAGE) and it seems like one can set it’s step and block size via RMS’s interface in anyway one likes.

;; RMS -- compute the RMS of a sound
(defun rms (s &optional (rate 100.0) window-size)
  (let (rslt step-size)
    (setf step-size (round (/ (snd-srate s) rate)))
    (cond ((null window-size)
               (setf window-size step-size)))
    (setf s (prod s s))
    (setf result (snd-avg s window-size step-size OP-AVERAGE))
        ;; compute square root of average
        (s-exp (scale 0.5 (s-log result)))))

Yup, it’s shorter in the sense of less samples but I thought the duration should be the same hence my question about how Audacity is displaying things. I need to think about this some more and look at the code again.

From Nyquist, can I create another track of the appropriate sample rate for the signals energy and make it show up below the original signals track? If so how?

Thanks Steve.


Yes you can do pretty much anything you like if you hack the Nyquist function code, but I was refering to using the standard (rms …) function in a Nyquist script, not modifying Nyquist.

No, not directly. As soon as the data is passed from Nyquist into Audacity, Audacity takes over and Nyquist has no control. If the data is being returned to an existing track (such as when using a “process” type plug-in) the sample rate of the existing track is outside of Nyquist’s control and can not be changed. When using a “generate” type plug-in Audacity creates a new track according to the current project rate.

The interface between Audacity and Nyquist is a pretty simple one. One variable (“s”) passes data from Audacity to Nyquist, and if a sound results from the Nyquist script it is passed back to the track that was being processed. In the case of “generate” plug-ins Audacity will produce a mono track to accommodate the returned sound if no track is selected, but will only produce one track with one channel, so only mono sounds can be generated unless a stereo track already exists and is selected.

A possible workaround:

Let’s say that you want to process a 10 second sound that has a sample rate of 8kHz (the track sample rate is 8000 Hz), and the returned (processed) sound has a sample rate of 80 Hz. The original sound has 80,000 samples. The returned sound has 800 samples, but because it is going into a track which has the sample rate set to 8kHz, the duration will be shortened to 0.1 seconds. So what you need to do to see the returned sound as 10 seconds duration is to change the track sample rate to match the new sample rate (in this case 80Hz).
To do this, click on the name of the track and from the drop down menu click on “Set Rate… > Other” then enter 80 as the new sample rate for the track. The track will magically jump back to 10 seconds duration, with the same 800 samples.

Yes, I see. You mean using (rms…) in ways so it will be viewed at the rate of the original signals track. I agree it’s a limitation on the use of (rms …) within Audacity in that sense but it’s not a limitation of the code itself. So what you’ve said next about the “generate” plug-ins and a workaround is very helpful in enlarging the range of uses for (rms…) in Audacity. Many thanks on this Steve.

Do you happen to have more information on the “generate plug-ins”?

This was my starting place for learning about Nyquist: Nyquist

Virtually all the other information that I have found has come from following links from this page, then links from those pages.

That’s not going to produce the same thing as the rms function, though, is it?

Wow, this is resurrecting an old thread :slight_smile:

No, I don’t think it does.
It should have been

(snd-sqrt (snd-avg (mult s s) window-size step-size OP-AVERAGE))

so for the equivalent of (rms s) you would have:

(snd-sqrt (snd-avg (mult s s)(round (/ *sound-srate* 100))(round (/ *sound-srate* 100)) OP-AVERAGE))

Where did you find this code?

mszlazak has not posted on the forum for over a year.