Trying to build phase-shifter plug-in using (snd-tapv ....) with no luck.

7 messages Options
Embed this post
Permalink
Dave Storer

Trying to build phase-shifter plug-in using (snd-tapv ....) with no luck.

Reply Threaded More More options
Print post
Permalink

I'm trying to build a simple plug-in which will apply an oscillating phase shift to one channel of a stereo signal.  Both channels of the stereo signal consist of a constant frequency sine wave, the same frequency on each channel.

What I would like is a plug-in which would accept as input the frequency of the input signal, the minimum and maximum phase shift, in degrees, and the modulation frequency of the oscillation.   The plug-in would apply a varying time delay to the signal on one channel, so that its phase changes withing the given limits.

For example, the starting signal is a 1Khz sine wave.   Minimum phase shift is to be 30 degrees, and the maximum 90 degrees, with a modulation frequency of 1 Hz.

To watch the phase shifts, I have a copy of the Goldwave editor running, with its display set to plot the left and right channels on the x and y axes of a graph, essentially displaying a Lissajous figure.  

I've tried several approaches using snd-tapv, but without throwing in a mysterious scale factor, I can't get it to work.

With a 1KHz signal, one period is 0.001 second, so the minimum delay should be 0.083333 x 0.001  (30 degrees is 1/12 of a circle -- 1/12 = 0.083333).  This much works.   The problem is in specifying the scale factor for the low frequency oscillator.   If the fixed delay is set to 60/360 x 0.001, it seems like the scale factor for the lfo should be 30/360 x 0.001, but this gives a barely noticeable oscilation. In order to get the desired phase shift, I have to throw in a fudge-factor, scaling up the lfo as described above by approximately 110.  Different values for the minimum and maximum require different scale factors, and the variations seem to be non-linear.  For example, the same requirements as above, but on a 100Hz signal, requires a fudge-factor of about 35.

Obviously, I'm missing some key understanding of how snd-tapv works.   Can anyone suggest a different approach.

Thanks for any insight you can give me.
Dave Storer


------------------------------------------------------------------------------
Are you an open source citizen? Join us for the Open Source Bridge conference!
Portland, OR, June 17-19. Two days of sessions, one day of unconference: $250.
Need another reason to go? 24-hour hacker lounge. Register today!
http://ad.doubleclick.net/clk;215844324;13503038;v?http://opensourcebridge.org
_______________________________________________
Audacity-nyquist mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/audacity-nyquist
Roger Dannenberg

Re: Trying to build phase-shifter plug-in using (snd-tapv ....) with no luck.

Reply Threaded More More options
Print post
Permalink
I think your calculations are right and it looks like tapv is working as
predicted. Here's what I tried:

(defun test ()
  (vector (hzosc 1000.0)
          (shifter (hzosc 1000.0))))

(defun shifter (s)
  (snd-tapv s (* 0.001 (/ 60.0 360.0)) (mult (* 0.001 (/ 30.0 360.0))
                                             (lfo 1.0)) 0.001))

(play (test))

Viewing this in Audacity, I can see a small phase shift with maximum
shift 1/4 of the way through and minimum at 3/4 as you would expect
since the lfo rises to a peak of 1 after 1/4 cycle and to -1 at 3/4 cycle.
-Roger



Dave Storer wrote:

> I'm trying to build a simple plug-in which will apply an oscillating phase shift to one channel of a stereo signal.  Both channels of the stereo signal consist of a constant frequency sine wave, the same frequency on each channel.
>
> What I would like is a plug-in which would accept as input the frequency of the input signal, the minimum and maximum phase shift, in degrees, and the modulation frequency of the oscillation.   The plug-in would apply a varying time delay to the signal on one channel, so that its phase changes withing the given limits.
>
> For example, the starting signal is a 1Khz sine wave.   Minimum phase shift is to be 30 degrees, and the maximum 90 degrees, with a modulation frequency of 1 Hz.
>
> To watch the phase shifts, I have a copy of the Goldwave editor running, with its display set to plot the left and right channels on the x and y axes of a graph, essentially displaying a Lissajous figure.  
>
> I've tried several approaches using snd-tapv, but without throwing in a mysterious scale factor, I can't get it to work.
>
> With a 1KHz signal, one period is 0.001 second, so the minimum delay should be 0.083333 x 0.001  (30 degrees is 1/12 of a circle -- 1/12 = 0.083333).  This much works.   The problem is in specifying the scale factor for the low frequency oscillator.   If the fixed delay is set to 60/360 x 0.001, it seems like the scale factor for the lfo should be 30/360 x 0.001, but this gives a barely noticeable oscilation. In order to get the desired phase shift, I have to throw in a fudge-factor, scaling up the lfo as described above by approximately 110.  Different values for the minimum and maximum require different scale factors, and the variations seem to be non-linear.  For example, the same requirements as above, but on a 100Hz signal, requires a fudge-factor of about 35.
>
> Obviously, I'm missing some key understanding of how snd-tapv works.   Can anyone suggest a different approach.
>
> Thanks for any insight you can give me.
> Dave Storer
>
>
> ------------------------------------------------------------------------------
> Are you an open source citizen? Join us for the Open Source Bridge conference!
> Portland, OR, June 17-19. Two days of sessions, one day of unconference: $250.
> Need another reason to go? 24-hour hacker lounge. Register today!
> http://ad.doubleclick.net/clk;215844324;13503038;v?http://opensourcebridge.org
> _______________________________________________
> Audacity-nyquist mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/audacity-nyquist
>
>  

------------------------------------------------------------------------------
Are you an open source citizen? Join us for the Open Source Bridge conference!
Portland, OR, June 17-19. Two days of sessions, one day of unconference: $250.
Need another reason to go? 24-hour hacker lounge. Register today!
http://ad.doubleclick.net/clk;215844324;13503038;v?http://opensourcebridge.org
_______________________________________________
Audacity-nyquist mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/audacity-nyquist
Dave Storer

Re: Trying to build phase-shifter plug-in using (snd-tapv ....) with no luck.

Reply Threaded More More options
Print post
Permalink
In reply to this post by Dave Storer

The problem seems to be with the Audacity implementation of Nyquist.  Below is my plug-in which illustrates the problem.  For testing it in Audacity, copy the code below to a file in the Audacity 1.3.7 plug-ins directory called Storer-phaser.ny.
In audacity, create a stereo track 20 seconds long with a 250Hz tone.
Split the left and right channels, select the left channel, and run the plug-in below.   By renaming it with a .lsp extension instead of .ny, and commenting or uncommenting a few lines as noted, you can run the same code in stand-alone Nyquist.   The stand-alone version works, the Audacity one does not.   To make the Audacity version run correctly, set the fudge-factor, called Scale, to 48 and re-run it.  Now it matches closely the stand-alone version's output.  

I don't have access to a development system, so I can't try it in 1.3.8.

Dave

Here's the plug-in code:

;;=======================================
;nyquist plug-in
;version 3
;type process
;categories "GeneratorPlugin"
;name "Test Phase Shifter"
;action "Testing Phaser"
;info "Test harness for tapv"

;control Frequency "Signal Frequency" real "Hz" 1000 0 2000
;control Lfo-freq "LFO Frequency" real "Hz" 1 0.01 20
;control Min-Phase "Minimum Phase" real "Degrees" 0.0 0.0 360.0
;control Max-phase "Maximum Phase" real "Degrees" 0.0 0.0 360.0
;control Scale "Scale LFO" real "fraction" 1.0 0.0 100.0
;control Tone-Length "Tone Length" real "Seconds" 30.0 0.0 100.0

;;;
;;; For Stand-alone Nyquist, uncomment the following six lines.
;;;
;(setf Frequency 250.0)
;(setf Lfo-freq 0.25)
;(setf Min-Phase 45.0)
;(setf Max-phase 135.0)
;(setf Scale 1.0)
;(setf Tone-Length 20.0)
   
(defun my-shifter (s)
      (setf Max-phase (float Max-phase))
      (setf Min-phase (float Min-phase))
      (setf Pd (recip (float Frequency)))
      (setf Pd-x-Pd (/ Pd 360.0))
      (setf Depth (/ (- Max-phase Min-phase) 2.0 ))
      (setf Depth-x-Pd (* Depth Pd-x-Pd))
      (setf Fixed (/ (+ Max-phase Min-phase) 2.0 ))
      (setf Fixed-x-Pd (* Fixed Pd-x-Pd))

      (snd-tapv s Fixed-x-Pd  (mult scale Depth-x-Pd (lfo Lfo-freq Tone-Length *table* 270)) Pd)
)

;;;
;;; For Stand-Alone Nyquist, uncomment the following line and comment out the line marked ;; Audacity-nyquist

;(play (vector (stretch Tone-Length (hzosc Frequency)) (my-shifter (stretch Tone-Length (hzosc Frequency)))))

(my-shifter s)     ;; Audacity-nyquist
;;=======================================

>> Roger Dannenberg wrote:
I think your calculations are right and it looks like tapv is working as
predicted. Here's what I tried:

(defun test ()
  (vector (hzosc 1000.0)
          (shifter (hzosc 1000.0))))

(defun shifter (s)
  (snd-tapv s (* 0.001 (/ 60.0 360.0)) (mult (* 0.001 (/ 30.0 360.0))
                                             (lfo 1.0)) 0.001))

(play (test))

Viewing this in Audacity, I can see a small phase shift with maximum
shift 1/4 of the way through and minimum at 3/4 as you would expect
since the lfo rises to a peak of 1 after 1/4 cycle and to -1 at 3/4 cycle.
-Roger




------------------------------------------------------------------------------
_______________________________________________
Audacity-nyquist mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/audacity-nyquist
David R. Sky

Re: Trying to build phase-shifter plug-in using (snd-tapv ....) with no luck.

Reply Threaded More More options
Print post
Permalink
Hi Dave,

I don't have any comment specifically regarding your question. However,
you may want to know that the 'len' argument in Audacity Nyquist is the
number of samples within :Audacity's selection. So to calculate length in
seconds:

(setf dur (/ len *sound-srate*))

so you don't need that duration edit field.

This was established in Audacity Nyquist ;version 2, so the code will only
work in ;version 2 or later Nyquist plugs.

Good luck

David

--
David R. Sky
http://www.shellworld.net/~davidsky/


On Fri, 26 Jun 2009, Dave Storer wrote:

>
> The problem seems to be with the Audacity implementation of Nyquist.  Below is my plug-in which illustrates the problem.  For testing it in Audacity, copy the code below to a file in the Audacity 1.3.7 plug-ins directory called Storer-phaser.ny.
> In audacity, create a stereo track 20 seconds long with a 250Hz tone.
> Split the left and right channels, select the left channel, and run the plug-in below.   By renaming it with a .lsp extension instead of .ny, and commenting or uncommenting a few lines as noted, you can run the same code in stand-alone Nyquist.   The stand-alone version works, the Audacity one does not.   To make the Audacity version run correctly, set the fudge-factor, called Scale, to 48 and re-run it.  Now it matches closely the stand-alone version's output.
>
> I don't have access to a development system, so I can't try it in 1.3.8.
>
> Dave
>
> Here's the plug-in code:
>
> ;;=======================================
> ;nyquist plug-in
> ;version 3
> ;type process
> ;categories "GeneratorPlugin"
> ;name "Test Phase Shifter"
> ;action "Testing Phaser"
> ;info "Test harness for tapv"
>
> ;control Frequency "Signal Frequency" real "Hz" 1000 0 2000
> ;control Lfo-freq "LFO Frequency" real "Hz" 1 0.01 20
> ;control Min-Phase "Minimum Phase" real "Degrees" 0.0 0.0 360.0
> ;control Max-phase "Maximum Phase" real "Degrees" 0.0 0.0 360.0
> ;control Scale "Scale LFO" real "fraction" 1.0 0.0 100.0
> ;control Tone-Length "Tone Length" real "Seconds" 30.0 0.0 100.0
>
> ;;;
> ;;; For Stand-alone Nyquist, uncomment the following six lines.
> ;;;
> ;(setf Frequency 250.0)
> ;(setf Lfo-freq 0.25)
> ;(setf Min-Phase 45.0)
> ;(setf Max-phase 135.0)
> ;(setf Scale 1.0)
> ;(setf Tone-Length 20.0)
>
> (defun my-shifter (s)
>      (setf Max-phase (float Max-phase))
>      (setf Min-phase (float Min-phase))
>      (setf Pd (recip (float Frequency)))
>      (setf Pd-x-Pd (/ Pd 360.0))
>      (setf Depth (/ (- Max-phase Min-phase) 2.0 ))
>      (setf Depth-x-Pd (* Depth Pd-x-Pd))
>      (setf Fixed (/ (+ Max-phase Min-phase) 2.0 ))
>      (setf Fixed-x-Pd (* Fixed Pd-x-Pd))
>
>      (snd-tapv s Fixed-x-Pd  (mult scale Depth-x-Pd (lfo Lfo-freq Tone-Length *table* 270)) Pd)
> )
>
> ;;;
> ;;; For Stand-Alone Nyquist, uncomment the following line and comment out the line marked ;; Audacity-nyquist
>
> ;(play (vector (stretch Tone-Length (hzosc Frequency)) (my-shifter (stretch Tone-Length (hzosc Frequency)))))
>
> (my-shifter s)     ;; Audacity-nyquist
> ;;=======================================
>
>>> Roger Dannenberg wrote:
> I think your calculations are right and it looks like tapv is working as
> predicted. Here's what I tried:
>
> (defun test ()
>  (vector (hzosc 1000.0)
>          (shifter (hzosc 1000.0))))
>
> (defun shifter (s)
>  (snd-tapv s (* 0.001 (/ 60.0 360.0)) (mult (* 0.001 (/ 30.0 360.0))
>                                             (lfo 1.0)) 0.001))
>
> (play (test))
>
> Viewing this in Audacity, I can see a small phase shift with maximum
> shift 1/4 of the way through and minimum at 3/4 as you would expect
> since the lfo rises to a peak of 1 after 1/4 cycle and to -1 at 3/4 cycle.
> -Roger
>
>
>
>
> ------------------------------------------------------------------------------
> _______________________________________________
> Audacity-nyquist mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/audacity-nyquist
>
>

------------------------------------------------------------------------------
_______________________________________________
Audacity-nyquist mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/audacity-nyquist
Roger Dannenberg

Re: Trying to build phase-shifter plug-in using (snd-tapv ....) with no luck.

Reply Threaded More More options
Print post
Permalink
In reply to this post by Dave Storer
It looks to me like Audacity's version of SND-TAPV does not check the
incoming sound for a scale factor, so in this case it will compute the
wrong answer. I'm not sure why your fix works. In any case, the
standalone nyquist shows a number of changes to the code, apparently to
fix a bug. I think you can wrap the input modulation signal to SND-TAPV
with SND-NORMALIZE, which just forces the multiplication of the scale
factor, and that should work around the problem, which I bet is already
fixed in the latest version Audacity under development.

(What's with scale factors? Nyquist scales signals lazily by just
attaching the scale factor to a data structure used to access the sound.
Many times, scale factors can be "factored out" of the inner loops,
which makes scaling, a very common operation with signals, free in many
cases.)

-Roger


Dave Storer wrote:
> The problem seems to be with the Audacity implementation of Nyquist.  Below is my plug-in which illustrates the problem.  For testing it in Audacity, copy the code below to a file in the Audacity 1.3.7 plug-ins directory called Storer-phaser.ny.
> In audacity, create a stereo track 20 seconds long with a 250Hz tone.
> Split the left and right channels, select the left channel, and run the plug-in below.   By renaming it with a .lsp extension instead of .ny, and commenting or uncommenting a few lines as noted, you can run the same code in stand-alone Nyquist.   The stand-alone version works, the Audacity one does not.   To make the Audacity version run correctly, set the fudge-factor, called Scale, to 48 and re-run it.  Now it matches closely the stand-alone version's output.  
>
> I don't have access to a development system, so I can't try it in 1.3.8.
>
> Dave
>
>  

------------------------------------------------------------------------------
_______________________________________________
Audacity-nyquist mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/audacity-nyquist
Dave Storer

Re: Trying to build phase-shifter plug-in using (snd-tapv ....) with no luck.

Reply Threaded More More options
Print post
Permalink
In reply to this post by Dave Storer

Unfortunately, using (snd-tapv (snd-normalize s) ....)  did not work.  The results were the same as without the snd-normalize.

Do you have any other suggestions?

Also, Thanks, David Sky for the information on the len variable which is the number of samples in the selected sound.  I did not know about that -- did I miss it in the Audacity-Nyquist manual or is it not in the manual yet?

Dave

Roger Dannenberg wrote:
It looks to me like Audacity's version of SND-TAPV does not check the incoming sound for a scale factor, so in this case it will compute the wrong answer. I'm not sure why your fix works. In any case, the standalone nyquist shows a number of changes to the code, apparently to fix a bug. I think you can wrap the input modulation signal to SND-TAPV with SND-NORMALIZE, which just forces the multiplication of the scale factor, and that should work around the problem, which I bet is already fixed in the latest version Audacity under development.

(What's with scale factors? Nyquist scales signals lazily by just attaching the scale factor to a data structure used to access the sound. Many times, scale factors can be "factored out" of the inner loops, which makes scaling, a very common operation with signals, free in many cases.)

-Roger


------------------------------------------------------------------------------
_______________________________________________
Audacity-nyquist mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/audacity-nyquist
David R. Sky

Re: Trying to build phase-shifter plug-in using (snd-tapv ....) with no luck.

Reply Threaded More More options
Print post
Permalink
Hi Dave,

I have documented several such Nyquist in Audacity items on my website in
this link:

http://www.shellworld.net/~davidsky/ny-help.htm

I've written about the len argument in the ;version 2 section.

It's possible that Edgar Franke might have also documented such pointers,
his website is listed somewhere in the Nyquist section of my site, or in
the Nyquist section of my links page:

http://www.shellworld.net/~davidsky/links.htm#nyquist

David

--
David R. Sky
http://www.shellworld.net/~davidsky/


On Sat, 27 Jun 2009, [hidden email] wrote:

>
> Unfortunately, using (snd-tapv (snd-normalize s) ....)  did not work.  The results were the same as without the snd-normalize.
>
> Do you have any other suggestions?
>
> Also, Thanks, David Sky for the information on the len variable which is the number of samples in the selected sound.  I did not know about that -- did I miss it in the Audacity-Nyquist manual or is it not in the manual yet?
>
> Dave
>
> Roger Dannenberg wrote:
> It looks to me like Audacity's version of SND-TAPV does not check the incoming sound for a scale factor, so in this case it will compute the wrong answer. I'm not sure why your fix works. In any case, the standalone nyquist shows a number of changes to the code, apparently to fix a bug. I think you can wrap the input modulation signal to SND-TAPV with SND-NORMALIZE, which just forces the multiplication of the scale factor, and that should work around the problem, which I bet is already fixed in the latest version Audacity under development.
>
> (What's with scale factors? Nyquist scales signals lazily by just attaching the scale factor to a data structure used to access the sound. Many times, scale factors can be "factored out" of the inner loops, which makes scaling, a very common operation with signals, free in many cases.)
>
> -Roger
>
>
> ------------------------------------------------------------------------------
> _______________________________________________
> Audacity-nyquist mailing list
> [hidden email]
> https://lists.sourceforge.net/lists/listinfo/audacity-nyquist
>
>
------------------------------------------------------------------------------

_______________________________________________
Audacity-nyquist mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/audacity-nyquist