Author |
Message |
mosc
Site Admin
Joined: Jan 31, 2003 Posts: 18198 Location: Durham, NC
Audio files: 213
G2 patch files: 60
|
Posted: Fri Jul 17, 2009 10:45 am Post subject:
How to build a Frequency Shifter? |
|
|
In another topic about binaural sync, http://electro-music.com/forum/topic-35640.html , the question came up about using Chuck to make a frequency shifter. I understand from Inventor that there is a built in for PitShift, but that is probably not a frequency shifter. Pitch shifters generally transpose the input, up or down, but frequency shifters shift the frequencies algebraically. What is needed is a balanced modulator where the up and down sidebands are available separately.
Any ideas? _________________ --Howard
my music and other stuff Last edited by mosc on Fri Jul 17, 2009 11:40 am; edited 1 time in total |
|
Back to top
|
|
|
blue hell
Site Admin
Joined: Apr 03, 2004 Posts: 24085 Location: The Netherlands, Enschede
Audio files: 278
G2 patch files: 320
|
Posted: Fri Jul 17, 2009 10:50 am Post subject:
|
|
|
What Les also said there that the chuck one was based upon a delay line, so likely with a write pointer and a read pointer running at different speeds, and so indeed a resampling pitch shifter.
What would be needed is the Bode frequency shifter, there is a description here (moog patents). _________________ Jan
also .. could someone please turn down the thermostat a bit.
|
|
Back to top
|
|
|
mosc
Site Admin
Joined: Jan 31, 2003 Posts: 18198 Location: Durham, NC
Audio files: 213
G2 patch files: 60
|
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
Posted: Fri Jul 17, 2009 1:06 pm Post subject:
|
|
|
Here is a comment from the author of the excellent web page that Blue Hell cited, describing the difference between ChucK's PitShift and what we want to create for mosc:
Quote: | It's important to note that this effect is a frequency shift and not the pitch shift effect currently available in modern digital effects boxes. In a frequency shifter all frequency components of the input signal are offset by a specific number of Hz while in a pitch shifter all frequency components are multiplied by a specific factor. The former sounds something like a ring modulator while the latter sound something like playing back a tape at a different speed. |
If I understand it right, we don't want to make the sound of a tape being played back at a different speed, which is what ChucK does with the PitShift UGen. Rather, we want to make the sound of an RF modulator with the upper and lower sidebands available as separate outputs. _________________ "Let's make noise for peace." - Kijjaz |
|
Back to top
|
|
|
Kassen
Janitor
Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Fri Jul 17, 2009 1:11 pm Post subject:
|
|
|
Hmmmm, would it do to take a Fourier transform, shift the data in the resultant array and take the inverse Fourier of that? Admittedly it's a bit on the crude side but it's easy
A real Bode shifter should be possible as well but i'd have to read up on how those worked, again. _________________ Kassen |
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
Posted: Fri Jul 17, 2009 1:57 pm Post subject:
|
|
|
Kassen, that would indeed be a crude yet effective way to do it, however in the other thread mosc mentioned that he needed a high recording sample rate to capture the nuances of the binaural effect. Something like a 1024 sample FFT, which is what's typically practical from a CPU usage standpoint, would be too crude. I think we should look at using ChucK to implement the Moog frequency shifter or some ChucKian simplification of it. _________________ "Let's make noise for peace." - Kijjaz |
|
Back to top
|
|
|
TGV
Joined: Jul 03, 2009 Posts: 23 Location: Utrecht, The Netherlands
|
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
Posted: Sat Jul 18, 2009 1:30 am Post subject:
|
|
|
I found an excellent web page on the topic here:
http://www.cim.mcgill.ca/~clark/nordmodularbook/nm_spectrum_shift.html
The block diagram for the frequency shifter is shown below. This seems to be a very clean and simple design that is easily implemented in ChucK. In fact, I did so, also posted below.
Change the fdelta parameter to vary the amount of frequency shifting, and change the f1 parameter to vary the carrier frequency. Also the lpf cutoff and maybe it's Q can be mucked with if desired.
The ChucK docs do not clearly state how phase is represented. Is it a variable from 0 to 1 or from 0 to 2*pi? I implemented the phase shift of the cosine oscillator as 0.25, being 1/4 of a 0 to 1 phase shift. Kas or someone could you clarify this detail?
mosc, if you test this and it seems to work, then I'll put it in a class wrapper and make two of them, one for the left channel and the other for the right. Then we'll have our ChucKian binaural encoder, I believe.
Les
Description: |
Frequency Shifter Block Diagram |
|
Filesize: |
25.01 KB |
Viewed: |
43806 Time(s) |
|
Description: |
|
Download |
Filename: |
FrequencyShifter1.ck |
Filesize: |
793 Bytes |
Downloaded: |
741 Time(s) |
_________________ "Let's make noise for peace." - Kijjaz |
|
Back to top
|
|
|
blue hell
Site Admin
Joined: Apr 03, 2004 Posts: 24085 Location: The Netherlands, Enschede
Audio files: 278
G2 patch files: 320
|
Posted: Sat Jul 18, 2009 6:15 am Post subject:
|
|
|
Ah Jim Clarck's site, of course
Inventor wrote: | [...]make two of them, one for the left channel and the other for the right. Then we'll have our ChucKian binaural encoder, I believe. |
The one on the G2 has two outputs, one output for an upshifted frequency and one for a downshifted frequency. Looking at the schematic that may just be the two points before the final summation, but I'm not sure there. Anyway, the way it's being used by me usually is that the up-shifted out goes to one channel and the downshifted down to the other channel, that way it makes some (moving) pseudo stereo from a mono signal (using a small frequency shift, less than 1 Hz typically). I've not seen Howard's patch, but I think that is what he did too. _________________ Jan
also .. could someone please turn down the thermostat a bit.
|
|
Back to top
|
|
|
blue hell
Site Admin
Joined: Apr 03, 2004 Posts: 24085 Location: The Netherlands, Enschede
Audio files: 278
G2 patch files: 320
|
Posted: Sat Jul 18, 2009 7:09 am Post subject:
|
|
|
Hmm .. that seems wrong ...
the low pas filters in the schematic above would cause the upper side bands of the first mix to be filtered out, I assume, at least when I calculate with that the output frequency would be shifted by the difference between f1 and f2, thus yielding only one shifted output.
I dont however see that it would shift by the absolute value of the difference, I just get :
fout = fin + f2 - f1
provided that the low pass filtering is perfect. Which means that a pretty high frequency should be used for both f1 and f2, but also that when f1 is smaller than f2 an upshift would occur.
Code: |
sin( fin) * sin( f1) = ( cos( fin - f1) - cos( fin + f1)) / 2 = P
sin( fin) * cos( f1) = ( sin( fin + f2) + sin( fin - f1)) / 2 = Q
perfectly low pass filtering these gives
R = lpf( P) = cos( fin - f1) / 2
S = lpf( Q) = sin( fin - f1) / 2
then the 2nd mixer gives us :
sin( f2) * R = ( sin( f2 + fin - f1) + sin( f2 + f1 - fin)) / 4 = T
cos( f2) * S = ( sin( f2 + fin - f1) - sin( f2 + f1 - fin)) / 4 = U
now T + U = sin( fin + f2 - f1) / 2 = sin( fout) / 2
so fout = fin + f2 - f1
|
_________________ Jan
also .. could someone please turn down the thermostat a bit.
|
|
Back to top
|
|
|
Kassen
Janitor
Joined: Jul 06, 2004 Posts: 7678 Location: The Hague, NL
G2 patch files: 3
|
Posted: Sat Jul 18, 2009 9:42 am Post subject:
|
|
|
Inventor wrote: |
The ChucK docs do not clearly state how phase is represented. Is it a variable from 0 to 1 or from 0 to 2*pi? I implemented the phase shift of the cosine oscillator as 0.25, being 1/4 of a 0 to 1 phase shift. Kas or someone could you clarify this detail?
|
Yes, phase ranges from 0 to 1. This is related to Phasor being the base-case for the (plain) oscillators, in the case of Phasor the literal output and it's phase are the same. This may be related to how Phasor refuses to react to plusewith settings, like the docs claim it should. It makes little sense to talk about pi in the case of -say- a SqrOsc. SinOsc, btw, is a exception in the source but still treats phase as a number from 0 to 1. _________________ Kassen |
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
|
Back to top
|
|
|
blue hell
Site Admin
Joined: Apr 03, 2004 Posts: 24085 Location: The Netherlands, Enschede
Audio files: 278
G2 patch files: 320
|
Posted: Sun Jul 19, 2009 5:30 am Post subject:
|
|
|
Maybe there is an issue with negative frequencies ... sin(-x) would be -sin(x) (for positive x) but cos(-x) would be cos(x) _________________ Jan
also .. could someone please turn down the thermostat a bit.
|
|
Back to top
|
|
|
puretube
Joined: Mar 07, 2006 Posts: 2 Location: germany
|
Posted: Tue Oct 13, 2009 12:47 am Post subject:
|
|
|
For shifting down, you need to subtract the 2 mixers outputs
instead of adding them...
(i.e. instead of the sum, you need the difference...) |
|
Back to top
|
|
|
blue hell
Site Admin
Joined: Apr 03, 2004 Posts: 24085 Location: The Netherlands, Enschede
Audio files: 278
G2 patch files: 320
|
Posted: Tue Oct 13, 2009 12:01 pm Post subject:
|
|
|
Interesting ... and
then we get
Code: |
sin( f2) * R = ( sin( f2 + fin - f1) + sin( f2 + f1 - fin)) / 4 = T
cos( f2) * S = ( sin( f2 + fin - f1) - sin( f2 + f1 - fin)) / 4 = U
and - U = ( - sin( f2 - fin - f1) + sin( f2 + f1 - fin)) / 4
now T + ( - U) = sin( f2 + f1 - fin) / 2 = sin( fout) / 2
so fout = f2 + f1 - fin
|
So fout gets smaller when fin goes up in this case.
Can't really experiment right now ... Les you still here? _________________ Jan
also .. could someone please turn down the thermostat a bit.
|
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
Posted: Tue Oct 13, 2009 1:59 pm Post subject:
|
|
|
Hi Jan, I'll try to make time to test it out.
Les _________________ "Let's make noise for peace." - Kijjaz |
|
Back to top
|
|
|
Inventor
Stream Operator
Joined: Oct 13, 2007 Posts: 6221 Location: near Austin, Tx, USA
Audio files: 267
|
|
Back to top
|
|
|
blue hell
Site Admin
Joined: Apr 03, 2004 Posts: 24085 Location: The Netherlands, Enschede
Audio files: 278
G2 patch files: 320
|
Posted: Tue Oct 13, 2009 2:39 pm Post subject:
|
|
|
I think you'll need pretty high frequencies ... the carrier tones should be filtered out by the filters for it to work. _________________ Jan
also .. could someone please turn down the thermostat a bit.
|
|
Back to top
|
|
|
puretube
Joined: Mar 07, 2006 Posts: 2 Location: germany
|
Posted: Wed Oct 14, 2009 12:59 am Post subject:
|
|
|
(scratch head...)
Somehow I had fig.3 of the Bode patent in mind...
In the ChucK-case this would probably end up inverting the sin(f2 t) of the second oscillator to minus sin(f2 t), (i.e. turned around by 180°),
and then adding the 2 mixed signals at the output again, like before?
Sorry if I mixed things up and spread confusion...
Ahh, and thanx for the welcome:
Scott Stites, whom I had the honour to send a few TDA1022s a few years ago, brought my attention here from http://www.diystompboxes.com/smfforum/forums.html... |
|
Back to top
|
|
|
Scott Stites
Janitor
Joined: Dec 23, 2005 Posts: 4127 Location: Mount Hope, KS USA
Audio files: 96
|
Posted: Sat Oct 17, 2009 5:54 pm Post subject:
|
|
|
OMG!!! Ton?
verily!!!
It's fantastic to see you here! _________________ My Site |
|
Back to top
|
|
|
mosc
Site Admin
Joined: Jan 31, 2003 Posts: 18198 Location: Durham, NC
Audio files: 213
G2 patch files: 60
|
Posted: Mon Oct 19, 2009 8:43 pm Post subject:
|
|
|
I read somewhere, but didn't bother to make a bookmark, that the best way to do a freq shifter in digital is using a Hilbert transform so you don't need dome filters. I was hopeful someone would know a bit more about this. _________________ --Howard
my music and other stuff |
|
Back to top
|
|
|
blue hell
Site Admin
Joined: Apr 03, 2004 Posts: 24085 Location: The Netherlands, Enschede
Audio files: 278
G2 patch files: 320
|
|
Back to top
|
|
|
blue hell
Site Admin
Joined: Apr 03, 2004 Posts: 24085 Location: The Netherlands, Enschede
Audio files: 278
G2 patch files: 320
|
Posted: Sun Oct 12, 2014 4:06 pm Post subject:
|
|
|
Okay .. seems to basically work ... copied from Steve's code
Code: | { ========
TModFreqShifter = class( TMod)
// https://github.com/swh/ladspa/blob/master/bode_shifter_1431.xml
private
FShift : TSignal;
FDelay : array[ 0 .. 255] of TSignal;
FDPtr : Integer;
FPhi : TSignal;
FLastShift : TSignal;
public
}
const
freqshifter_in = 0;
freqshifter_shift = 1;
freqshifter_up = 0;
freqshifter_down = 1;
XCoeffs : array[ 0 .. 99] of TSignal = (
+0.0008103736, +0.0008457886, +0.0009017196, +0.0009793364,
+0.0010798341, +0.0012044365, +0.0013544008, +0.0015310235,
+0.0017356466, +0.0019696659, +0.0022345404, +0.0025318040,
+0.0028630784, +0.0032300896, +0.0036346867, +0.0040788644,
+0.0045647903, +0.0050948365, +0.0056716186, +0.0062980419,
+0.0069773575, +0.0077132300, +0.0085098208, +0.0093718901,
+0.0103049226, +0.0113152847, +0.0124104218, +0.0135991079,
+0.0148917649, +0.0163008758, +0.0178415242, +0.0195321089,
+0.0213953037, +0.0234593652, +0.0257599469, +0.0283426636,
+0.0312667947, +0.0346107648, +0.0384804823, +0.0430224431,
+0.0484451086, +0.0550553725, +0.0633242001, +0.0740128560,
+0.0884368322, +0.1090816773, +0.1412745301, +0.1988673273,
+0.3326528346, +0.9997730178, -0.9997730178, -0.3326528346,
-0.1988673273, -0.1412745301, -0.1090816773, -0.0884368322,
-0.0740128560, -0.0633242001, -0.0550553725, -0.0484451086,
-0.0430224431, -0.0384804823, -0.0346107648, -0.0312667947,
-0.0283426636, -0.0257599469, -0.0234593652, -0.0213953037,
-0.0195321089, -0.0178415242, -0.0163008758, -0.0148917649,
-0.0135991079, -0.0124104218, -0.0113152847, -0.0103049226,
-0.0093718901, -0.0085098208, -0.0077132300, -0.0069773575,
-0.0062980419, -0.0056716186, -0.0050948365, -0.0045647903,
-0.0040788644, -0.0036346867, -0.0032300896, -0.0028630784,
-0.0025318040, -0.0022345404, -0.0019696659, -0.0017356466,
-0.0015310235, -0.0013544008, -0.0012044365, -0.0010798341,
-0.0009793364, -0.0009017196, -0.0008457886, -0.0008103736
);
procedure TModFreqShifter.SetDefaults; // override;
begin
FDezipperMap := [
freqshifter_shift
];
end;
procedure TModFreqShifter.DoTick; // override;
var
i : Integer;
hilb : TSignal;
rm1 : TSignal;
rm2 : TSignal;
shift_i : TSignal;
shift_c : TSignal;
freq_fix : TSignal;
sinval : TSignal;
cosval : TSignal;
begin
FShift := LookupFrequency( FInputs[ freqshifter_shift]);
shift_i := FLastShift;
shift_c := Clip( FShift, 0.0, 10000.0);
freq_fix := 2 * PI / System_Rate;
FDelay[ FDPtr] := FInputs[ freqshifter_in];
hilb := 0.0;
for i := Low( XCoeffs) to High( XCoeffs)
do hilb := hilb + XCoeffs[ i] * FDelay[ ( FDPtr - 2 * i) and ( 255)];
SinCos( FPhi, sinval, cosval);
rm1 := hilb * 0.63661978 * sinval;
rm2 := FDelay[ ( FDPtr - 99) and 255] * cosval;
FOutputs[ freqshifter_down] := ( rm2 - rm1) * 0.5;
FOutputs[ freqshifter_up ] := ( rm2 + rm1) * 0.5;
FDPtr := ( FDPtr + 1) and 255;
FPhi := FPhi + shift_i * freq_fix;
while FPhi > 2 * PI
do FPhi := FPhi - 2 * PI;
FLastShift := shift_c;
end;
function TModFreqShifter.InputName( anIndex: Integer): string; // override;
begin
case anIndex of
freqshifter_in : Result := 'in';
freqshifter_shift : Result := 'shift';
else Result := NO_INPUT;
end;
end;
function TModFreqShifter.OutputName( anIndex: Integer): string; // override;
begin
case anIndex of
freqshifter_up : Result := 'up';
freqshifter_down : Result := 'down';
else Result := NO_OUTPUT;
end;
end;
|
_________________ Jan
also .. could someone please turn down the thermostat a bit.
|
|
Back to top
|
|
|
|