Anmerkung:
Quelle des Textes von:
http://www.funet.fi/pub/sci/audio/misc/pm-intro
******************************************************
Anfang des Artikels
******************************************************
Article 3975 of rec.music.synth:
Path: ulowell!m2c!husc6!cs.utexas.edu!ut-sally!utastro!james
From: james@utastro.UUCP (James McCartney)
Newsgroups: rec.music.synth
Subject: Phase Modulation
Keywords: synth
Message-ID: <2773@utastro.UUCP>
Date: 14 Jun 88 16:49:46 GMT
Organization: U. Texas, Astronomy, Austin, TX
Lines: 77
Several people have requested this. Besides, it's good fer ya!
Despite the fact that Yamaha claims to be making FM synthesizers, the
implementation on their chips is actually Phase Modulation. I can testify to
this because I have had a chance to see the data books on these chips.
The difference between FM & PM in a digital oscillator is that FM is
added
to the frequency before the phase integration, while PM is added to the
phase
after the phase integration. Phase integration is when the old phase for the
oscillator is added to the current frequency (in radians per sample) to get
the new phase for the oscillator. The equivalent PM modulator to obtain the
same waveform as FM is the integral of the FM modulator. Since the integral
of sine waves are inverted cosine waves this is no problem. In modulators
with multiple partials, the equivalent PM modulator will have different
relative partial amplitudes. For example, the integral of a square wave is
a triangle wave; they have the same harmonic content, but the relative
partial
amplitudes are different. These differences make no difference since we are
not trying to exactly recreate FM, but real (or nonreal) instruments.
The reason PM is better
is because in PM and FM there can be non-zero energy produced at 0 Hz,
which in FM will produce a shift in pitch if the FM wave is used again as a
modulator, however in PM the DC component will only produce a phase shift.
Another reason PM is better is that the modulation index (which determines
the
number of sidebands produced and which in normal FM is calculated as the
modulator amplitude divided by frequency of modulator) is not dependant on
the frequency of the modulator, it is always equal to the amplitude of the
modulator in radians. The benefit of solving the DC frequency shift problem,
is that cascaded carrier-modulator pairs and feedback modulation are
possible.
The simpler calculation of modulation index makes it easier to have voices
keep the same harmonic structure throughout all pitches.
The basic mathematics of phase modulation are available in any text on
electronic communication theory.
Below is some C code for a digital oscillator that implements FM,PM,and
AM.
It illustrates the difference in implementation of FM & PM. It is only meant
as an example, and not as an efficient implementation.
/* Example implementation of digital oscillator with FM, PM, & AM */
#define PI 3.14159265358979
#define RADIANS_TO_INDEX (512.0 / (2.0 * PI))
typedef struct { /* oscillator data */
double freq; /* oscillator frequency in radians per sample */
double phase; /* accumulated oscillator phase in radians */
double wavetable[512]; /* waveform lookup table */
} OscilRec;
/* oscil - compute 1 sample of oscillator output whose freq. phase and
* wavetable are in the OscilRec structure pointed to by orec.
*/
double oscil(orec, fm, pm, am)
OscilRec *orec; /* pointer to the oscil's data */
double fm; /* frequency modulation input in radians per sample */
double pm; /* phase modulation input in radians */
double am; /* amplitude modulation input in any units you want */
{
long tableindex; /* index into wavetable */
double instantaneous_freq; /* oscillator freq + freq modulation */
double instantaneous_phase; /* oscillator phase + phase modulation */
double output; /* oscillator output */
instantaneous_freq = orec->freq + fm; /* get instantaneous freq */
orec->phase += instantaneous_freq; /* accumulate phase */
instantaneous_phase = orec->phase + pm; /* get instantaneous phase */
/* convert to lookup table index */
tableindex = RADIANS_TO_INDEX * instantaneous_phase;
tableindex &= 511; /* make it mod 512 === eliminate multiples of 2*k*PI
*/
output = orec->wavetable[tableindex] * am; /* lookup and mult by am input
*/
return (output); /* return oscillator output */
}
--------------- James McCartney --- Austin, Tx