----------------------------------------------------------------------------

    Direct Digital Synthesis (DDS) MATLAB 5 simulator readme.txt
    Martin Pechanec, April 1998
    pechanec@iname.com
    http://www.geocities.com/CapeCanaveral/5611/

    Versions:
      April 28, 1998:   Plotting data error corrected.
                        Added PsdFloor and FigFloor [dB]
                        global variables. User can set both
                        the calculation floor and plotting
                        floor. See section (c) bellow.

      April 24, 1998:   gResize and gCenter added to ddsg.m,
                        small version of GUI ddsgsm.m introduced.
                        ddsg.m and ddsgsm.m changed from a function
                        to a plain M-file. See section (a) Using GUI
                        for explanations.

      February 14, 1998:  First release

----------------------------------------------------------------------------

The simulator requires MATLAB 5. All the files should be extracted to the
same directory and run from there. The simulator consists of the following
files:

M-files (not functions):

--> ddsg.m      .. main GUI file. Run this if you do not want to read
                   further. Do not forget to press [Initialize] button!
--> ddsgsm.m    .. same as ddsg.m, but the GUI has smaller footprint
                   on the screen. The functionality is identical to
                   ddsg.m. This version is particularly suited for
                   screen resolutions 640x480 and 800x600.

    ddsini.m    .. main initialization
    ddsg.mat    .. description of the GUI. It is loaded by ddsg.m
    ddsgt.m     .. simulation processor, also [Simulate] button callback

    ddsgset.m   .. [Set parameters] button callback. It reads the values from
                   from the GUI boxes and sets the MATLAB variables according
                   to them.
    ddsgini.m   .. [Initialize] button callback. It creates the simulation
                   variables (only if they do not exist). Then it reads
                   the simulation variables and set their values into
                   the corresponding GUI boxes.
    ddstext.m   .. creates the string array to be included into the figures
    ddsparam.m  .. prints the simulation parameters into the MATLAB command
                   window
    ddsfplot.m  .. frequency spectrum plot of rPsdQ vector, also
                   [Plot spectrum] callback.
    ddsftime.m  .. time domain plots or rSig... vectors, also
                   [Time plots] callback.

Functions:

    ddsph.m     .. generates the accumulated phase
    ddstrunc.m  .. truncates the phase accumulator
    ddssin.m    .. phase to amplitude sin conversion
    ddsqn.m     .. amplitude quantization
    ddspsd.m    .. frequency spectral calculation (FFT)

    ddsplot.m   .. frequency spectrum plot
    ddsplota.m  .. frequency spectrum augmented plot
    ddsplotf.m  .. frequency spectrum plot with input frequency vector
    ddsstem.m   .. modified stem frequency plot
    ddsstema.m  .. same as ddsplota, but stem
    ddsstemf.m  .. same as ddsplotf, but stem

    pn.m        .. pseudonoise M-sequence generation
    vectbin.m   .. binary vector or row vectors to an integer number
                   conversion. It is used along with pn.m
    bittrunc.m  .. truncates the integer number to the given number of bits


Variable naming convention
--------------------------
For keeping the program organize the following naming convention was used:

    Name        .. float variable
    iName       .. integer variable
    gName       .. logical variable (0 or 1 only)

    rName       .. row vector of numbers
    cName       .. column vector of numbers
    mName       .. matrix of numbers
    sName       .. text string

    rcName      .. row vector of cells (see MATLAB 5 manual)
    ccName      .. column vector of cells

 - Naming convention for variables as functions input/output parameters

    foName      .. float output variable
    ioName      .. integer output variable
    roName      .. output row of numbers
    coName      .. output row of numbers
    moName      .. output matrix of numbers

    fiName      .. float input variable
    iiName      .. integer input variable
    giName      .. logical input variable
    siName      .. input string


File explanation
----------------
All the functions and are well commented in their headers and in the code.
The simulator can be run both using the GUI or from the MATLAB command
line.


(a) Using GUI
~~~~~~~~~~~~~
Start the GUI running

    ddsg

or for the small footprint GUI

    ddsgsm

from the MATLAB command line. In the GUI you MUST press [Initialize] button.
Then the simulator is ready.

There might be some problems, especially at UNIX stations, with the GUI
figure size. As default, the GUI window is set as non-resizable and the
position, width, and height where it appears on the screen are fixed.

If you want to change that, look at the beginning of ddsg.m for explanations.
The Boolean flag

    gResize = {0,1}

set the property of the GUI window.
If you change the variable gResize during MATLAB session, the change
will effect the behavior of the windows next time the ddsg.m or ddsgsm.m
are executed.

The Boolean flag

    gCenter = {0,1}

controls whether the position if the GUI on the screen at startup
is screen centered or user defined. The default is gCenter = 1,
so the GUI is always centered on the screen and it guarantees
that the GUI window control bar is always visible on the screen.

If the gCenter = 0, then the manual preset location is used.
Position and dimensions of the GUI screen can be then controlled
by variables iDdsWidth, iDdsHeight, iDdsLeft, and iDdsBottom, in
pixels (!) (or iDdsSm... for the small version of GUI).

The variable changes take effect the same way as gResize change.
Feel free to edit the beginning of ddsg.m or ddsgsm.m for the best fit.

GUI boxes explanation and variable relations
(MATLAB variable names are in parenthesis):
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

   Tuning number:       F  (iF) .. integer accumulator increment
   Accumulator width:   n  (iN) .. accumulator width in bits
   Driving frequency:   fv (Fv) .. accumulator register clock frequency.
                                   This value is only used for spectrum
                                   plots frequency axis.
 ----
   Phase truncation:    check (gTrunc) .. phase truncation on/off flag
   Bits to phase table: p (iP)  .. number of MSG accumulator bits used
                                   for phase/amplitude sin conversion.
   Phase delta offset:  poff (Poff) .. see bellow
 ----
   Amplitude quantization: check (gQuant) .. amplitude quantization on/off
   Amplitude bits:      b (iB)  .. number of amplitude quantization bits
                                   (number of D/A bits in practice)
   Amplitude offset:    aoff (Aoff) .. see bellow
 ----
   Phase dithering:     check (gDit) .. phase 1-st order dithering on/off
   Polynomial degree:   dp (iDitPoly) .. degree of the phase dithering
                                         binary primitive polynomial for
                                         PN M-sequence generation
   Dithered bits:       db (iDitBits) .. number of bits from the shift
                                         register generation PN sequence
                                         used for the phase dithering.
                                         Those bits are added to the LSB
                                         accumulator bits before the phase
                                         is truncated.
 ----
   [Initialize]:        button  .. MUST be pressed after startup. It sets
                                   the unset variables by calling ddsgini.m
                                   and set the boxes in GUI according to the
                                   DDS variables set in MATLAB.
   [Set parameters]:    button  .. it does exactly the opposite than
                                   [Initialize]. It reads the boxes in the
                                   GUI and sets the MATLAB variables according
                                   to the values in GUI. It calls ddsgset.m.
                                   It is called automatically when [Simulate]
                                   is pressed.
   Clear in run:        check (gClear) .. clear the signal arrays immediately
                                   when they are no longer needed. It helps
                                   to save the memory requirements. However,
                                   you will not be able to plot the time
                                   domain plots.
   [Clear signals]:     button  .. it clears all but the last time domain
                                   signals. The output time signal rSigq and
                                   frequency spectrum rPsdQ are kept.
 ----
   [Simulate]:          button  .. it performs the simulation. It calls
                                   ddsgset.m and ddsgt.m for simulation.
                                   The text box shows the simulation progress.
                                   The most important value is the signal
                                   length in samples. It determines the length
                                   of a simulation. I could not get it working
                                   on UNIX machines, so you can let the
                                   progress message appear in the MATLAB
                                   command window by setting gPrintMsg = 1;
                                   To set it by default, change it at
                                   designing
   [Plot spectrum]:     button  .. plot the discrete line output power
                                   spectrum in [dB] in between f=0 to Fv
                                   (sampling frequency). The factor sin(x)/x
                                   is NOT used for spectrum weighting!! It
                                   can be easily added to ddsgt.m after the
                                   rPsdQ spectrum vector is calculated.

Flags for ddsfplot.m (0-no or 1-yes values):

   Stem:        check (gStem)   .. stem (vertical lines) the spectrum instead
                                   of plot. Keep this 0 and set for 1 only
                                   when you SEE the necessity. Memory and
                                   consuming!

   Augment:     check (gAugment) .. augment the spectrum by one frequency
                                    sample to get nice symmetric figure from 0
                                    to Fv (included).
   Data:        check (gData)   .. print the text information data in the
                                   figure or by the figure.
   In plot:     check (gInPlot) .. where to plot information data in the
                                   plot - in the figure itself or by the
                                   figure.
 ----
   [Time plots]:        button  .. it stems all the checked time plots, one
                                   figure for each plot. It either stems what
                                   is specified by Starting and Ending sample
                                   or one whole period, whatever is shorter.
                                   It checks the feasibility of the limits.

Flags for ddsftime.m (0-no or 1-yes values): (also uses the flags from above)

   Phase:       check (gTPhase) .. stem linear phase accumulator values rSigp.
   Dithered:    check (gTDither) .. dithered phase accumulator values rSigd.
   Trunc:       check (gTTrunc) .. truncated (and dithered) phase accumulator
                                   values rSigt.
   Amplitude:   check (gTAmplitude) .. non-quantized sin amplitude rSigs.
   Quantized:   check (gTQuant)  .. quantized sin amplitude - the final DDS
                                    time domain output signal rSigq.

   Starting sample:   (iSampleStart) .. index of the first sample to stem
   Ending sample:     (iSampleEnd)   .. index of the last sample to stem

Both sample indices are shifted by the iIndBase value, so one can have
1-base indices (MATLAB) or 0-based indices (C and DSP theory). iIndBase
is set in designing to default value 1, so it complies with MATLAB
vector indexing.


(b) Using command line
~~~~~~~~~~~~~~~~~~~~~~
By using command line only, one can do all the simulation and plotting.
First run

    ddsini

from the MATLAB command line. Then set the variable (names in parenthesis
above) manually from the command line. Command

    ddsparam

prints all the important variables along with their names. Do not forget
to set

    gPrintMsg = 1

to get the simulation progress message to the MATLAB command window and

    gShell = 0

to tell the simulator that it is being run from the command line.
Start the simulation by

    ddsgt

When it is done, plot the spectrum by

    ddsfplot

Check the flags gStem, gData and gInPlot for stem/plot and
text information into the figure.
The time domain plots can be done by

    ddsftime

controlled by the flags above and also gTPhase, gTDither,
gTTrunc, gTAmplitude, and gTQuant, along with the
iIndBase for vector index base and iSampleStart
and iSampleEnd.

(c) Power spectrum dB floor and figure plotting dB floor
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There are two global variables controlling the dynamic
region of the power spectrum calculation and plotting.
For calculatin the power spectrum (psd) one has to limit
the minus infinity values to some floor values. This is
controlled by the variable

   PsdFloor

The value is in [dB] and should be always negative. It
is set in ddsini.m to the default value

    PsdFloor = -100;

Once the psd is calculated it is plotted by ddsfplot.m
from GUI by pressing [Plot spectrum] button. To control
the floor from figure to figure one can set the global
variable

    FigFloor

manually in between figures to get different floors.
The value is in [dB] and should be always negative. It
is set in ddsini.m to the default value

    FigFloor = -100;

The sanity check is performed by ddsfplot.m so if the
FigFloor < PsdFloor, then PsdFloor is used instead.
If FigFloor > 0, then it is assumed that user errorneouslyl
entered positive number instead of a negative, so it is
multiplied by -1 and check again against PsdFloor.

Both variables should by manually changed from the
MATLAB command line.


Amplitude offset and Phase delta offset
---------------------------------------
Explanation:

(a) Phase delta offset:  poff (Poff)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Phase offset (variable Poff) is the phase offset at which
the sin(x) is being sampled. For utilizing sin 4-quadrant
symmetry to conserve the lookup table size by a factor
of 4 we have to start sampling the sin(x) not at 0, but
at exactly the phase step divided by two. The phase step
is
                  2*pi
    Delta_phi = --------
                  2^iN

The phase offset Poff is the phase offset in Delta phi
units, so the sin(x) samples are defined as


    y(k) = sin( k * Delta_phi - Delta_phi * Poff )

for k=0, 1, 2, ..., 2^iN-1 for the full sin period.
Keep the Poff = 0.5, which is a default value.


(b) Amplitude offset: aoff (Aoff)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The amplitude number representation used is the
offset positive integer method, so for b=3 bit quantization
the situation looks like this:

    +1 ---------------------- Maximum sin(x) amplitude = +1
         111 (7) ---- center of the quantization level
       ----------------------
         110 (6) ----
       ----------------------
         101 (5) ----
       ----------------------
         100 (4) ----
   0 --------------------------
         011 (3) ----
       ----------------------
         010 (2) ----
       ----------------------
         001 (1) ----
       ----------------------
         000 (0) ----
    -1 ---------------------- Minimum sin(x) amplitude = -1

It is convenient for D/A converters. It was shown that is is convenient
not to sample sin(x) such that the maximum amplitude of sin(x) reaches
the ceiling of the 111 quantization level, but if the sin(x) maximum
lies somewhere inside the extreme quantization level bands so one
can get somewhere around 5dB better result of spurious signals
caused by the amplitude quantization. Therefore there is an option
to scale the sin(x) signal before sampling. The quantization level
width is

          2
    d = -----
         2^b

where b is a number of quantization bits. Then the signal to be sampled
is

    f(x) = (1 - d * Aoff) * sin(x)

If Aoff = 0.7, then the maximum sin(x) amplitude will be at 0.3*d
inside the maximum quantization level 111.


Data in the figure
------------------
Most of the data corresponds to the stuff already explained. There are
two more values which shows up: Fd, A and mju (Greek letter u [mju] ).
Fd is the lower part of F, which is formed by the phase truncated bits.
Mathematically:

    Fd = F mod 2^iQ

Then

          2*pi
    A = --------
          2^iP

is the maximum phase error from the linear phase when the phase
truncation is used and

             2^iQ
   mju = ----------------- >= 1
          GCD( Fd, 2^iQ )

is the period (in samples) of the phase error signal (difference from the
linearly increasing phase). If mju = 1, there are no spurious signals caused
by phase truncation. GCD means greatest common divisor.

That's all. If you have any questions or you like or dislike this, please let
me know.

Martin Pechanec
pechanec@iname.com
http://www.geocities.com/CapeCanaveral/5611/
