Plugin to find sample value in unsigned integer

I am new to audacity.I am trying to learn nyquist prompt in audacity to develop a plugin.I want to develop a plugin which will provide the sample values of a given audio in a given time range .What I want is that there should be a button in the UI clicking which provides the sample value of next sample in the range and so on till I require.I want to know is it possible ?? Because what I have searched and saw is that using “;control” we can make the user specify a value or using “control” we can make the user select a value from a drop down kind of menu. So is it possible to make a next button that will let me achieve my target ???

Topic moved to the “Nyquist” board.

No, that’s not possible. Nyquist in Audacity is not interactive.
What you could do is to make a plug-in that stores a value in the special “SCRATCH” variable, then uses that value the next time the plug-in runs.
SCRATCH is documented here: Missing features - Audacity Support

A simple example of using scratch is given below. This example can be run in the Nyquist Prompt effect (Nyquist Prompt - Audacity Manual).

;control reset "Reset to zero" choice "No,Yes" 0
;control val "Add to previous value" int "" 1 1 10

(cond 
  ((= reset 1)
      (when (boundp '*scratch*)
        (setf *scratch* '*unbound*))
      (format nil "Plug-in has been reset."))
  ((boundp '*scratch*)
      (let ((old *scratch*))
        (setf *scratch* (+ *scratch* val))
        (format nil "~a + ~a = ~a" old val *scratch*)))
  (t  (setf *scratch* val)
      (format nil "0 + ~a = ~a" val *scratch*)))

I am trying to make a plugin in which i want to know the sample value of Nth sample.What I want is that the plugin should ask for the value of N and it must display the value of Nth sample .Is it possible to find the value of Nth sample if the audio is not starting from 0 second , means I want to know the value of Nth sample if I select a region ??? What command to use to get the value of Nth sample. I used -

(print (sref s (+ (/ myvalue (snd-srate s)) (snd-t0 s))))

to find the value of Nth sample from start.But the result shown is in dB (probably) and is also not in agreement with the value of samples i have dumped in a text file…Any help in this regard ?? I am stuck to this issue for quite some time now.

Merged topics and moved to Nyquist forum.

Try this:

(abs-env (print (sref *track* (/ sample-number *sound-srate*))))

Note that this uses the “version 4” syntax, so if running in the Nyquist Prompt, ensure that “legacy (version 3) syntax” is NOT selected.
The returned value is 32-bit float, where the linear range is +/- 1.

I suspect that the problem you were running into is due to the way that Nyquist handles time in Audacity.
In “generate” type plug-ins, “local” time is the same as “global” time, where snd-t0 is the start of the selection. Thus 1 second in local time is 1 second in actual (global) time.

In “process” and “analyze” type plug-ins, the default environment is warped such that the length of the selection is 1. Thus 1 second in local time is the length of the selection.

(ABS-ENV behaviour) forces the behaviour to be calculated with actual time values regardless of the type of plug-in.

@steve
Hii steve the command you specified -

(abs-env (print (sref track (/ sample-number sound-srate))))

This command is giving me the sample-number and not its value. Can you help me on this ??

Even after using ABS-ENV the sample value given by my plugin is different from the sample value dumped in a file by using “Sample-data export” Plugin of audacity. Any help in this regard ???
I am stuck to this issue for quite some time now . Can anyone help me how “Sample-data export” Plugin of audacity is calculating sample values.???

Tested with the first 20 samples from a mono 440 Hz Sine tone, amplitude 0.8:

Sample Data Export:

sample-data.txt   1 channel (mono)
Sample Rate: 44100 Hz. Sample values on linear scale.
Length processed: 20 samples 0.00045 seconds.


1	0.00000
2	0.06265
3	0.12505
4	0.18696
5	0.24814
6	0.30834
7	0.36733
8	0.42488
9	0.48075
10	0.53474
11	0.58663
12	0.63622
13	0.68330
14	0.72770
15	0.76924
16	0.80776
17	0.84310
18	0.87514
19	0.90373
20	0.92878

Copied from the Debug output of the Nyquist Prompt (Click the “Debug” button instead of the “OK” button) using this code;

(setf output "")  ;initialize output string
(setf *float-format* "%.5f")  ;output to 5 decimal places

;; Loop 20 times and return output string to debug window
(dotimes (i 20 (format t output))
  (setf output
    (abs-env
      (format nil "~a~%~a ~a"
          output
          (1+ i)
          (sref *track* (/ i *sound-srate*))))))

;Return output string
output

The output:

1 0.00000
2 0.06265
3 0.12505
4 0.18696
5 0.24814
6 0.30834
7 0.36733
8 0.42488
9 0.48075
10 0.53474
11 0.58663
12 0.63622
13 0.68330
14 0.72770
15 0.76924
16 0.80776
17 0.84310
18 0.87514
19 0.90373
20 0.92878

The settings that I used for Sample Data Export:
fullwindow-Sample Data Export-000.png

Here is my Nyquist debug output when I copied and pasted your code(as below) in the Nyquist prompt -

(setf output “”) ;initialize output string
(setf float-format “%.5f”) ;output to 5 decimal places

;; Loop 20 times and return output string to debug window
(dotimes (i 20 (format t output))
(setf output
(abs-env
(format nil “~a~%~a ~a”
output
(1+ i)
(sref track (/ i sound-srate))))))


OUTPUT:(Nyquist prompt debug output)-

error: unbound variable - TRACK
if continued: try evaluating symbol again
Function: #<FSubr-PROGV: #a7f12b0>
Arguments:
(QUOTE (WARP LOUD TRANSPOSE SUSTAIN START STOP CONTROL-SRATE SOUND-SRATE))
(LIST (QUOTE (0.00000 1.00000 NIL)) 0.00000 0.00000 1.00000 MIN-START-TIME MAX-STOP-TIME DEFAULT-CONTROL-SRATE DEFAULT-SOUND-SRATE)
(FORMAT NIL “~a~%~a ~a” OUTPUT (1+ I) (SREF TRACK (/ I SOUND-SRATE)))
Function: #<FSubr-SETF: #a7f4420>
Arguments:
OUTPUT
(ABS-ENV (FORMAT NIL “~a~%~a ~a” OUTPUT (1+ I) (SREF TRACK (/ I SOUND-SRATE))))
Function: #<FSubr-DOTIMES: #a7f2d50>
Arguments:
(I 20 (FORMAT T OUTPUT))
(SETF OUTPUT (ABS-ENV (FORMAT NIL “~a~%~a ~a” OUTPUT (1+ I) (SREF TRACK (/ I SOUND-SRATE)))))
1>




What is the problem according to you now ?? Is there something wrong with my Audacity??

Either you are using an obsolete version of Audacity, or you have “Use legacy (version 3) syntax” selected.

If you are using Audacity 2.1.2, ensure that “Use legacy (version 3) syntax” is not enabled (not selected) in the Nyquist Prompt effect.
If you are using an old version of Audacity, get Audacity 2.1.2 from here: Audacity ® | Downloads

To check the version Audacity number in Windows or Linux, look in “Help > About Audacity”. On a Mac, look in the Audacity menu > About Audacity.

Thanks a lot you were absolutely right. The legacy version 3 was enabled for the nyquist prompt.Now the legacy version 3 is also enabled for the plugins.Please tell me how can I disable it so that I can make a plugin now ???

I got to know how to exclude legacy version 3 syntax in our plugin.We need to have " ;version 4 " in our code to disable legacy version 3 syntax.

Yes, You just need to include the “;version 4” header command and that will tell Audacity to interpret the code as version 4 code. See: Missing features - Audacity Support

Hii Steve I am undergoing a new problem now. My plugin that I developed to display the sample value of selected region using below code -

(abs-env (print (sref *track* (/ samplenumber *sound-srate*))))

The problem is that when I am running this plugin for some other audio file its showing the below thing in DEBUG -

error: bad argument type - #(#<Sound: #5a2d328> #<Sound: #5a2d568>)
Function: #<Subr-SND-SREF: #ab5e068>
Arguments:
  #(#<Sound: #5a2d328> #<Sound: #5a2d568>)
  0.839583
Function: #<Closure-SREF: #ab828e8>
Arguments:
  #(#<Sound: #5a2d328> #<Sound: #5a2d568>)
  0.839583
Function: #<FSubr-PROGV: #ab60068>
Arguments:
  (QUOTE (*WARP* *LOUD* *TRANSPOSE* *SUSTAIN* *START* *STOP* *CONTROL-SRATE* *SOUND-SRATE*))
  (LIST (QUOTE (0 1 NIL)) 0 0 1 MIN-START-TIME MAX-STOP-TIME *DEFAULT-CONTROL-SRATE* *DEFAULT-SOUND-SRATE*)
  (PRINT (SREF *TRACK* (/ SAMPLENUMBER *SOUND-SRATE*)))
1>

What can be the reason for this ??? How can I correct it .

Your code is trying to find the value of a sample in a “sound”, but your trying to apply it to a stereo track.
The data from a stereo track is not one “sound” but an array containing two sounds (one sound for each channel).

To access an element from an array, there’s the command AREF file:///home/steve/Documents/Audacity/Manuals/xlisp/xlisp-ref/xlisp-ref-029.htm

So to access the sound in the left channel of a stereo sound track:

(aref *track* 0)

Can you provide the code to print the value of sample value of a sample using track . I tried a lot but its not working.

I did that here: Plugin to find sample value in unsigned integer - #9 by steve

Actually Steve I got to know how to code when more than one channels are present .
In order to get sample value of Nth sample when more than one channel is present -

  1. (abs-env (print (sref (aref track 0) (/ samplenumber sound-srate))))

The above code will work when more than one channel is present in the track

In order to get sample value of Nth sample when one channel is present -

  1. (abs-env (print (sref track (/ samplenumber sound-srate)))

This code will work when one channel is present in our track

Correct me if I am wrong somewhere. Now I want to know a IF condition so that my code will execute the 1 code statement when more than one channel are present and will execute 2 code statement when one channel is present. This is because I want to write only one plugin that will be generic to all cases. How can I code that IF condition ???