Nyquist Transformation Environment

Using Nyquist scripts in Audacity.
Post and download new plug-ins.

If you require help using Audacity, please post on the forum board relevant to your operating system:
Windows
Mac OS X
GNU/Linux and Unix-like

Re: Nyquist Transformation Environment

Permanent link to this post Posted by steve » Tue May 25, 2010 11:48 pm

edgar-rft wrote:Counter-question: do you know the Vinal Scratch Tutorial? This would be fun to write an Audacity plugin out of it! Or is there already one from David Sky?

I've not seen it as a plug-in, but a direct implementation is probably not that interesting from the standpoint of *warp* related functions. Most of the interesting stuff is in the (fmosc ...) function. It does make some pretty groovy noises though :D (especially if the 'pch' parameter is pushed up quite high)

Code: Select all
;nyquist plug-in
;version 1
;type generate
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
;name "ScratchSynth..."
;action "Generating weird sounds..."
;info "From 'Vinyl Scratch' tutorial.n"

;control lfo "LFO" real "Hz" 1 0.5 440
;control s-length "Length" real "seconds" 5 1 100
;control p "pitch parameter" real "" 1.2 0.5 10

   (defun ring (s-in dur pch scl)
     (let ((modstep1 (hz-to-step (* (step-to-hz pch) (sqrt 2.0))))
           (modstep2 (hz-to-step (* (step-to-hz pch) (sqrt 11.0)))))
       (stretch dur
         (mult
           (env 0.05 0.1 0.2 1 0.6 0.24 1)
           (fmosc pch (mult
                   (pwl 0.07 1800 0.15 1000 0.4 680 0.8 240 1 100 1)
              scl
                        (osc modstep1)
                        (osc modstep2)))))))

(ring  s s-length (hz-to-step lfo) p)


Possibly a more interesting effect, (and this may be more along the lines of what you were thinking), would be an effect that will "scratch" the sound from the Audacity track (as a 'process' effect). It would also be a rather more difficult head scratcher.
David Sky did produce a "TurntableWarp" effect (http://audacityteam.org/download/nyquistplugins ), which would make a good basis for approaching the problem.

Perhaps something like this:
Code: Select all
;nyquist plug-in
;version 1
;type process
;name "Scratchin..."
;action "scrathchin..."
;info "Probably best on a short section.nThis version is for MONO only. To use on stereo tracks, split them firstn(or modify the plug-in).nNOT release quality. Expect to get clicks.nn"
;control dummy "This control does nothing" real "" 1 0 1
; Variable Resample function by Roger B. Dannenberg
(defun variable-resample (steps snd)
; p1 helps convert steps to a ratio
  (let ((p1 (/ (log 2.0) 12)) ratio map)
; pitch ratio
    (setf ratio (s-exp (mult steps p1)))
; map from real-time to sound time
    (setf map (integrate ratio))
(snd-compose snd (force-srate *sound-srate* map))))

(setq dur (get-duration 1))
(force-srate 44100 (stretch-abs 1
(variable-resample
(pwl 0 0 (* dur 0.1) 0 (* dur 0.2) 12 (* dur 0.25) -24 (* dur 0.3) 0 (* dur 0.35) 0 (* dur 0.4) 12  (* dur 0.45) -24 (* dur 0.5) 0 (* dur 0.55) 0 (* dur 0.6) 12 (* dur 0.65) -24 (* dur 0.7) 0 dur)
(sound s))))

and here's a little demo:
Attachments
quiet-storm-before-after.mp3
(536.56 KiB) Downloaded 242 times
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 46973
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Nyquist Transformation Environment

Permanent link to this post Posted by edgar-rft » Wed May 26, 2010 2:07 am

Several hours later the first usable result:

(time-shift-abs OFFSET SOUND &optional WET)

OFFSET - a time offset in positive or negative integer or floating-point seconds
SOUND - a Nyquist sound object
WET - the volume level of the time-shifted sound between 0.0 and 1.0

The TIME-SHIFT-ABS function time-shifts the sound by an offset in seconds. The function can handle positive time-shifts [to the right] as well as negative time-shifts [to the left] where the returned sound has exactly the same length as the input sound. If applied to the sound in an Audacity selection, the function does not change the length of the selection.

The 'wet' parameter is part of the usual 'dry/wet' relationship, where 'wet' is the volume level of the time-shifted sound and 'dry' is the volume level of the original sound. The default for 'wet' is 0.5, what equals to 50% original sound and 50% time-shifted sound. The higher the 'wet' level, the lower the 'dry' level, where the 'dry' level gets computed automatically from the value of the 'wet' level. A 'wet' value of 0.0 or below equals to the original sound only, a 'wet' value of 1.0 or above equals to the time-shifted sound only.

Here is the uncommented code for the Audacity Nyquist prompt:

Code: Select all
(defun time-shift-abs (offset sound &optional (wet 0.5))
  (let ((dur (get-duration 1.0)))
    (if (or (>= offset dur) (<= wet 0.0))
        sound
        (let* ((start  (if (minusp offset) (abs offset) 0.0))
               (end    (if (plusp offset) (- dur offset) dur))
               (offset (max 0.0 offset))
               (wet    (max 0.0 (min 1.0 wet)))
               (dry    (- 1.0 wet)))
          (sum (scale dry sound)
               (scale wet (at-abs offset
                            (cue (extract-abs start end sound)))))))))

Here is an over-commented version of the same code:

Code: Select all
(defun time-shift-abs (offset sound &optional (wet 0.5))
  (let ((dur (get-duration 1.0))
    ;; 'dur' is the duration of the Audacity selection in seconds
    (if (or (>= offset dur) (<= wet 0.0))
        ;; if the time-shifted sound is outside of the Audacity selection
        ;; or if the volume of the time-shifted sound is zero or below
        ;; then we do not need to compute the time-shifted sound
        sound
        ;; otherwise we must compute the complete time-shift
                      ;; if the offset is negative we must
                      ;; cut away samples from the beginning
        (let* ((start (if (minusp offset) (abs offset) 0.0))
                      ;; if the offset is positive we must
                      ;; cut away samples from the end
               (end   (if (plusp offset) (- dur offset) dur))
               ;; the offset must be positive or zero, because
               ;; Nyquist cannot handle negative start-times
               (offset (max 0.0 offset))
               ;; the volume level of the time-shifted sound must
               ;; not be less than zero and not be greater than 1.0
               (wet (max 0.0 (min 1.0 wet)))
               ;; the volume level of the original sound is
               ;; 1.0 minus the volume level of the time-shifted sound
               (dry (- 1.0 wet)))
          (sum (scale dry sound) ; the volume of the original sound
                          ;; shift the sound to the 'offset' in seconds
               (scale wet (at-abs offset
                            ;; we only use the part between 'start' and 'end'
                            (cue (extract-abs start end sound)))))))))

I do not think of this code as 'perfect' or 'finished', I have written it as a basis for further discussion. Maybe it would be useful to set-up a page with screenshots what I did and why. But first I need some sleep now. For today I say good night folks, see you tomorrow...

- edgar
edgar-rft
 
Posts: 347
Joined: Sun Jan 20, 2008 12:03 am
Operating System: Please select

Re: Nyquist Transformation Environment

Permanent link to this post Posted by edgar-rft » Wed May 26, 2010 1:34 pm

Left-overs from yesterday [sorry, it's a bit jumbled, but I didn't want to produce another huge text box]:

steve: Question about *warp*: If you have (osc 60) in a Generate plug-in the *warp* time-stretch value is NOT bound to the length of the Audacity selection, but in a Process plug-in it IS bound to the length of the Audacity selection. Is that right?

edgar: No, the *warp* time-stretch value is ALWAYS bound to the length of the Audacity selection, no matter what type of plugin. The only exception is if you choose a 'generate' plugin from the Audacity 'Generate' menu and there is no Audacity selection, then the plugin creates a new track, where the *warp* time-stretch value is left to the default of 1.0, as defined in 'nyquist.lsp'.

steve: Suggestion: stretching sounds from the Audacity track, something like this:

Code: Select all
(setq dur 2.0)
(force-srate *sound-srate*
  (stretch-abs (/ dur (get-duration 1.0))
    (sound s)))

edgar: Does in principle the same thing as "Audacity->Effect->Change speed". Maybe interesting to document how this works with Nyquist, but does the "Change speed" Effect need to be re-invented again? Or maybe you have another idea where this could be used and I haven't understood the context?

steve: FMOSC makes some pretty groovy noises though...

edgar: FM-synthesis is fun, but also a rather endless topic, we could start another thread about this...

steve: David Sky did produced a "TurntableWarp" effect...

edgar: The Turntable-Warp plugin does in principle the same thing as the Audacity Time-Track. This also does not necessarily to be re-invented again. It would be interesting to find out how Nyquist could be used to create a real "Scratchin" effect, where the sound runs partially backwards, but this would probably need a slow SND-FETCH implementation together with a sample-array buffer because Nyquist cannot compute backwards in time. If anybody is interested in this, please start a new thread...
edgar-rft
 
Posts: 347
Joined: Sun Jan 20, 2008 12:03 am
Operating System: Please select

Re: Nyquist Transformation Environment

Permanent link to this post Posted by steve » Wed May 26, 2010 4:57 pm

edgar-rft wrote:steve: Question about *warp*: If you have (osc 60) in a Generate plug-in the *warp* time-stretch value is NOT bound to the length of the Audacity selection, but in a Process plug-in it IS bound to the length of the Audacity selection. Is that right?

edgar: No, the *warp* time-stretch value is ALWAYS bound to the length of the Audacity selection, no matter what type of plugin. The only exception is if you choose a 'generate' plugin from the Audacity 'Generate' menu and there is no Audacity selection, then the plugin creates a new track, where the *warp* time-stretch value is left to the default of 1.0, as defined in 'nyquist.lsp'.


That's confused me :?
Why is it then that this plug-in always creates a tone of 1 second duration, whether there is a selection or not?

Code: Select all
;nyquist plug-in
;version 1
;type generate
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
;name "Tone Generate..."
;action "Generating Tone..."
;info ""

;control note "Frequency" real "Hz" 440 1 1000

(osc (hz-to-step note))


whereas this plug-in will create a tone of length equal to the selection:
Code: Select all
;nyquist plug-in
;version 1
;type process
;categories "http://lv2plug.in/ns/lv2core#GeneratorPlugin"
;name "Tone Convert..."
;action "Converting to Tone..."
;info ""

;control note "Frequency" real "Hz" 440 1 1000

(osc (hz-to-step note))


edgar-rft wrote:edgar: Does in principle the same thing as "Audacity->Effect->Change speed". Maybe interesting to document how this works with Nyquist, but does the "Change speed" Effect need to be re-invented again? Or maybe you have another idea where this could be used and I haven't understood the context?

I was thinking in terms of more complex effects that need to stretch sounds from the Audacity track, rather than as an effect in its own right. (more of a code snippet than a plug-in).

I like the (time-shift-abs OFFSET SOUND &optional WET) function - a neat solution :)

edgar-rft wrote:edgar: The Turntable-Warp plugin does in principle the same thing as the Audacity Time-Track. This also does not necessarily to be re-invented again.

Except that the Turntabe-warp plug-in does what it says on the tin. I've never been able to get particularly good results with the Time-Track, there always seems to be a good deal of inconsistency between what the time track says should be happening, and what actually is happening to the sound.
Again I was thinking of this more in terms of code snippets - the "Scratchin" plug-in is basically a recycling of the TurntableWarp effect - or more accurately, another application of Rodger Dannenberg's "Variable Resample" function.

I notice that the audio sample has not been downloaded yet, but even without the sound going backward (which as you say would probably need a very slow SND-FETCH implementation) I think it produces a reasonable "scratch" type of effect.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 46973
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Nyquist Transformation Environment

Permanent link to this post Posted by edgar-rft » Wed May 26, 2010 5:52 pm

steve: Why is it then that this plug-in [see above] always creates a tone of 1 second duration, whether there is a selection or not?

edgar: Looking at "audacity/src/effects/nyquist.cpp", function "EffectNyquist::ProcessOne()" I see that with Audacity 'generate' plugins [represented by the INSERT_EFFECT flag] the length of the Audacity track is defined as zero what has to the consequence that in "audacity/lib-src/libnyquits/nyx.c" in the function "nyx_set_audio_params" the values of Nyquist LEN and *warp* time-stretch are also initialized with zero. This is clearly an Audacity bug.

steve: [About time-stretch functions] I was thinking in terms of more complex effects that need to stretch sounds from the Audacity track, rather than as an effect in its own right. (more of a code snippet than a plug-in).

edgar: Question: How should a time-stretch handle the Audacity selection? I'm asking because in multi-track situations it's an crucial issue that a plugin doesn't change the length of the selection. There must be found a way how to tell the function wether changing the selection is allowed or not.

In this context I remember that around Chrismas a problem was that Nyquist plugins changed the length of the selection by +/-1 sample depending on the mouse position. Has this ever been solved?

steve: I notice that the audio sample has not been downloaded yet...

edgar: I had copied the code directly from the screen because I first had to de-mess it:

Code: Select all
;nyquist plug-in
;version 1
;type process
;name "Scratchin..."
;action "scrathchin..."
;info "Probably best on a short section.nThis version is for MONO only. To use on stereo tracks, split them firstn(or modify the plug-in).nNOT release quality. Expect to get clicks.nn"
;control dummy "This control does nothing" real "" 1 0 1

; Variable Resample function by Roger B. Dannenberg
(defun variable-resample (steps snd)
  (let* ((p1 (/ (log 2.0) 12))           ; helps convert steps to a ratio
         (ratio (s-exp (mult steps p1))) ; pitch ratio
         (map (integrate ratio)))        ; map from real-time to sound time
    (snd-compose snd (force-srate *sound-srate* map))))

(let ((dur (get-duration 1)))
  (force-srate 44100 (stretch-abs 1
    (variable-resample
      (pwl 0 0 (* dur 0.1)    0
               (* dur 0.2)   12
               (* dur 0.25) -24
               (* dur 0.3)    0
               (* dur 0.35)   0
               (* dur 0.4)   12
               (* dur 0.45) -24
               (* dur 0.5)    0
               (* dur 0.55)   0
               (* dur 0.6)   12
               (* dur 0.65) -24
               (* dur 0.7)    0  dur)
      (sound s)))))

Have you any idea how a user interface for defining your own PWL breakpoints should look like?
edgar-rft
 
Posts: 347
Joined: Sun Jan 20, 2008 12:03 am
Operating System: Please select

Re: Nyquist Transformation Environment

Permanent link to this post Posted by steve » Wed May 26, 2010 9:36 pm

edgar-rft wrote:... the consequence that .... the values of Nyquist LEN and *warp* time-stretch are also initialized with zero. This is clearly an Audacity bug.

I see how that will explain the behaviour, thanks for the explanation. I don't understand enough about the Audacity source code to be able to work that out myself, so I assumed it was intentional.

I've just tested this in Audacity 1.2.6 and see that (exactly as you described) "the *warp* time-stretch value is ALWAYS bound to the length of the Audacity selection, no matter what type of plugin".

edgar-rft wrote:In this context I remember that around Chrismas a problem was that Nyquist plugins changed the length of the selection by +/-1 sample depending on the mouse position. Has this ever been solved?
There are still some minor peculiarities regarding the first and last samples in the selection, but I think that it has essentially been solved now.

edgar-rft wrote:steve: I notice that the audio sample has not been downloaded yet...

edgar: I had copied the code directly from the screen because I first had to de-mess it:

Hmm yes, sorry about the scrawl, it was rather late at night and I wanted to get it posted before bed. :oops: (though I don't take any responsibility for the layout of the Variable Resample function - I took that straight from here: http://audacityteam.org/nyquist/turntablewarp.ny ;) )

I actually meant the audio sample "quiet-storm-before-after.mp3"

edgar-rft wrote:Have you any idea how a user interface for defining your own PWL breakpoints should look like?

I've been struggling with that question in relation to making an "Envelope" plug-in that is accessible for VIP's (visually impaired persons).
With the current limitations of the Audacity/Nyquist interface, I think it comes down to either a whole lot of sliders (t1,l1,t2,l2...tn,ln), or text input widget.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 46973
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Nyquist Transformation Environment

Permanent link to this post Posted by edgar-rft » Thu May 27, 2010 1:05 pm

stevethefiddle wrote:... though I don't take any responsibility for the layout of the Variable Resample function ...

Yes, I know, I recognize David-Sky-code from miles away. David wrote his code with a stoneage DOS computer with the help of "WordPerfect" [stoneage text processor] macros. Because he was unable see the result on the screen, it always was an "adventure" to read his code. But it had been lots of fun to work with David.

But now unfortunately some bad news:

I'm sorry to tell but it turns out that in the current Auadcity CVS HEAD the length of the sound returned by a Nyquist plugins is still dependent of the mouse pointer position between two samples when the user selects the sound in Audacity, so Nyquist plugins still destroy the the phase coherence of the Audacity track by chance. The returned sound of Nyquist plugins must be considered as unreliable.

To me it makes not much sense to continue the *warp* discussion until this bug is fixed. I have started a new thread:

edgar-rft
 
Posts: 347
Joined: Sun Jan 20, 2008 12:03 am
Operating System: Please select

Re: Nyquist Transformation Environment

Permanent link to this post Posted by steve » Fri May 28, 2010 12:57 pm

Code: Select all
(force-srate 44100 (pwl 1 1 ))

The end of the envelope goes to zero. Is that supposed to happen or is it a bug?

Code: Select all
(control-srate-abs *sound-srate* (pwl 1 1))

The end of the envelope is at 1.0
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)
steve
Site Admin
 
Posts: 46973
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Previous

Return to Nyquist



Who is online

Users browsing this forum: No registered users and 3 guests