Forums > MaxMSP

Aliasing problems with FM

August 27, 2007 | 10:39 pm

Hi,

I’m building my own FM synth based on the features of the FM7/8. I have to say everything is working out pretty well so far except for one little thing.

I also use other waveforms like tri~, rect~ and saw~ for modulation besides cycle~. These, however generate serious aliasing problems due to the many sidebands they generate when used for modulation.

I tried to avoid this by placing a brickwall lowpass filter before the dac~. As the basis I used the MSP tutorial dealing about filtering with pfft~. I used an < ~22050 object and a gate~ to filter out bin center frequencies above 22050 Hz.

I’m not completely sure why this doen’t work. Is it maybe because the bin center frequencies only represent the original carrier frequency and do not account for any possible sidebands due to modulation, or am I talking crazy now?

I really hope someone can explain this to me


August 27, 2007 | 10:55 pm

On Aug 27, 2007, at 4:39 PM, Michael Dzjaparidze wrote:
>
> I’m building my own FM synth based on the features of the FM7/8. I
> have to say everything is working out pretty well so far except for
> one little thing.
>
> I also use other waveforms like tri~, rect~ and saw~ for modulation
> besides cycle~. These, however generate serious aliasing problems
> due to the many sidebands they generate when used for modulation.
There are relatively easy formulas for determining the highest
sideband with significant energy, given the Fc, Fm & mod index
(assuming sine waves for M & C). Try googling for FM synthesis
tutorials.

>
> I tried to avoid this by placing a brickwall lowpass filter before
> the dac~. As the basis I used the MSP tutorial dealing about
> filtering with pfft~. I used an < ~22050 object and a gate~ to
> filter out bin center frequencies above 22050 Hz.
>
> I’m not completely sure why this doen’t work. Is it maybe because
> the bin center frequencies only represent the original carrier
> frequency and do not account for any possible sidebands due to
> modulation, or am I talking crazy now?
A filter will only remove things above the cut off – but aliasing
produces ‘foldover’ which places the aliased frequencies back down
below the Nyquist frequency. In other words, filters will not remove
aliasing once it has been created – the only way to get rid of it is
to avoid it in the first place.

>
> I really hope someone can explain this to me
Hope this helps – or at least gives you an idea where to look for
more info.

—-
Steven M. Miller
Professor, Contemporary Music Program
College of Santa Fe

Home < http://pubweb.csf.edu/~smill>
SFIFEM <
http://sfifem.csf.edu>
Atrium Sound Space <
http://atrium.csf.edu>
OVOS <
http://pubweb.csf.edu/~smill/ovos.html>
CMP <
http://www.csf.edu/csf/academics/cmp/index.html>


August 28, 2007 | 3:52 am

i just use cycle~
and replace the sine
with buffers that have those other waveforms
written in the range -1. to 1.
you can get twice the modulation index before foldover

otoh
i kinda like foldover


August 28, 2007 | 6:28 am

>> I tried to avoid this by placing a brickwall lowpass filter before the dac~.

no, not there.

put a lp filter in the OSC, before its tuned, i.e. round
or filter your tri, square, and saw waves before you FM.

if you want to make it perfect, this filter is dynamic
and depends on the note played.

the keyword is "bandlimited oscillator":
make sure that an OSC never contains anything above
nyquist (=half the samplingrate), no matter at what
base frequency its currently playing.

the only problem here when using filters is that all
common filters are either remove more than neccesary
(slide~) or cause phase changes (IIR, biquad~) but its
better than without filters.

-110


August 28, 2007 | 9:04 am

Thank you all for the tips. I totally understand now that indeed a filter can’t eliminate fold-over once it has been introduced. That makes perfectly sense.

Probably the best thing to do is to bandlimit the modulator waveforms proportional to the note being played before FM like you suggested. I did some experiments with my pfft~ brickwall directly after the modulating saw~ object and this definitely reduces the fold-over side-effects.

Staying clear from completely no fold-over probably is not achievable however. Especially when modulating 2 tri~’s or 2 saw~’s.

The only thing i have to do now is to find some good ‘scaling’ factor to dynamically link the note being played to the cutoff frequency of the lowpass filter. It’s not a fullproof solution, but it should do the trick more or less.

Once again thank for the advice


August 28, 2007 | 11:06 am

don malone skrev:
> i just use cycle~
> and replace the sine
> with buffers that have those other waveforms
> written in the range -1. to 1.
> you can get twice the modulation index before foldover
>
Hi Don – do you have a quick example of this that you can show us?
> otoh
> i kinda like foldover
Same here. To me that’s part of the charm.

Andreas.


August 28, 2007 | 1:00 pm

>
> Staying clear from completely no fold-over probably is not achievable however. Especially when modulating 2 tri~’s or 2 saw~’s.

thats absolutely right, with a saw modulating an other
you


August 28, 2007 | 1:23 pm

> do you have a quick example of this that you can show us?

the buffering technique is in cycle~.help
in the subpatcher [p generate-buffer~]

> thats absolutely right, with a saw modulating an other
> you?ll get a lot extra hf content. :)

sidebands are created around every spectral component of the carrier at the distance of every spectral component of the program

the number of sidebands (modulation index) depends on the amplitude of the program

so anything but sine -> sine can get pretty (pun intended) thick quickly


August 30, 2007 | 2:54 pm

Yes, making your own waveforms, store them in a buffer~ and read them out with cycle~ is actually a great idea! There is a example of "how to" in the cycle~ helpfile. For all of you who are interested in other waveforms, I made a couple myself already. Use a buffer~, name it to the coresponding peek~ object and set the buffertime to 11.61 ms (1000ms/(44100/512):

max v2;
#N vpatcher 239 153 839 553;
#P window setfont "Sans Serif" 9.;
#P newex 85 245 53 9109513 peek~ sine;
#P newex 85 221 47 9109513 pack 0 0.;
#N vpatcher 143 119 743 519;
#N comlet sine function;
#P outlet 87 129 15 0;
#N comlet sample nr.;
#P inlet 87 46 15 0;
#P window setfont "Sans Serif" 9.;
#P newex 87 72 110 9109513 expr ($i1/512.)*6.283185;
#P newex 87 99 20 9109513 sin;
#P connect 2 0 1 0;
#P connect 1 0 0 0;
#P connect 0 0 3 0;
#P pop;
#P newobj 122 167 33 9109513 p sine;
#P newex 277 245 52 9109513 peek~ saw;
#P newex 277 221 47 9109513 pack 0 0.;
#P newex 210 245 64 9109513 peek~ square;
#P newex 210 221 47 9109513 pack 0 0.;
#N vpatcher 179 182 779 582;
#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#P newex 176 103 121 9109513 if $f1 > 0.5 then -1. else 0.;
#P window linecount 0;
#P newex 50 103 123 9109513 if $f1 < = 0.5 then 1. else 0.;
#N comlet ramping function out;
#P outlet 50 143 15 0;
#N comlet sample nr.;
#P inlet 50 24 15 0;
#P newex 50 74 136 9109513 split 0. 0.5;
#P newex 50 50 32 9109513 / 512.;
#P connect 2 0 0 0;
#P connect 0 0 1 0;
#P connect 1 0 4 0;
#P fasten 5 0 3 0 181 132 55 132;
#P connect 4 0 3 0;
#P connect 1 1 5 0;
#P pop;
#P newobj 247 167 44 9109513 p square;
#N vpatcher 187 253 787 653;
#P window setfont "Sans Serif" 9.;
#P window linecount 1;
#P newex 171 127 72 9109513 expr ($f1*4.)-4.;
#P newex 97 127 72 9109513 expr 2.-($f1*4.);
#P window linecount 0;
#P newex 50 127 27 9109513 * 4.;
#N comlet ramping function out;
#P outlet 50 178 15 0;
#N comlet sample nr.;
#P inlet 50 24 15 0;
#P newex 50 100 57 9109513 split 0. 0.25;
#P newex 50 74 131 9109513 split 0. 0.75;
#P newex 50 50 32 9109513 / 512.;
#P connect 3 0 0 0;
#P connect 0 0 1 0;
#P connect 1 0 2 0;
#P connect 2 0 5 0;
#P connect 7 0 4 0;
#P connect 6 0 4 0;
#P connect 5 0 4 0;
#P connect 2 1 6 0;
#P connect 1 1 7 0;
#P pop;
#P newobj 178 167 46 9109513 p triangle;
#N vpatcher 179 182 779 582;
#N comlet ramping function out;
#P outlet 50 141 15 0;
#N comlet sample nr.;
#P inlet 50 24 15 0;
#P window setfont "Sans Serif" 9.;
#P newex 92 100 66 9109513 expr (2*$f1)-2;
#P newex 50 100 27 9109513 * 2.;
#P newex 50 76 52 9109513 split 0. 0.5;
#P newex 50 50 32 9109513 / 512.;
#P connect 4 0 0 0;
#P connect 0 0 1 0;
#P connect 1 0 2 0;
#P connect 3 0 5 0;
#P connect 2 0 5 0;
#P connect 1 1 3 0;
#P pop;
#P newobj 314 167 53 9109513 p sawtooth;
#P newex 141 245 66 9109513 peek~ triangle;
#P newex 141 221 47 9109513 pack 0 0.;
#P newex 85 131 47 9109513 t i i;
#P newex 85 107 40 9109513 line 0 1;
#P message 85 85 52 9109513 0 , 512 512;
#P newex 85 60 45 9109513 loadbang;
#P connect 0 0 1 0;
#P connect 1 0 2 0;
#P connect 2 0 3 0;
#P connect 3 0 14 0;
#P connect 14 0 15 0;
#P connect 3 1 13 0;
#P connect 13 0 14 1;
#P fasten 3 0 4 0 90 212 146 212;
#P connect 4 0 5 0;
#P fasten 3 1 7 0 127 158 183 158;
#P connect 7 0 4 1;
#P fasten 3 0 9 0 90 212 215 212;
#P connect 9 0 10 0;
#P fasten 3 1 8 0 127 158 252 158;
#P connect 8 0 9 1;
#P fasten 3 0 11 0 90 212 282 212;
#P connect 11 0 12 0;
#P fasten 3 1 6 0 127 158 319 158;
#P connect 6 0 11 1;
#P pop;


August 30, 2007 | 3:37 pm

Quote: Michael Dzjaparidze wrote on Mon, 27 August 2007 15:39
—————————————————-
> Hi,
>
> I’m building my own FM synth based on the features of the FM7/8. I have to say everything is working out pretty well so far except for one little thing.
>
> I also use other waveforms like tri~, rect~ and saw~ for modulation besides cycle~. These, however generate serious aliasing problems due to the many sidebands they generate when used for modulation.
>

Aliasing problems? Dude, that’s where the flavor’s at. FM without aliasing is like french food without butter.

mz


August 30, 2007 | 5:11 pm

mzed skrev:
> Quote: Michael Dzjaparidze wrote on Mon, 27 August 2007 15:39
> —————————————————-
>
>> Hi,
>>
>> I’m building my own FM synth based on the features of the FM7/8. I have to say everything is working out pretty well so far except for one little thing.
>>
>> I also use other waveforms like tri~, rect~ and saw~ for modulation besides cycle~. These, however generate serious aliasing problems due to the many sidebands they generate when used for modulation.
>>
>>
>
>
> Aliasing problems? Dude, that’s where the flavor’s at. FM without aliasing is like french food without butter.
>
> mz
>
hehe. You said it.
A.


Viewing 11 posts - 1 through 11 (of 11 total)