fpga-base fm music synthesizer by dominic zucchini
TRANSCRIPT
FPGA-base FM Music Synthesizer
An integration of RT-DSP and DMS for Musical Synthesis
By Dominic Zucchini
In cooperation with
Missouri University of Science Technology
OURE Fellows Undergraduate Research Program 2020-2021
With supervision from
Dr. Rohit Dua
Associate Teaching Professor of Computer and Electrical Engineering
Zucchini 2
Abstract:
In the field of sound design, no other form of musical synthesis is recognized for its unique
timbre like frequency modulation (FM) synthesis. The versatility of this technique was used in
many early keyboard synthesizers, such as the Yamaha DX7, and synthesizer chips for game
consoles such as the Sega Genesis using the Yamaha YM2612. Some modern iterations of FM
synthesis exist now in the form of Virtual Instruments (VSTs) in Digital Audio Workstations
(DAWs) such as Image Line’s Sytrus FM synthesizer. The goal of this design was to integrate
the feature set of FM synthesizers such as these in a field-programmable gate array (FGPA)-
based environment using the concepts taught in courses such as digital system modeling (DSM)
and real-time digital signal processing (RT-DSP). This report covers the methods discovered
such as direct digital synthesis (DDS) as well as the limitations and possible improvements to the
approach. The features under review will be waveform generation through a numerically
controlled oscillator, envelope gain, Musical Instrument Digital Interface (MIDI) compatibility,
FM using phase manipulation, mixing of signals, the unison effect, and filtering.
Introduction: The FPGA-based FM Music Synthesizer is a stereo, fixed-point, digital synthesizer programmed
on an Intel Cyclone IVE FPGA with a Texas Instruments MSP430 powered interface and NXP
UDA1334ATS stereo digital-to-analog converter (DAC). The system was written in Verilog
(hardware descriptive language) HDL code, synthesized using Intel’s Quartus Prime software
suite, and tested using the Altera Modelsim simulator. The FPGA acts as the sound generating
hardware and incorporates a numerically controlled oscillator (NCO), FM matrix, unison effect,
envelope gain (EG) generator, and low and high pass (infinite impulse response) IIR filters as
well as a serial peripheral interface (SPI) and other interfaces and a module to store patch
settings. With a MIDI-connected keyboard, users can play up to 8 notes simultaneously with 5
voices per note and 4 inter-modulated oscillators per voice. The user interface allows real-time
modification of the sound generating system giving users the ability to create rich sounds on the
fly for song recording or live performances. The features of the synthesizer borrow concepts
from other FM synthesizer implementations and much of the research was done by studying the
Sytrus FM synthesizer and finding resources that can describe how its features work. The goal of
this project is to address how the concepts taught in courses like Embedded Systems, RT-DSP,
and DSM can be brought together to create a useful complex system. The rest of the report will
cover in detail how the features are created and how they function.
Overall Design: In DSM, module encapsulation defines a hierarchical structure where lower modules are
contained and driven by higher-level ones. This design implements this concept with a top-level
entity that contains the entire system and sits at the top of the hierarchy. The top-level includes
the main modules such as the sound generating hardware (note controller), the IIR filters,
memory unit, and communication unit. Below in Figure 1 is the block diagram.
Zucchini 3
Figure 1: Top Level Block Diagram
The main sound generating hardware is a hierarchical structure of its own starting with the NCO
and moving upwards to the FMM/Voice Unit, the Unison Effect/Note Unit, and finally, the Note
Controller which resides in the top level. The main sound generating hardware behaves as a
multiplexed pipeline of modules. At a given level, multiple instances of the lower module take
turns being processed through one piece of hardware. For example, in the note controller, eight
notes can be played, but having eight note units is expensive. To avoid the cost, each note is
processed one after the other through a single note unit and then mixed. This costs more time but
is acceptable given the 96 kHz sample clock is much slower than the 50 MHz system clock.
Design Outcomes: To demonstrate the outcomes of the system design, it will be compared with the outputs of the
Sytrus FM synthesizer. The system works as designed implementing 4x4 matrix-based phase
modulation, up to order 5 unison effect, and the ability to filter. Below a series of waveforms
from both the Sytrus FM synth and this project will be compared to show the successful design
outcomes. Figure 1 shows the result of feedback phase modulation on a sinewave oscillator.
Figure 2 shows the result from Figure 1 with the addition of the unison phase shift effect at
unison order 5. Figure 3 shows the result of the waveform in Figure 1 through a lowpass filter.
These figures show how the audio signals compare visually. To see and hear the outcomes of the
design, please view the videos below.
Demo 1: https://youtu.be/yWKJBZ5DGp4
Demo 2: https://youtu.be/83Wzo1gOcug
Zucchini 4
Figure 2: Sytrus (left) and FPGA (right) Comparison: Single Oscillator with Feedback Modulation.
Figure 3: Sytrus (left) and FPGA (right) Comparison: Feedback with Unison Phase Shift Order 5
Figure 4: Sytrus (left) and FPGA (right) Comparison: Feedback with LPF
Design Limitations: Some design limitations were not considered at the start of this project that have now come to
light. These resulted in some mismatches with appropriate hardware and introduced constraints
that limited the capabilities of the system. Below are the listed limitations of the design.
• The low number of available DSP and memory units on the FPGA is bad for any DSP
system which relies heavily on multiplications and delay lines. If the hardware had been
provided with more multipliers and memory, then the number of simultaneous notes that
Zucchini 5
can be played may have been greater. It also would have allowed for more complex RT-
DSP algorithms to be implemented such as reverberation.
• The DAC chip initially selected was not stereo and did not easily provide the proper
voltage ranges for audio signals. Later, revisions to the communication module were
made to integrate a more appropriate DAC with stereo capability, proper voltage levels,
and a 3.5mm jack output.
• To keep development at a quick pace, timing constraints were note considered deeply
through the design process. Unfortunately, this means some combinational circuits
introduce large delays and can cause erroneous data to be registered. At low
temperatures, the FPGA chip behaves better than at high temperatures. If the chip heats
up, then the system can begin introducing glitches and distorted audio. Luckily, the
effects of this have not been significantly noticeable.
• Not enough time was able to be spent developing a more complex interface. Because of
this, users may find it difficult to configure the synthesizer's various patch settings.
• The current methods by which certain notes are switched on and off are not perfect. A
second note can overwrite a note that is still playing if it is playing because of the release
time from the ASDR envelope that has not finished.
• Most modern synthesizers have a method for saving and loading patch settings. This way
if users create a sound they like, they can come back to it later at any time. No method
currently exists on this system, so there is no way to recover certain sounds once they are
changed or reset.
• Voices are often allocated dynamically so that more notes can be played if notes are
using fewer voices. In this design, there is no dynamic allocation and all notes are
allocated 5 voices. When the voices aren’t in use, they simply are muted instead of being
used to play more notes.
Future Plans: Future plans for the system involve addressing many of the limitations and changing current
functionality.
• Increasing the resolution of several parameters such as frequency, frequency multiplier,
FMM settings.
• More envelope gain parameters such as attack level, and decay level.
• Notes which are pressed again before they finish their envelope will use the same note
instead of a new one.
• More notes by optimizing the design and utilizing more appropriate FPGA hardware.
Using the FPGA-based FM Synthesizer: The use of the synthesizer is simple. Plug in a MIDI keyboard to the SDIN MIDI port and press
the keys to play a note. By default, the system will only play sinusoidal tones. To change the
tone, modify the patch settings via the rotary encoder and potentiometer. Start with the rotary
encoder to select a particular parameter. Then push in the encoder to enable writing to that
parameter. Begin turning the potentiometer to modify this parameter’s value. Only certain
parameters are changeable via the interface. Table 1 in the Memory module description shows
which are user-configurable via the user interface. The provided DAC has a 3.5 mm jack output
Zucchini 6
for connecting stereo speakers or headphones. The system currently has no volume control, so
speakers with volume control are recommended.
Module Descriptions:
NCO
At the heart of every musical synthesizer is an oscillator that produces a periodic waveform at a
desired frequency or pitch. In this design, the oscillator is controlled numerically through a
digital system and is thus known as a numerically controlled oscillator or NCO. The design is
based on an analog Devices article [1] and was modified for use with the rest of the system. The
block diagram for the NCO can be seen below in Figure 5.
Figure 5: NCO Block Diagram
The beginning of the waveform generation comes from the value in the frequency register, this is
then transformed into a change-of-phase (Δ-phase) value that is accumulated every clock cycle.
As values of Δ-phase are accumulated, each value is then converted to an amplitude. Thus, the
Phase to Amplitude Converter or PAC outputs a periodic waveform as the phase accumulator
counts up and overflows repeatedly. The PAC in the article was a LUT (Look Up Table) of
sinewave values. This became a limiting factor in the design as a 16bit precision would require
2*2^16 = 131,072 bytes or 1,048,576 bits of memory. The Cyclone IVE only supports 76,032
bytes or 608,256 bits. To overcome this, the LUT-based PAC was substituted with an
algorithmic approach. The algorithm is a 3rd order polynomial approximation of one-quarter of a
sine wave. Through symmetry, the other three quarters are traced. The approximation produces a
0.5% error to the LUT but does not noticeably affect sound quality. This approach saved on
memory in exchange for more combinational logic. It uses 8 out of the 132 embedded 9-bit
multiplier units provided by the Cyclone IVE FPGA. Another major modification was
implemented to the design for system-wide compatibility. As was discussed, the system works as
a multiplexed pipeline of single modules to produce the effect of multiple modules in parallel.
Zucchini 7
This approach allows efficient use of the hardware while creating rich complex sounds. To
achieve this, the phases of each waveform must be saved until the multiplexed system has
wrapped back around. Since the system supports at most 8 notes with 5 voices each and 4 NCOs
per voice, we need to accumulate all 160 phase values independently. This makes the phase
accumulator block 160 times larger adding to the total register bits but is necessary for multiple
signals to be produced. In a round-robin fashion, each phase is combined with the phase
modulation and phase shift and converted to an amplitude. At the same time, the accumulator
adds Δ-phase to the current value and registers the phase.
FMM/Voice Unit
An important disclaimer for this part of the system is that frequency modulation is achieved via
phase modulation this is generally preferable for the sounds it can create and its more robust
implementation. The FM and PM algorithms work out the same mathematically and the use of a
digital system makes PM much more preferable. [2] For the rest of this report, the FM
nomenclature will still be used in favor of PM. Phase modulation works by using the amplitude
of one oscillator to shift the phase of another. The carrier is the oscillator whose phase is
modulated by the modulator. Many different interconnected modulation schemes can be made
when the frequencies of the carrier and modulator are simple ratios like 1:2. Figure 6 shows the
effect of a modulator at twice the frequency of the carrier. The frequencies of each of the four
NCOs can be set as multiples of the base frequency. This allows more complex FM algorithms to
be achieved.
The frequency modulation matrix (FMM) takes four NCOs and modulates each’s phase based on
user-defined settings. A detailed description of the FMM nomenclature can be found in the
nomenclature section below. The matrix implementation is based on the Sytrus FM synthesizer.
Sytrus uses 5 oscillators and so its matrix is a 5x5 configuration. This design uses 4 oscillators
and thus has a 4x4 FMM. Figure 7 shows the block diagram of the FMM/Voice Unit
Zucchini 8
Figure 6: 1:2 Phase Modulation Ratio
Figure 7: FMM/Voice Unit Block Diagram
Notice the use of multiplexers and demultiplexers. This is due to the aforementioned
multiplexer-based pipeline architecture. Each NCO takes turns generating the next value in their
waveforms by applying the previous phase-modulation values and then saves the value. The
saved values are used for the next rounds of phase-modulation. Finally, the saved values are
Zucchini 9
mixed to form the “Voice” output. The note unit also contains another key module, the Envelope
Gain Generator.
Envelope Generator
This module is an important part of any synthesizer. Many non-synth instruments have different
volume characteristics as notes are played. A violin for example fades into its maximum volume
in contrast to a piano which is percussive and is at its maximum volume the instant after a key is
pressed. A synthesizer seeks to achieve the sound of any instrument and thus must have control
over how its volume changes over the duration a note is played for. This is what the EG
generator does. The EG generator implemented in this project is a simple four-part piecewise
linear function. Each section of the piecewise controls the volume of the NCO output depending
on the state of the envelope. The four states are known as Attack, Decay, Sustain, and Release.
This is known as ADSR envelope gain. In more complex synths, ADSR can be non-linear. The
initial state is the attack state. This occurs right as a key is pressed and ends after a given amount
of time. During this time the volume starts from 0 and increases to the maximum possible value.
To bring back the violin and piano comparison, a violin generally has a longer attack time than a
piano. The decay state follows after the attack. Decay time determines how long a note decays
from the maximum to the sustain level. Once the decay time is exceeded, the volume stays at the
sustain level. This is the third state which will persist until the note is released. The final state is
the release state. Release time applies here by decaying the volume from the sustain level to zero.
This is like a violin string that has been left to continue vibrating until it settles. Below in Figure
8 is an example of two differing ADSR EG curves.
Figure 8: Example ADSR Envelopes for Violin and Piano
Like in the Sytrus FM synthesizer, EG is applied to each NCO, since there are 4 NCOs per voice,
We need 4 EG units. But like the other modules, this too is multiplexed and pipelined to save on
resources. Like the NCO phase values, the previous values for each envelope generator must be
demultiplexed, saved, and multiplexed into the generator to produce the gain output for each
voice. The 4 NCO and EG settings are shared across all voices in a unison effect, so it is only
necessary to keep track of the 4*8 = 40 EG values. Figure 9 shows the block diagram below.
Zucchini 10
Figure 9: Envelope Gain Unit Block Diagram
The ADSR Envelope module processes the instantaneous gain for the four oscillators per note
based on the ADSR curve set by the user. The instantaneous state of the system for a single
oscillator for a singular note is saved into the Envelope Register, meanwhile, the next oscillator’s
gain is waiting for the next clock edge to be processed through the Envelope Gain module. Also,
at this time the instantaneous gain is used in the voice unit before the oscillation amplitude is
saved and used in the FMM. This allows the EG to affect the modulation as well. The four
oscillators for a particular note are processed and the next note is processed cyclically.
Unison Effect/Note Unit
The Unison Effect is a detuning, phase shifting, and panning effect that greatly adds to the depth
of an otherwise simpler voice. The three aspects detuning, phase shifting, and panning each
function differently depending on the “order” of the effect, so a description is necessary. The
detuning feature is done by creating parallel voices at slightly different frequencies. The order
defines the number of voices as well as the frequency difference. The difference is a percentage
of the base frequency such that all active voices average to the base frequency. The spread of
these frequencies is determined by the detuning parameter. No detuning means all voices are at
the same frequency, full detuning spreads the frequencies more. Maximum detuning can sound
bad but is available at the user's discretion like it is in other synthesizers with this effect.
The pitch shifting aspect either adds or subtracts from the phase accumulator value in the NCO.
The amount of shift is controlled by the user. For both the detuning and phase-shifting aspects,
higher-order voices are filled into the spread evenly. This means if the order is odd, one voice is
left unchanged, and the rest are either positively or negatively pitch and phase-shifted. This also
makes the default order of 1 similar to having the unison effect “off”.
Zucchini 11
The panning aspect controls how the detuned and phase-shifted voices are shared between the
left and right audio channels. If the order is 1, this has no effect and both channels are copies of
each other; If the order is even, the positively detuned and phase-shifted voices are sent to the
right channel and vice-versa for the left channel; If the order is odd, the un-detuned and unshifted
voice is copied into both channels. In this implementation, the setting simply toggles the effect.
Below shows the block diagram of the Note Unit which implements the unison effect by
cyclically generating the sample of each voice with its given detune and phase-shift and then
mixes them.
Figure 10: Note Unit/Unison Effect Block Diagram
The Note Unit acts as a key object activating when a key is pressed and deactivating after that
key is released.
Note Controller
The Note Controller’s responsibility is to instrumentalize the synthesizer into a keyboard. A
keyboard has keys that can be pressed and released. Initially, all keys are released or off. This
means the note units should all be producing zero output until a key is pressed. Once a key is
pressed a note unit should continue producing its sound until that key is released. This means the
note controller has to know which key each note unit is activated by. Also, the note units must be
provided a frequency. A module is used to convert the key number to the correct frequency. This
note-to-frequency converter uses a LUT of note numbers to select a note frequency and a
frequency divisor. The note frequencies are all the highest octave for A, A#, B, C, etc. Since
lower octaves are all inverse powers of 2, the lower frequencies can be calculated by bit shifting
the highest octave frequencies. This conversion takes longer than one clock cycle but will
ultimately be stable by the time the note is activated. This is due to the communication API
discussed later. The note number is the first of three messages. Since the transmission time is
Zucchini 12
significantly greater than the system clock, note numbers have plenty of time to be converted to
the corresponding frequency before they are used.
The note velocity is the measure of how quickly a key is pressed. A light keypress will produce
low velocity and vice-versa. The velocity is used as the percent output of the note. A lighter
keypress will produce a quieter sound and vice-versa. The values of the note number and note
velocity and other parameters are provided by the memory unit which is discussed later.
Note activation is important to do correctly so that multiple notes can be played at once, and if
more notes are played than allowed, the oldest note is replaced. To do this, each note keeps track
of its “age” which is incremented every time a different note is activated. This also means if a
note is activated, its age will be reset. For example, if the maximum allowed notes were three
and a user plays notes C4, D4, and E4, if they play F4, then C4 would be deactivated and
reactivated at the F4 frequency. Another example, if C4, then D4, then E4 is played, C4 is
released and then F4 is played, no notes will be replaced and F4 will simply fill the empty spot
left by C4. But if then G4 is played, G4 will replace D4.
Note deactivation is much simpler. If a note-off signal is received and the note number is C4,
then all the notes with that value will be turned off. Typically, this is always only one note with a
given note number active, but exceptions to this are handled on the microcontroller side meaning
it is possible on the FPGA to have multiple notes with the same value if the microcontroller tells
the FPGA it is so. Below is the block diagram for the note controller in which the activation and
deactivation block is programmed with the behavior described above.
Figure 11: Note Controller Block Diagram
IIR Filter
Included before the sample output is an IIR LPF. Two are used in parallel for the left and right
audio channels. These run at the same frequency as the DAC meaning it needs to borrow an
Zucchini 13
update signal from the communication unit. This signal is a clock at ~87kHz. The rising edge of
this pulse is the clocking signal for the filter memory blocks. The filter coefficients are pre-
calculated and written to the FPGA as LUTs based on the user-defined cutoff. The cutoff
frequency is exponentially scaled from the parameter p in the range from 0-255 to 20-87kHz
using the following equation:
���� � �1 � 287932�� ������
The coefficients were derived based on the impulse invariance technique and the filter was
implemented as a modified Direct Form I. Figure 12 shows the block diagram for the IIR LPF.
The coefficients β and α were derived from the z domain equation below. A LUT was created for
each of the coefficient values for a given cutoff frequency. This allows users to change the cutoff
in real-time.
���� � ���� � � ���� ! " � 1 # ���� !
The coefficients are fractional values in the format Q0.M that are defined to have a range and
precision (or step size) based on the number of M bits used. The range and precision of this
number are defined below.
$%&'� � (#1, 2*�� # 12*�� + -$�./0/1& � 1
2*��
M was chosen to be 20 for these filters to provide high quality. When the sample is multiplied by
the coefficients, it becomes a fixed-point number in the format Q16.20 with 16 integer bits and
20 fractional bits. Because of this, the output of the summing block must be divided by 220 to
return the sample to Q16.0 format.
Figure 12: IIR Stereo LPF Block Diagram
Zucchini 14
Direct form II is not desirable for fixed-point implementation. In Direct Form II intermediate
values are allowed to exceed the bit size of the input values requiring the summing block to have
an even higher bit count to avoid overflow.
The reason for the appearance of M – 1 in the expression is because the MSB is the sign bit
which does not add to the precision or range.
The filters are connected in series meaning their frequency domain responses multiply. This
allows the user to form a bandpass filter by setting the LPF cutoff higher than the HPF cutoff.
Memory Unit
Digital synthesizers can typically store the parameters of the sound hardware. The collection of a
set of specific settings is called a patch or patch settings. The memory module in this project
stores the patch settings as well as the parameters for note activation and deactivation. The
memory module receives bytes from the communication unit. It is assumed that each
transmission will be a two-byte message: an address followed by data. Control signals are shared
between the memory module and communication unit to ensure proper data flow. The control
signals are called “next_byte_rdy” and “first_byte”. “next_byte_rdy” tells the memory unit that
the data is ready to be registered. At this point, “first_byte” is logic 1 which tells the memory
unit to register the data as an address. At the same time “first_byte” transitions to logic 0. Now
when “next_byte_rdy” is activated the data will be registered to the address defined by the first
byte. For example, the unison order parameter is saved as address 0x20. If a user sets the unison
order to three. The microcontroller must set 0x20, 0x03 over SPI to the FPGA. Below is the
block diagram for the Memory Unit.
Figure 13: Memory Unit Block Diagram
Table 1 below shows the memory map for the Memory Unit. All addresses are 8-bits wide.
Table 1: Memory Map for Memory Unit
Address Data Reset Value User Control
0x04 Note Number 0 Restricted
Zucchini 15
0x05 Note Velocity 0 Restricted
0x06 Note On (BIT0) Note Off (BIT7) All Off (BIT6) 0 Restricted
0x07 NCO 1 frequency multiplier 1 Available
0x08 NCO 2 frequency multiplier 1 Available
0x09 NCO 3 frequency multiplier 1 Available
0x0A NCO 4 frequency multiplier 1 Available
0x0B FMM 1,1 0 Available
0x0C FMM 1,2 0 Available
0x0D FMM 1,3 0 Available
0x0E FMM 1,4 0 Available
0x0F NCO 1 Output volume 255 Available
0x10 FMM 2,1 0 Available
0x11 FMM 2,2 0 Available
0x12 FMM 2,3 0 Available
0x13 FMM 2,4 0 Available
0x14 NCO 2 Output volume 0 Available
0x15 FMM 3,1 0 Available
0x16 FMM 3,2 0 Available
0x17 FMM 3,3 0 Available
0x18 FMM 3,4 0 Available
0x19 NCO 3 Output volume 0 Available
0x1A FMM 4,1 0 Available
0x1B FMM 4,2 0 Available
0x1C FMM 4,3 0 Available
0x1D FMM 4,4 0 Available
0x1E NCO 4 Output volume 0 Available
0x20 Unison Order 0 Available
0x21 Unison Pan 0 Available
0x22 Unison Phase 0 Available
0x23 Unison Pitch 0 Available
0x24 NCO 1 Attack Time 0 Available
0x25 NCO 1 Decay Time 0 Available
0x26 NCO 1 Sustain Level 255 Available
0x27 NCO 1 Release Time 0 Available
0x28 NCO 2 Attack Time 0 Available
0x29 NCO 2 Decay Time 0 Available
0x2A NCO 2 Sustain Level 255 Available
0x2B NCO 2 Release Time 0 Available
0x2C NCO 3 Attack Time 0 Available
0x2D NCO 3 Decay Time 0 Available
0x2E NCO 3 Sustain Level 255 Available
0x2F NCO 3 Release Time 0 Available
0x30 NCO 4 Attack Time 0 Available
0x31 NCO 4 Decay Time 0 Available
0x32 NCO 4 Sustain Level 255 Available
Zucchini 16
0x33 NCO 4 Release Time 0 Available
0x34 NCO EG Enable (Bit Field) 0 Available
0x35 LPF Cutoff 255 Available
0x36 HPF Cutoff 0 Available
0x37 Parameter Display 0 Restricted
Communication Unit
The communication unit is an SPI that is slave to the microcontroller and a different interface
acting as master to the DAC. Figure 14 is its block diagram.
Figure 14: Communication Unit Block Diagram
It is worth noting the SPI module was provided by Jean Nicolle of fpga4fun.com [3] and then
modified for use with the microcontroller. The API for the microcontroller to FPGA interface
over SPI is the two-byte address, data scheme from earlier. To add, the “first_byte” signal is
shared with the microcontroller from the FGPA’s GPIO allowing the microcontroller to know
when to send data. The API for the DAC is to provide the bit clock signal and WS signal. WS
selects Which Side the audio channel is, so the WS = 1 is the right channel and WS= 0 is the left
channel. Logic level transitions of WS capture the last 16-bits as an LSB justified audio sample.
WS is required to transition on the negative edge of the bit clock. Figure 15 shows the timing
diagram provided by the DAC datasheet [4].
Zucchini 17
Figure 15: DAC API Timing Diagram
Microcontroller Interface
The user interface and MIDI interface are both handled by the MSP430FR5969 microcontroller.
This microcontroller was chosen because it came as an evaluation module with easy
programming capability and provided GPIO pins. The MSP430 also offers a variable baud rate
generator which is advantageous since the MIDI interface is a simple UART bus at 32500 baud,
an uncommon value. The microcontroller is used to interface a rotary encoder and potentiometer
which combine to form the interface to modify synthesizer patch settings. The encoder can be
turned to select an address defined in the memory map. If user control is restricted, then its value
cannot be modified by the encoder and potentiometer. The program running on the
microcontroller uses interrupt-based serial data capture from the MIDI controller and analog to
digital conversion of the potentiometer and encoder. Messages are then sent to the FPGA using
the API described in the communication Unit section previously.
Nomenclature:
FMM
The frequency modulation matrix is an implementation of FM algorithm selection which allows
the user to define the FM algorithm based on the configuration of the FMM. The modulation
intensities are arranged in a matrix form where each element is a percentage. A row of these
percentages is multiplied by all four NCO amplitudes respectively then summed to form the
phase modulation value for a given NCO, thus there are four rows and four columns to the
matrix. A final column defines the percent output of each NCO to the higher-level system.
Below is are the equations for calculating the phase modulation for each NCO where φm,n is the
total modulation applied to the nth NCO, an is the amplitude of the nth NCO, and mr,c is the
percent value of modulation applied by the cth NCO to the rth NCO:
23,� � %� ∗ 5�,� � %� ∗ 5�,� � %6 ∗ 5�,6 � %7 ∗ 5�,7
23,� � %� ∗ 5�,� � %� ∗ 5�,� � %6 ∗ 5�,6 � %7 ∗ 5�,7
23,6 � %� ∗ 56,� � %� ∗ 56,� � %6 ∗ 56,6 � %7 ∗ 56,7
23,7 � %� ∗ 57,� � %� ∗ 57,� � %6 ∗ 57,6 � %7 ∗ 57,7
Voice
A voice in sound design is used to denote a single sound generating unit. This may be a single
oscillator or a group of oscillators and effects. In this project, a voice refers to the output of the
FMM thus after modulation is applied. This was done so the unison effect can be implemented as
a sum of panned, frequency shifted, and phase-shifted voices which share the same modulation
algorithm.
Zucchini 18
Acknowledgments: I would like to thank the OURE Fellows Research program for allowing me the opportunity to
do this project.
I would like to thank Deepak Kumar Tala of ASIC-world.com for their excellent Verilog HDL
programming tutorials. With this resource, becoming a novice Verilog programmer was
relatively stress-free.
References [1] Analog Devices, Inc., “Fundamentals of Direct Digital Synthesis (DDS)” October 2008.
[online]. Available at https://www.analog.com/media/en/training-seminars/tutorials/MT-
085.pdf [Accessed: March 29, 2020]
[2] J. M. Chowning, “The Synthesis of Complex Audio Spectra by Means of Frequency
Modulation,” Journal of the Audio Engineering Society, vol. 21, no. 7, pp. 526–534, Sep.
1973.
[3] J. P. Nicolle, SPI 2 - A simple implementation. [Online]. Available:
https://www.fpga4fun.com/SPI2.html. [Accessed: 27-Jan-2021].
[4] Low power audio DAC with PLL, UDA1334ATS, NXP Semiconductors, 2000. [Online].
Available: https://www.nxp.com/docs/en/data-sheet/UDA1334ATS.pdf [Accessed: 15-
Mar-2021]