Docstoc

WIRELESS GUITAR EFFECTS BOARD

Document Sample
WIRELESS GUITAR EFFECTS BOARD Powered By Docstoc
					                                                 i




WIRELESS GUITAR EFFECTS BOARD

                      By

 Scott Vandyke, Ken Schutte, and Jeff Johnisee

           ECE 345: Senior Design

                TA: Jeff Cook

                   05-01-01

                 Project #26
                                                                                                         ii
                                             Abstract:

       This paper will cover the design, construction, and testing of a wireless guitar effects board. The
purpose of the project is to eliminate the encumbrance of long cables and increase mobility for
musicians performing on a stage. An HC-912 micro-controller will control the switching of the effects.
A TI-54x DSP module will then alter the guitar signal to simulate the effects of reverb, delay, and
phasing. A FM wireless system will finally transmit the altered signal at around 900 MHz to a receiver
module at a guitar amp where the signal will be attenuated and ran into the input of the guitar amp.
Various obstructions to the completion of the project and solutions to these challenges will also be
included in this paper as well as detailed circuit designs, block diagrams, and test results.
                                                                 iii
                          Table of Contents

1.   INTRODUCTION………………………………………………………………...1

2.   DESIGN PROCEDURE……………………………………………..……………3

      2.1 All-Pass Filter……………...……………………………………………...3
      2.2 Reverberator……………………………………………………………….3
      2.3 Phase Shifting……………...………………………………………………4
      2.4 4-Tap Delay………………………………………………………………..4
      2.5 900 MHz Transmitter/Reciever Pair………………………………………4
      2.6 T-Attenuation Pad…………………………………………………………5
      2.7 Guitar Amplification………………………………………………………5
      2.8 Serial Communication……………………………………………………..5
      2.9 User Interface…..………………………………………………………….5

3.   DESIGN DETAILS……………………………………………………………….7

      3.1 Reverberator……………………………………………………………….7
      3.2 Phase Shifting……………...………………………………………………7
      3.3 4-Tap Delay………………………………………………………………..7
      3.4 Transmitter Input Signal Strength………………………………….………8
      3.5 Transmitter Reciever Module / Layout………………………….…………8
      3.6 T-Attenuation Pad………………...…………………………….………….8
      3.7 Guitar Amplification………………………………………….……………9
      3.8 HC12 Serial Communication……………………….……….……………..9
      3.9 DSP Serial Communication………………………………….……………10
      3.10 Roland EV-5 Foot Pedal………………………………….……………...10
      3.11 HC12 Functionality……………………………………….……………...11

4.   DESIGN VERIFICATION…………………………………………..……………12

      4.1 Signal to Noise Ratio…………………………………….…………….….12
      4.2 Link Budget……………………………………………………………….12
      4.3 Guitar Signal Amplification……………………………………………….13

5.   COST……………………………………………………………...……………….14

6.   CONCLUSIONS…………………………………………………...……………...15

APPENDIX A …………………………………………………………………………….16
APPENDIX B …………………………………………………………………………….17
APPENDIX C …………………………………………………………………………….23

REFERENCES………………………………………………………………………..…..24
                                                                                                          1
                                      1.0     Introduction
In designing this project, we hoped to make a useful product for musicians performing on live stages.
The basic concept of the wireless guitar effects board was to eliminate the cables normally used in
hooking up effects pedals to guitar amps. The compatibility of three different effects in one board and
the ease of switching between them was also a large goal of the project. As the project was completed,
it utilized a HC912 micro-controller to handle the switching of effects through the serial port of the DSP,
a volume pedal that controlled the intensity of these effects also through the HC912, a DSP board to
alter the guitar signal to simulate the different effects, and a RF wireless system to transmit the affected
audio signal over a range of about 25-50 ft.

PERFORMANCE SPECIFICATIONS
   Show that audio signal is received through RF transmission up to 25 ft.
   Test switching of audio effects through HC12 interfaced foot switches.
   Test for signal integrity by comparing oscilloscope readings before and after RF transmission
     and calculating the SNR of the received signal.
   Prepare a Link Budget to ensure proper signal level of 200mV input into the guitar amp
   Simulate audio effects in MATLAB, and show graphs of their filtering effects
     Test for signal strength at various points in the system in order to ensure stability.

ADVANTAGES OF WIRELESS SYSTEM
   Musicians can easily move around the stage without tripping over audio chords.
   Set up and transportation of equipment in a quicker and simpler manner.
   Move effects set-up to different areas on the stage that would not be allowable with a hard-line
    effects board.


We have implemented three distinct audio effects on the DSP: reverberation, phasing, and digital delay.
To achieve professional sounding effects, we had to make use of efficient effects algorithms and keep
the code from introducing any noise or unwanted distortion to our signal.
                                     2




Figure 1. Block Diagram of Project
                                                                                                             3
                                      2.0    Design Procedure

2.1    All-Pass Filter
The All-Pass filter is a basic component in many audio effects. It is called an all pass filter due to the
fact that it passes all frequencies through equally. This property makes it useful in reverberator design
because it increases echo density while decreasing signal coloration. The block diagram seen below in
Fig. 2 illustrates the very simple form of the first order All-Pass filter.




                                 Figure 2. All-Pass Filter Block Diagram.

2.2    Reverberator
Reverberation is the product of the reflections of a sound that occur in a room. While the bulk of the
sound power heard follows the direct path to from the source to your ear, the shape and size of the room
also account for a differing amount of reverberated sound. The idea being that by creating our own
delayed reflections, we can replicate the reverberation of a more interesting setting. Through the use of
All-Pass filters, we can manipulate the timing and amplitude of these reverberated sounds. There are
many different ways to implement a reverberator. For the reverberator, our plan was to implement the
Schroeder Reverberator [1], a simple design from the 1960s consisting of Comb filters in parallel and
two All-Pass filters in series. After simulating this design in MATLAB, we were not satisfied with the
sound output. The design that we chose was a variation on the plate-class reverberator based on J.
Dattorro’s design [2]. It is basically four first order All-Pass filters in series with a feedback loop as
seen below in Fig. 3. While the actual reverberator that Dattorro discusses is much more complicated,
this design yielded impressive results.




                                 Figure 3. Reverberator Block Diagram.
                                                                                                           4
2.3    Phase Shifting

The idea of phase shifting is to periodically over time sweep through the entire 360 phase of the
sinusoidal input. By adding the scaled output of an All-Pass filter to the input, a shift in phase results.
For example, if we add a delayed signal that is precisely out of phase with the input, the result will be
approximately zero. This is due to the notch nature of the All-Pass filter. While this alone might not be
very interesting, by varying the delay time of the All-Pass filter a loop through the entire 360 phase of
the signal can be established. The block diagram shown below in Fig. 4 explains the nature of the phase
shifting effect.




                                 Figure 4. Phase Shifting Block Diagram.

2.4    4-Tap Delay
The 4-Tap Delay is a relatively simple effect that adds delayed samples to the original signal. Figure 5
shows that he signal is also sent back through the loop to create an echo effect. The length between each
echo is simply the total length of the entire delay structure. This effect is truly utilized when the length
of each delay line are of varying amounts and in descending or ascending order. This creates a waterfall
effect in the sound where you will hear each delayed sound more rapidly after each tap. One of the most
commonly used effects, the delay is both easy to use and extremely effective.




                                  Figure 5. 4-Tap Delay Block Diagram


2.5    900 MHz FM Transmitter / Receiver Pair
For a simplistic audio signal that would come out of a guitar, a simple RF system can also be chosen to
transmit the signal over a wireless path. Simplicity of the wireless system would offer easy trouble
shooting, low cost, and easy construction. Since the guitar signal and DSP output are both analog
signals, an analog wireless system would be considered optimal as no further A/D or D/A converters
would be necessary. AM and FM wireless systems are both common and relatively simplistic, and their
level of efficiency is definitely adequate for this application. Initially, a simple AM wireless system was
                                                                                                               5
to be built from basic circuit components, but as a FM transmitter / receiver pair was found to be
available in a LINX module that required only power and an external antenna, this wireless system was
then chosen for our project. The TXM/RXM-900-HP-II wireless system that was chosen also operates
in the 903-923 MHz bandwidth, leaving it invulnerable to interference from other audio frequencies
operating at a much lower level on a live sound stage. The capable audio bandwidth that the wireless
system can cover is between 500 – 25,000 Hz, which is ideal for guitar audio signals that easily fit with
in this range. The LINX wireless pair also incorporates an 8-channel binary frequency selective switch
that changes the operating frequency between 8 different channels for maximum transmission
efficiency.

2.6    T-Attenuation Pad
One problem that will arise with the RF wireless system is that the nominal output of the receiver
module is around 1V. This will be too high of a signal as the input impedance of a guitar amp is very
low and normally sees signals around 300 mV from a hardwired guitar. A simple T-attenuator can be
applied to drop the 1V output signal to a more useful 300mV signal.



2.7    Guitar Amplification
Signal strength is an important quantity that we must be aware of in all phases of our design. We want
the user to be able to plug his guitar directly into our control module, so we must deal with electric
guitar output signal qualities. String vibrations are converted voltage fluctuations by the pickups on the
guitar, but this signal is very small. This signal must be amplified to be read in by the DSP board’s A/D
converter. Therefore we will design an amplifier that will be placed into our transmitter/pedal board.
This amp must be very small, have relatively low power dissipation, and be able to amplify the signal by
about a factor of ten. This can be accomplished with a simple circuit utilizing an op amp IC.

2.8    Serial Communication

A key aspect of our design is the ability of real-time control of the effects by the user. This requires the
DSP to receive input instructing it which effect to run and information allowing parameters of the effect
to be changed. This will be accomplished by using the TL16C550 Asynchronous Communication
Element (ACE) serial controller, which is located on the DSP EVM board. We will use an HC12
microcontroller to gather the various user inputs and send this data to the DSP. The built in serial
interfaces of the HC12 and EVM board result in a quick and easy way for the two to communicate.
With user input fitting within a single byte of information, this method will provide more than enough
bandwidth.

2.9   User Interface
Our effects processor allows the guitar player two hands-free ways to send information to the system.
Four buttons on the main enclosure will be used to select between reverberation, phasing, delay, and no
effect. A foot pedal will allow the user to vary some parameter of the chosen effect in real time. We
have a Roland EV-5 Expression Pedal that can be used for varying the effect parameters. This will act
as a variable dc voltage source and sent to an analog-to-digital converter on the HC12. The
microcontroller will collect input from the buttons and the pedal and send it to the DSP as explained
above. The HC12 will also control some status LEDs mounted on the enclosure.
                                                                                                            6
                                        3.0     Design Details

3.1    Reverberator
All of our effects were implemented using the TI TMS320C54x DSP chip. All of our code was written
using the TI Mnemonic Instruction Set, and our Reverberator is no exception. As shown in the
reverberator code in Appendix B, all of the memory allocated for this effect was stored in memory
located in internal memory making the data stored easy to access and manipulate. The block diagram
shown in Fig. 1 was implemented directly as shown. The decay and diffusion coefficients are not stored
as constants, allowing the user to determine the exact level that is desired from 0.0 - 0.75 for the
diffusion coefficients, and from 0.0 – 0.5 for the decay. Any greater decay than 0.5 would cause the
feedback in the system to become very unstable.

3.2    Phase Shifting
The Phase Shifting effect was implemented much the same way that the reverberator was accomplished
since they both use the All-Pass filter to decorrelate the input signal. The phaser however needs to
oscillate in order to effectively be used. This was accomplished by coding a function that will lengthen
or shorten the delay line of the All-Pass filter periodically. The exact method is detailed in Appendix B,
but the general idea is that every time that the circular buffer loops around, the system performs a check
to determine if the length should change. If so, it then checks to see how it should change, and finally
performs the operation and resets the count. Please note that when the delay line is shorter, it will run
through this check more often, and thusly it will alter the length of the delay line more rapidly. This
creates a great effect as it almost whips around the end of the cycle, and then slows at the other end. The
length of time that the system takes to completely run through the 360 phase of the signal is entirely
user defined in real time from anywhere between 32385 – 518160 samples, or about 0.73 – 11.75
seconds.

3.3    4-Tap Delay
The 4-Tap Delay was a little more difficult to implement. Since the delays are so long, it is more
difficult to store and access the data. We had to use the external memory. This means that it will take
four additional cycles to store or retrieve the data. However, since the nature of our code was to be as
efficient as possible, these extra cycles were not a serious problem. The maximum run time of our code
is
                                     163 cycles / 80 MHz = 2.04 s                                       (1)
and with the sample rate of 44.1 kHz, our threshold computing time is locked at

                                         1 / 44100 Hz = 22.5 s                                         (2)
As you can see, this worst case run time is well within the acceptable range. The main reason that there
is such a great difference between these two values is the pipelining that the processor performs. This
allows many instructions to be running at once. Appendix B contains all of the commented code for this
DSP application. One great aspect of our 4-Tap Delay is that the user is allowed to change the length of
every delay line in real time, creating a very useful guitar effect. The delay lines range as follows

Delay Line 1          Delay Line 2          Delay Line 3          Delay Line 4          Delay Line 5
0 – 65535 samples     0 – 32768 samples     0 – 16384 samples     0 – 8192 samples      0 – 4096 samples
0 – 1.486 seconds     0 – 0.743 seconds     0 – 0.37 seconds      0 - 0.186 seconds     0 – 0.093 seconds
                                Table 1. Values for the 4-Tap Delay Lines
                                                                                                         7



3.4    Transmitter Input Signal Strength
The TXM-900-HP-II module was specified to receive between a 0-3Vp-p input signal for analog
transmission (LINX TXM 11), and since the DSP was experiencing no signal gain or loss, the out put of
the op-amp circuit had to be measured to ensure that the signal level would stay within the limits. It can
be seen from Fig. 1 that the op-amp signal strength easily stays within the specified limits of 0-3Vp-p.


3.5    Transmitter / Receiver Module Layout

The LINX transmitter / receiver pair were hooked up as shown below in Fig. 6. A power supply filter
consisting of a 33uF and a 0.0683uF capacitor in parallel was implemented in both the transmitter and
receiver modules to clean up the Vcc input power and protect the circuitry (see Fig. 6 below).




                                  Figure 6. RF Wireless System Layout



The CTS (Clear To Send) pin on the transmitter module was connected to an LED in parallel with a
5K which was lit when the CTS pin went high and indicated that the PLL (Phase Locked Loop) had
caught on to the input frequency and was ready to transmit. The RSSI (Received Signal Strength
Indicator) pin on the receiver module was also connected in a similar fashion to an LED in order to
determine whether the receiver was receiving a strong enough signal for good capture of the wireless
audio signal. Although the three channel select buttons on both the transmitter and receiver modules
were originally designed as connected to a switch, the pins were instead permanently set to a binary [1 0
0] for simplicity reasons. This set the LINX RF system to operate at 912.37 MHz [4,5]. In order to
protect the LINX modules from outside RF interference, a metal shielding was also placed around each
module after final testing and implementation into the containers.
                                                                                                          8
3.6    T-Attenuation Pad

Taking the designated nominal output signal strength [5] minus the desired input signal strength into the
guitar amp; one can find the amount of signal drop desired in the T-attenuation pad.

Analog Out of Receiver         1Vp-p          =       4dBm*
Desired Signal Into Amp       -200mVp-p       =      -(-10dBm*)

Total Attenuation in Pad                      =      14dBm
*(assuming a constant 50 system)

Using an application note provided by LINX, one can then look up the values of the resistors to be used
in the attenuator [6].
                                        R1 = 0.6673 * 50 = 33.365                                  (3)
                                        R1 = 0.4155 * 50 = 20.775                                  (4)

The resistors are then arranged in parallel and added to the receiver module as seen in Fig. 5.

3.7    Guitar Amplification
After sending the electric guitar output through an oscilloscope, we saw that it typically output 200-
300mV peak-to-peak. These measurements all had the guitar volume potentiometer on full volume.
Very hard strumming of the guitar strings pushed the signal up near 500mV peak-to-peak. In my guitar
there was also a 35-40mV noise floor.

The design we used is a typical audio pre-amp based on a 741 op-amp. The full schematic is included as
APPENDIX C. Value of resistor R4 can be changed from 100 kΩ to 1MΩ to select the desired voltage
gain. From our measurements on the guitar output and the EVM board A/D desired input range, we
have concluded that a gain of approximately 10 is desirable. This is achieved with an R4 value of 500
kΩ.

3.8    HC12 Serial Communication
One area that we ran into trouble with was the serial communication between the HC12 microcontroller
and the DSP EVM board. A main objective of our design was the hands-free user interface provided by
our custom made pedal board. As we have stated the HC12 was used to collect user input and send the
information to the DSP via its serial port. Both modules have a built in serial interface, but getting them
to talk to each other proved to be harder than expected.

The Motorola 68HC912 serial interface consists of an NRZ format (one start, eight or nine data, and one
stop bit) asynchronous communication system with built in baud rate generator, receiver, and
transmitter. Serial data is sent through a Maxim RS-232 Driver/Reciever built on the HC12 PCB.

To use the HC12 Serial Communication Interface (SCI), we must set appropriate control registers in
memory. The first are the baud rate controller registers, SC0BDH and SC0BDL (located at $00C0 and
$00C1 respectively). Serial baud rates are determined by dividing the master clock by some value set by
the user BR. BR is a 13 bit value with the lower 8 bits equal to SC0BDL(0:7) and SC0BDH(0:4). The
upper 3 bits of SC0BDH are reserved for test functions that we are not concerned with. The overall
formula for the bit rate is:
                        SCI Baud Rate = master clock / (16*BR)                                   (5)
                                                                                                              9

Therefore, to achieve the desired 9600 bps we must set SC0BDH to 0x00 and SC0BDL to 0x34.
In addition, there are two SCI control registers, SC0CR1 and SC0CR2 (located at $00C2 and $00C3
respectively) that must be set. Important settings in these registers include the M (Mode), PE (Parity
Enable), TE (Transmitter Enable), and RE (Receiver Enable) bits. With M and PE set to zero, the serial
port has parity disabled and is set for one start, eight data, and one stop bit. TE and PE must be set high
to enable the communication hardware.


3.9    DSP Serial Communication
The TI EVM320C549 evaluation modules that we used contain a TL16C550 Asynchronous
Communication Element (ACE) serial controller. This device is initialized in the DSP code. The
core.asm file executes the set-up and defines macros to be used in our main code. As with the HC12,
there are control registers in memory that must be properly initialized to create the desired functionality.

3.10   Roland EV-5 Foot Pedal
To create a complete user interface, we used a controller pedal to vary the audio effect parameters in real
time. The pedal that we used is a Roland EV-5 Expression Pedal. This is a foot pedal that acts as a dc
voltage source whose output level is controlled by the user rocking his foot back and forth. The output
is received through a 3-connector, ¼” audio jack. We were able to use existing pedal’s case; however,
we had to rebuild the circuitry within. It simply consists of two potentiometers in the following
configuration:




                                  Figure 7. Roland Foot Pedal Schematic
When the shield is grounded and the ring is set to VCC, the tip outputs a voltage between some
minimum, Vmin, and VCC depending on the position of the 10k pot that is controlled by the foot pedal.
Vmin can vary between 0V and VCC and is determined by the 50k pot that is controlled by a small
knob on the side of the EV-5.

While replacing the damaged pots inside the pedal, we ran into a bit of trouble coming from the fact that
our replacement parts had slightly different physical dimensions as the original. Therefore we had to
modify the inner mechanics slightly. This resulted in the full range of the pedal not being able to turn
the 10k pot through its entire range of values. In our reconstructed EV-5, our VCC of +5V, resulted in
a maximum output of 3.865V.
                                                                                                         10
The output of our foot pedal is sent into the analog-to-digital converters built into the HC12. The
HC12’s A/D module is an 8-channel, 10-bit analog-to-digital converter accurate to 2 bits. Thus data is
read in as 8-bit binary numbers. It can be run in two modes: single or multichannel mode. In single
channel mode, results are generated by eight sequential readings from a single channel and stored in the
registers ATD0-ATD7. Multichannel mode takes eight samples from eight different input channels and
stores them in their perspective registers. While we could have used either mode, because our sampling
rate can be relatively slow, we chose to use multichannel mode and read data only from a single input
channel. As was the case in the serial port configuration, the A/D system is initialized through the use
of a set of control registers in memory.


3.11 HC12 Functionality
The code we wrote for the microcontroller is fairly straightforward. After initializing necessary registers
and ports, we simply monitor the control inputs and output the current status to the serial interface when
a change occurs. The complete code is included as appendix A. A basic flow chart is shown below.




                                     Figure 8. HC12 Code Flowchart

The buttons we used on our pedal board are momentary push buttons, meaning that they consist of a
switch that is usually closed. The switch becomes an open only for the time that it is depressed. With
                                                                                                        11
one end of each button connected to VCC and the other wired into a pin of Port A, when a button is
depressed the corresponding pin will be read as a low voltage. That is why we continually check
PAB(0:3) for a zero in the flow chart above. All the connections to the HC12 are summed up in figure
9.




                                       Figure 9. HC12 pin layout
3.12 Container Construction

Two plastic containers of appropriate size were found at a local electronics shop and used for housing
the transmitter and receiver portions of the project. The container for the transmitter that also included
the HC12 micro-controller had a slanted aluminum face that was drilled out to hold 4 push-button
switches and 4 LED’s. These switches would allow the user to choose between the three effects and a
clean tone channel. An antenna was mounted of the top of both containers and banana power jacks were
mounted on the back to receiver +5V, +12V, and +0V. The guitar plugged into a ¼ in jack on the side
of the transmitter container, and the amp received the wireless audio from a ¼ in jack output on the side
of the receiver container. The Roland foot pedal was also connected to the transmitter container through
a ¼ in jack input on the opposite side of the guitar input. These containers were sealed and relatively
durable to travel and overall usage.
                                                                                                     12
                                     4.0     Design Verification

4.1     Signal to Noise Ratio
Table 2. Received Signal and Noise Levels

freq.(Hz)         Received Signal Strength(mV) Received Noise Floor (mV)
             5000                          342                            86
            10000                          386                            94
            15000                          392                           103
            20000                          415                           112
            25000                          426                           121
             avg.             392mV ~ -4dBm                103mV ~ -16dBm



SNR = 20 log (Power spectrum on signal / Power spectrum of noise)                       (6)
    = 12.04




Figure 10. SNR of Received Wireless Audio (Signal on Top, Noise on Bottom)

4.2     Link Budget
In many radio systems, it is ideal to create a link budget to account for the gains and losses in the
system. This allows for a designer to account for changes in system parameters such as antenna gain or
transmitter power by balancing out the link budget to maintain signal integrity. Below in Table 1 is a
basic link budget of the entire system. Such things as free space loss and transmission line loss are
negligible in the small transmission length for this project, and thus are not included.
                                                                                                         13




                              Table 3. Link Budget of Signal Strength
                                              GAIN (dBm) SIGNAL STRENGTH (dBm)

                   Guitar Signal                        -10                         -10
                   Op-amp                                14                           4
                   DSP Signal Conversion                  0                           4
                   LINX 900MHz Transmitter             -7.5                        -3.5
                   1/4 Wave Whip Antennas                 0                        -3.5
                   LINX 900MHz Receiver                 7.5                           4
                   T-Attenuator Pad                     -14                         -10

                                     -10 dBm = 200mVp-p                                    (7)
With a basic mirror gain between the transmitter and receiver chip, the attenuator is designed to also
mirror the op-amp’s losses. An out put signal of 200mV is obviously obtainable, and proves why the
system is audibly functional.

4.3    Guitar Signal Amplification
Initial testing consisted of inputing a 100mV peak-to-peak sine wave and viewing the output on the
oscilloscope. By using difference frequencies of input, we collected the below data. As you can see, the
gain of our amplifier is approximately 10 V/V for this range of frequencies. While the frequency
content of a typical guitar signal can extend well beyond 3kHz, the most of the signal’s power is in
frequencies on the order of a 1-3 kHz. After testing it with the guitar and the DSP, we felt that this amp
will suit our project very well. While the sound quality was not perfect, constructing a high quality
guitar amplifier could be a design project in itself. Our design was a very small and cheap amp that can
boost the signal to a level that the DSP’s A/D can handle.

Input frequency    Vout peak-to-peak
      (Hz)               (Volts)
       200                1.125
       300                1.156
       400                1.156
       500                1.156
     1000                 1.094
     1250                 1.062
     1500                 1.031
     1750                 1.000
     2000                 0.968
     2500                 0.875
     3000                 0.781


                                                        Figure 11. Amplifier Gain
                                                                                                         14
5.0    COST
The total cost of this project represents the simulation of a real-world project. The pricing of some parts
was estimated due to their free availability in the lab or corresponding shops. Other prices are quotes
from manufacturers. Also estimated was the hourly rate of $40.00 / hr for the 3 engineers working on
this project and the hours spent working to design it.


                                      Table 4. Cost Analysis
                 Quantity       Desciption                              Price     Total
                 4              10kΩ resistor                           N/A       $0.00
                 2              1MΩ resistor                            N/A       $0.00
                 2              22kΩ resistor                           N/A       $0.00
                 1              500kΩ resistor                          N/A       $0.00
                 1              100kΩ resistor                          N/A       $0.00
                 1              470kΩ resistor                          N/A       $0.00
                 1              50nF capacitor                          N/A       $0.00
                 1              4.7μF capacitor                         N/A       $0.00
                 1              4.7nF capacitor                         N/A       $0.00
                 1              100μF capacitor                         N/A       $0.00
                 1              1μF capacitor                           N/A       $0.00
                 6              Light Emitting Diode                    $2.00     $2.00
                 1              LM741CN Operational Amplifier           N/A       $2.00
                 2              2-conductor ¼” audio jack               N/A       $2.00
                 1              3-conductor ¼” audio jack               N/A       $2.00
                 5              Banana clip input                       N/A       $2.00
                 4              Momentary push buttons                  $3.00     $5.00
                 2              BNC connections                         N/A       $5.00
                 1              HC12 / Maxim RS-232 PCB                 $60.00    $65.00
                 1              Large project enclosure                 $8.00     $73.00
                 1              Small project enclosure                 $5.00     $78.00
                 2              Large breadboard                        $12.00    $90.00
                 1              Small breadboard                        $7.00     $97.00
                 2              LINX ¼ wave whip antenna                $5.00     $102.00
                 1              LINX HP-II 900MHz transmitter           $22.00    $124.00
                 1              LINX HP-II 900MHz receiver              $31.00    $155.00
                 1              TI EVM320C549 evaluation board          $250.00   $405.00
                 400 hrs        3 Engineers paid at $40.00 / hr         $48,000   $48,405



The total cost of our project as seen in Table 4 was $48, 405.
                                                                                                      15
                                        6.0     Conclusion

The goal of our project was to create a useable guitar effects processor for the touring musician that
could be easily used on a busy stage. We were able to accomplish most off our goals. The real time
DSP effects worked as well as we had hoped, and the serial interface also performed up to
specifications. The output, however, had a Signal to Noise Ratio that is much too great for high quality
audio performance. This noise could be attributable to many different factors. The most likely source
of the noise came from interference between the LINX chips and the surrounding equipment. The noise
could also stem from the LINX chips interfering with each other. We would recommend that the chips
have better shielding and improved insulation around the wiring between the antennas and the chips.
We would also recommend that the HC12 be fitted with a better safety circuit to prevent the deletion of
the loader program, or possibly a different method of controlling the DSP. In its present form, this
device is still not ready for production, but we still feel that it is an attainable goal.
                                                                                              16
                                                       APPENDIX A
HC12 Code
PORTA    EQU    $0000 ; port control registers
PORTB    EQU    $0001
DDRA     EQU    $0002
DDRB     EQU    $0003
COPCTL   EQU    $0016
SC0BDH   EQU    $00C0 ; serial control registers
SC0BDL   EQU    $00C1
SC0CR1   EQU    $00C2
SC0CR2   EQU    $00C3


; Variable definitions
SWINPUT EQU $0805 ; storage of switch input
STATE   EQU $0806 ; 0806 = current state of switch output (ie holds $00,$01,$02,or $03)
                        (this is updated anytime a button is depressed)
OLDVAL EQU $0807 ; output byte of previous loop

; begin program at start of EEPROM: $8000
        ORG $8000

         LDAA #%00001000         ; turn of the COP
         STAA COPCTL             ; (computer operating properly)

         LDAA #$0000              ; initialize oldval to 0
         STAA OLDVAL

         LDAA    #$0000          ; initialize serial interface
         STAA    SC0BDH
         LDAA    #$34
         STAA    SC0BDL
         LDAA    #$00
         STAA    SC0CR1
         LDAA    #$0C
         STAA    SC0CR2

         LDAA #$00              ; set initial output state to $00
         STAA STATE

         LDAA    #%00000000     ; setup input & output ports A and B
         STAA    DDRA
         LDAA    #%11111111
         STAA    DDRB

         LDAA #%00000100        ; initial state is 00, light up
         STAA PORTB             ; the proper LED

STARTT
         LDAA #%10000000        ; setup the A/D converter

         STAA    $0062          ;ATDCTL2
         LDAA    #$00
         STAA    $0063          ;ATDCTL3
         LDAA    #$01
         STAA    $0064          ;ATDCTL4
         LDAA    #%01110011     ;select CHANNEL #3
         STAA    $0065          ;ATDCTL5

         ANDA #$00            ; clear accumulator A
         LDAA PORTA           ; read from portA, store in A
         STAA $0805           ; store in $0805 for safe keeping

         LDAA $0805           ; retrieve input data
         LDAB $0806           ; retrieve current output state
SEND00
         BITA    #%00000001
         BNE     SEND01     ; if (A AND 1) != zero, then bit one is high (not depressed)
         LDAB    #%00000000
         LDAA    #%00000100         ; turn LED0 on
         STAA    PORTB
         JMP     SENT
SEND01
         BITA    #%00000010
         BNE     SEND10     ;    if (A AND 2) != zero, then bit two is high (not depressed)
         LDAB    #%00000001
         LDAA    #%00001000           ; turn LED1 on
         STAA    PORTB
         JMP     SENT
SEND10
         BITA    #%00000100
         BNE     SEND11     ; if (A AND 4) != zero, then bit three is high (not depressed)
         LDAB    #%00000010
         LDAA    #%00100000         ; turn LED2 on
         STAA    PORTB
         JMP     SENT
SEND11
                                                                                                             17
         BITA   #%00001000
         BNE    SENT
         LDAB   #%00000011
         LDAA   #%10000000            ; turn LED3 on
         STAA   PORTB
SENT
         STAB $0806             ; store current (possibly new) output state in memory

         LDAA $0076             ; get A/D input
         ANDA #%11111100        ; clear the lowest two bits in A
         LDAB $0806             ; get current output state

         ABA                    ; (A) + (B) -> A

         CMPA $0807
         BNE GOTNEW
         JMP STARTT              ; if it's not new, don't do anything
GOTNEW
         STAA $0807
         JSR TRANSMIT           ; there's a new value, so send to DSP
         JMP STARTT

TRANSMIT LDAB $00C4           ;SUBROUTINE WRITE 1 CHAR FROM ACCUM A OUT RS-232 PORT
        LDAB $00C4           ;MUST READ SCISR1 BEFORE ANY WRITE TO SCIDRL
        STAA $00C7           ;SEND OUT THE CHARACTER THAT IS IN ACCUMULATOR A
COMPLETE LDAA $00C4          ;EXAMINE SERIAL COMMUNICATION INTERFACE STATUS REGISTER 1
        ANDA #$40             ;%0100 0000=$40=TRANSMIT COMPLETE=TC= BIT 6 IS A 1=
                              ;TRANSMITTER IS IDLE. Z=1 IF ANDA=0
         BEQ COMPLETE         ;BRANCH IF CONDITION CODE Z=1 AND CHECK SCISR1 AGAIN
         RTS                  ;RETURN FROM SUBROUTINE

         ORG $F7FE ; These two lines are needed to load into EEPROM
         DW $8000


                                                         APPENDIX B
DSP Code
; ---------------------start of final1.asm------------------------
          .copy "w:\final project\finished\myCore.asm"

;   FINAL1.ASM
;   last edited: 04/23/2001
;   by: Scott Van Dyke
;   Handling program for the 3 effects
            .sect ".sdata"                                     ; internal memory for the filters

               .align    4096                                  ; space for the filters needs to be aligned
AP3Buffer                                                      ; to the nearest power of 2
               .space    4000*16

               .align    2048
AP4Buffer
               .space    2000*16

               .align    1024
AP1Buffer
               .space    1000*16

               .align    1024
AP2Buffer
               .space    1000*16

          .align         512
phaseBuffer
          .space         300

          .sect ".data"                           ; data section. Holds parameters.
hold                          .word 0             ; filled from the Serial Buffer in the Core file
effectNum                     .word 0             ; serial interface values
effectLevel                   .word 0
ArrayIndex                                        ; stored variable array of the user accessable coeffs
          .copy "w:\final project\finished\coeffs32.asm"

inDiff1Pos                              .word      8192        ; the user varying parameters
inDiff1Neg                              .word      -8192
inDiff2Pos                              .word      10240
inDiff2Neg                              .word      -10240
feedBack                                .word      10000
delay1BufEnd                            .word      0xFFFF
delay2BufEnd                            .word      0x8000
                                                                                                   18
delay3BufEnd                   .word         0xC000
delay4BufEnd                   .word         0xE000
delay5BufEnd                   .word         0xF000
countStart                     .word         4

AP1BufferLen                   .word         840      ; Reverb's constant Parameters
AP2BufferLen                   .word         636
AP3BufferLen                   .word         2248
AP4BufferLen                   .word         1644
AP1Ptr                         .word     0
AP2Ptr                         .word     0
AP3Ptr                         .word     0
AP4Ptr                         .word     0
mix                            .word         16384
oneMinusMix                    .word         8192

phaseBufferLen                 .word         100      ; Phaser's constant Parameters
phaseBackNeg                   .word         -20000
phaseBackPos                   .word         20000
phasePtr                       .word     0
up                                           .word    0
phaseMix                       .word         16384
oneMinusPhaseMix               .word         16384
count                          .word         0
temp                           .word         0


delay1Ptr                      .word         0x0000   ; Delay's constant Parameters
delay2Ptr                      .word         0x0000
delay3Ptr                      .word         0x8000
delay4Ptr                      .word         0xC000
delay5Ptr                      .word         0xE000
delay1Out                      .word         0
delay2Out                      .word         0
delay3Out                      .word         0
delay4Out                      .word         0
delay5Out                      .word         0
delayTemp                      .word         0
delay1Buffer                   .word         0x0000
delay2Buffer                   .word         0x0000
delay3Buffer                   .word         0x8000
delay4Buffer                   .word         0xC000
delay5Buffer                   .word         0xE000
delay1Tap                      .word         24576
delay2Tap                      .word         14000
delay3Tap                      .word         8192
delay4Tap                      .word         8000
delayFeedBack                  .word         14000

         .sect   ".text"
         .copy   "w:\final project\REVERB1.ASM"
         .copy   "w:\final project\THEPHASER.ASM"
         .copy   "w:\final project\DELAY.ASM"
         .sect   ".text"
main
         ; initialize pointers
         stm       #AP1Buffer, AR1                    ; this section just sets up the
         mvmd      AR1, AP1Ptr                        ; pointers to their buffers
         stm       #AP2Buffer, AR1
         mvmd      AR1, AP2Ptr
         stm       #AP3Buffer, AR1
         mvmd      AR1, AP3Ptr
         stm       #AP4Buffer, AR1
         mvmd      AR1, AP4Ptr
         stm       #phaseBuffer, AR1
         mvmd      AR1, phasePtr

loop
         ; wait for next block of data to arrive
         WAITDATA

         stm         #(BlockLen-1),BRC
         rptb        copy-1
       mvmm          AR6, AR3                         ; this sets a pointer to the current input
         ld        *AR6,16, A
         mar         *+AR6(2)                         ; Rcv data is in every other channel
         ld        *AR6,16, B
         mar         *+AR6(2)                         ; Rcv data is in every other channel
                                                                                                       19
         ld          *(effectNum), B             ; B = effectNum (ID of the given effect)
         bc          outputTime, beq             ; if effectNum == 0, just go straight through
         sub         #1, B
         cc          REVERB, beq                 ; if effectNum == 1, call REVERB
         sub         #1, B
         cc          PHASER, beq                 ; if effectNum == 2, call PHASER
         sub         #1, B
         cc          DELAY, beq                  ; if effectNum == 3, call DELAY

outputTime:

         sth         A, *AR7+                    ; this code writes the output
         sth         A, *AR7+                    ; to the output buffer
         sth         A, *AR7+

         sth         B, *AR7+
         sth         B, *AR7+
         sth         B, *AR7+

copy:

_serial_loop
          stm        #hold,AR3                   ; Read to hold location

         READSER 1                               ; Read one byte from serial port

         cmpm        AR1,#1                      ; Did we get a character?
         bc          loop, NTC                   ; if not, branch back to start


gotData:
; this code writes the user defined variables to the appropriate location

          ld        *(hold), A                   ;   A = hold (from serial port)
          ld        A, B                         ;   B = A
          sfta      A, -2                        ;   A holds the effect type
          and       #0x0003, B                   ;   B holds the effect level
          stl       B, *(effectNum)              ;   store them.
          stl       A, *(effectLevel)
          stm       #ArrayIndex, AR3             ; AR3 -> ArrayIndex
; 11 = number of variable effects
          mpy       *(effectLevel), #11, A       ;   A = effectLevel * 11 * 2 (index of Array)
          sfta      A, -1                        ;   A = A/2
          stlm      A, AR0                       ;   AR0 = index
          stm       #inDiff1Pos, AR4             ;   AR4 -> inDiff1Pos (first adjustable var.)
          mar       *AR3+0                       ;   AR3 = AR3 + *AR0
          stm       #10, BRC                     ;   load the BRC (block repeat counter = # of times - 1)
          nop
          nop
          nop
          rptb      endCoeffUpdate-1             ; repeat BRC + 1 times
          nop
          ld        *AR3+, A                     ; A = Index value
          stl       A, *AR4+                     ; variable = A
endCoeffUpdate:
          nop
          b loop                                 ; return to the initial loop



; ---------------------start of delay.asm------------------------
DELAY
; DELAY.ASM
; last edited: 4/23/2001
; by Scott Van Dyke

; 4-Tap Delay effect
          ld        a, b                         ; preserve the input
; begin delay 1
          stm       delay1Out, AR1               ; AR1 -> delayOut
          xor       a, a
          ld        #01, 16, A                   ; set the datapage
          adds      *(delay1Ptr), A              ; add the offset

         READPROG 1                              ; call external memory retrieval routine

         stm         delayTemp, AR1              ; AR1 -> delayTemp
                                                                                   20
         ld       *(delayFeedBack), T   ;   T = delayFeedBack
         ld       b, a                  ;   A = B = input
         mac      *(delay5Out), A       ;   A = A + T * delay5Out
         sth      A, *AR1               ;   delayTemp = A
         ld       #01, 16, A            ;   set datapage again
         adds     *(delay1Ptr), A       ;   add the offset

         WRITPROG 1                     ; call external memory writing routine

          add     #01, A                ; increment the offset
          stl     A, *(delay1Ptr)       ; store offset in delayPtr
          xor     A, A
          adds    *(delay1Ptr), A
          subs    *(delay1BufEnd), A    ;   A = BufPtr - BufEnd
          bc      notEndDelay1, aleq    ;   if A <= 0, skip
          ld      *(delay1Buffer), B    ;   else, load the beginning
          stl     B, *(delay1Ptr)       ;   store in delayPtr, B
notEndDelay1:

          ld      *(delay1Out), 16, A
          ld      a, b                  ; preserve the input
; begin delay 2
          stm     delay2Out, AR1        ; AR1 -> delayOut
          xor     a, a
          ld      #02, 16, A            ; set the datapage
          adds    *(delay2Ptr), A       ; add the offset

         READPROG 1                     ; call external memory retrieval routine

         stm      delayTemp, AR1        ;   AR1 -> delayTemp
         ld       b, a                  ;   A = B = input
         sth      A, *AR1               ;   delayTemp = A
         ld       #02, 16, A            ;   set datapage again
         adds     *(delay2Ptr), A       ;   add the offset

         WRITPROG 1                     ; call external memory writing routine

          add     #01, A                ; increment the offset
          stl     A, *(delay2Ptr)       ; store offset in delayPtr
          xor     A, A
          adds    *(delay2Ptr), A
          subs    *(delay2BufEnd), A    ;   A = BufPtr - BufEnd
          bc      notEndDelay2, aleq    ;   if A <= 0, skip
          ld      *(delay2Buffer), B    ;   else, load the beginning
          stl     B, *(delay2Ptr)       ;   store in delayPtr
notEndDelay2:

          ld      *(delay2Out), 16, A
          ld      a, b                  ; preserve the input
; begin delay 3
          stm     delay3Out, AR1        ; AR1 -> delayOut
          xor     a, a
          ld      #02, 16, A            ; set the datapage
          adds    *(delay3Ptr), A       ; add the offset

         READPROG 1                     ; call external memory retrieval routine

         stm      delayTemp, AR1        ;   AR1 -> delayTemp
         ld       b, a                  ;   A = B = input
         sth      A, *AR1               ;   delayTemp = A
         ld       #02, 16, A            ;   set datapage again
         adds     *(delay3Ptr), A       ;   add the offset

         WRITPROG 1                     ; call external memory writing routine

          add     #01, A                ; increment the offset
          stl     A, *(delay3Ptr)       ; store offset in delayPtr
          xor     A, A
          adds    *(delay3Ptr), A
          subs    *(delay3BufEnd), A    ;   A = BufPtr - BufEnd
          bc      notEndDelay3, aleq    ;   if A <= 0, skip
          ld      *(delay3Buffer), B    ;   else, load the beginning
          stl     B, *(delay3Ptr)       ;   store in delayPtr
notEndDelay3:

          ld      *(delay3Out), 16, A
          ld      a, b                  ; preserve the input
; begin delay 4
                                                                                            21
         stm       delay4Out, AR1                ; AR1 -> delayOut
         xor       a, a
         ld        #02, 16, A                    ; set the datapage
         adds      *(delay4Ptr), A               ; add the offset

         READPROG 1                              ; call external memory retrieval routine

         stm       delayTemp, AR1                ;   AR1 -> delayTemp
         ld        b, a                          ;   A = B = input
         sth       A, *AR1                       ;   delayTemp = A
         ld        #02, 16, A                    ;   set datapage again
         adds      *(delay4Ptr), A               ;   add the offset

         WRITPROG 1                              ; call external memory writing routine

          add      #01, A                        ; increment the offset
          stl      A, *(delay4Ptr)               ; store offset in delayPtr
          xor      A, A
          adds     *(delay4Ptr), A
          subs     *(delay4BufEnd), A            ;   A = BufPtr - BufEnd
          bc       notEndDelay4, aleq            ;   if A <= 0, skip
          ld       *(delay4Buffer), B            ;   else, load the beginning
          stl      B, *(delay4Ptr)               ;   store in delayPtr
notEndDelay4:

          ld       *(delay4Out), 16, A
          ld       a, b                          ; preserve the input
; begin delay 5
          stm      delay5Out, AR1                ; AR1 -> delayOut
          xor      a, a
          ld       #02, 16, A                    ; set the datapage
          adds     *(delay5Ptr), A               ; add the offset

         READPROG 1                              ; call external memory retrieval routine

         stm       delayTemp, AR1                ;   AR1 -> delayTemp
         ld        b, a                          ;   A = B = input
         sth       A, *AR1                       ;   delayTemp = A
         ld        #02, 16, A                    ;   set datapage again
         adds      *(delay5Ptr), A               ;   add the offset

         WRITPROG 1                              ; call external memory writing routine

          add      #01, A                        ; increment the offset
          stl      A, *(delay5Ptr)               ; store offset in delayPtr
          xor      A, A
          adds     *(delay5Ptr), A
          subs     *(delay5BufEnd), A            ;   A = BufPtr - BufEnd
          bc       notEndDelay5, aleq            ;   if A <= 0, skip
          ld       *(delay5Buffer), B            ;   else, load the beginning
          stl      B, *(delay5Ptr)               ;   store in delayPtr
notEndDelay5:

          ld        *AR3, 16, A                  ; here we add each of the taps
          stm       delay1Out, AR1               ; with their respective gains
          ld        *(delay1Tap), T
          mac       *AR1+, A
          ld        *(delay2Tap), T
          mac       *AR1+, A
          ld        *(delay3Tap), T
          mac       *AR1+, A
          ld        *(delay4Tap), T
          mac       *AR1+, A
; now we are finished...A = output
          ret

; ---------------------start of phaser.asm------------------------
PHASER
; THEPHASER.ASM
; last edited: 4/23/2001
; by Scott Van Dyke

; Allpass phasing filter

         ld        a, b                          ; preserve the input into B
         mvdm      #phaseBufferLen, BK ; load BK for Circular Buffering
         mvdm      phasePtr, AR1                 ; load AR1 with the current location
         mvdm      phaseBackNeg, T               ; T = phaseBackNeg (negative gain)
                                                                                              22
            mpya      A                            ;   A   =   A(32-16) * T
            add       *AR1, 16, A                  ;   A   =   A + current value
            mvdmphaseBackPos, T                    ;   T   =   phaseBackPos (positive gain)
            macaT, b, b                            ;   B   =   Input + A(32-16) * T

          sth       B, *AR1+%                     ; new input (B) stored
          mvmd      AR1, phasePtr                 ; store the new buffer location
; now we are done with the All-Pass filter (A = Output)

; this next section   processes the change in buffer length
          sth         A, *(temp)                    ; preserve the AP output
          xor         a, a                          ; here we process the phasing
          xor         b, b                          ; clear A,B
          ld          #phaseBuffer, A               ; A = initial location of Buffer
          ld          *(phasePtr), B                ; B = current location in Buffer
          sub         B, A
          bc          noChange, aneq                ; skip if A = B

            ld        *(count), A                  ;   A = count
            sub       #1, A                        ;   A = A(15-0) - 1
            stl       A, *(count)                  ;   preserve the count
            bc        noChange, agt                ;   skip if A > 0
            xor       A, A                         ;   A = 0
            ld        *(countStart), A
            stl       A, *(count)                  ;   count = countStart
            ld        *(up), B                     ;   load the flag that determines
            bc        goingDown, beq               ;   extend or contract the filter
            ld        *(phaseBufferLen), A         ;   if up == 1
            add       #1, A                        ;   phaseBufferLen++
            stl       A, *(phaseBufferLen)
            sub       #255, A
            bc        noChange, alt                ; if phaseBufferLen++ > 255
            xor       A, A
            stl       A, *(up)                     ; reset up flag

goingDown:

            ld        *(phaseBufferLen), A         ; if up == 0
            sub       #1, A                        ; phaseBufferLen--
            stl       A, *(phaseBufferLen)
            sub       #1,
            bc        noChange, agt                ; if phaseBufferLen-- <= 0
            xor       A, A
            add       #1, A
            stl       A, *(up)                     ; set up flag

noChange:

; here we just combine the input with the filter output

          ld        *(temp), 16, A                ; A = preserved filter out
          stm       #phaseMix, AR1                ; AR1 -> phaseMix
          mpya      *AR1                          ; A = A(32-16) * phaseMix
          mvdm      oneMinusPhaseMix, T ; T = oneMinusPhaseMix
          mac       *AR3, A                       ; A = A + Input * T
; A = complete phased output
          ret                                     ; return from the function call

; ---------------------start of reverb1.asm------------------------
REVERB
; REVERB1.ASM
; last edited: 4/23/2001
; by Scott Van Dyke

; Reverberating filter
          ld        a, b                           ;   preserve the input (A = B)
          mvdm      #AP1BufferLen, BK              ;   load BK for circular buffering
          mvdm      AP1Ptr, AR1                    ;   AR1 = AP1Ptr
          mvdm      inDiff1Neg, T                  ;   T = inDiff1Neg
          mpya      A                              ;   A = A(32-16) * T
          add       *AR1, 16, A                    ;   A = A + AP1out
          mvdm      inDiff1Pos, T                  ;   T = inDiff1Pos
          maca      T, b, b                        ;   B = B + A(32-16) * T

            mvdm      AP4Ptr, AR2                  ;   feedback to be added
            nop                                    ;   AR2 = AP4Ptr
            ld        *AR2, T                      ;   T = *AP4Ptr
            stm       #feedBack, AR4               ;   AR4 -> feedBack
                                                                                      23
         mac       *AR4, B                       ; B = B + feedBack * AP4Ptr

         sth       B, *AR1+%                     ; new input stored
         nop                                     ; (%AR1)++
         nop
         mvmd      AR1, AP1Ptr                   ; AP1Ptr = next output

; now we are done with the 1st All-Pass filter
; Allpass filter 2

         ld        a, b                          ;   preserve the input (A = B)
         mvdm      #AP2BufferLen, BK             ;   load BK for circular buffering
         mvdm      AP2Ptr, AR1                   ;   AR1 = AP2Ptr
         mvdm      inDiff1Neg, T                 ;   T = inDiff1Neg
         mpya      A                             ;   A = A(32-16) * T
         add       *AR1, 16, A                   ;   A = A + AP2out
         mvdm      inDiff1Pos, T                 ;   T = inDiff1Pos
         maca      T, b, b                       ;   B = B + A(32-16) * T

         sth       B, *AR1+%                     ; new input stored
         nop                                     ; (%AR1)++
         nop
         mvmd      AR1, AP2Ptr                   ; AP2Ptr = next output

; now we are done with the 2nd All-Pass filter
; Allpass filter 3

         ld        a, b                          ;   preserve the input (A = B)
         mvdm      #AP3BufferLen, BK             ;   load BK for circular buffering
         mvdm      AP3Ptr, AR1                   ;   AR1 = AP3Ptr
         mvdm      inDiff2Neg, T                 ;   T = inDiff2Neg
         mpya      A                             ;   A = A(32-16) * T
         add       *AR1, 16, A                   ;   A = A + AP3out
         mvdm      inDiff2Pos, T                 ;   T = inDiff2Pos
         maca      T, b, b                       ;   B = B + A(32-16) * T

         sth       B, *AR1+%                     ; new input stored
         nop                                     ; (%AR1)++
         nop
         mvmd      AR1, AP3Ptr                   ; AP3Ptr = next output

; now we are done with the 3rd All-Pass filter
; Allpass filter 4

         ld        a, b                          ;   preserve the input (A = B)
         mvdm      #AP4BufferLen, BK             ;   load BK for circular buffering
         mvdm      AP4Ptr, AR1                   ;   AR1 = AP4Ptr
         mvdm      inDiff2Neg, T                 ;   T = inDiff2Neg
         mpya      A                             ;   A = A(32-16) * T
         add       *AR1, 16, A                   ;   A = A + AP4out
         mvdm      inDiff2Pos, T                 ;   T = inDiff2Pos
         maca      T, b, b                       ;   B = B + A(32-16) * T

         sth       B, *AR1+%                     ; new input stored
         nop                                     ; (%AR1)++
         nop
         mvmd      AR1, AP4Ptr                   ; AP4Ptr = next output

; now we are done with the 4th All-Pass filter
          ld        A, B                         ;   B =   A = output
          stm       #mix, AR1                    ;   AR1   -> mix
          mpya      *AR1                         ;   A =   A(32-26) * mix
          mvdm      oneMinusMix, T               ;   T =   oneMinusMix
          mac       *AR3, B                      ;   B =   B + input * oneMinusMix
          ld        B, A
; Reverb is complete: (A = mixed output)

         ret




                                            APPENDIX C
24
                                                                                                        25
                                          REFERENCES

[1] J. Dattorro, “Effect Design Part 1: Reverberator and Other Filters,” J. Audio Eng. Soc., vol. 45, No.
        9, pp. 660-684, Sept. 1997.

[2] S. Lehman, “Effects Explained,” September 1997, http://www.harmony-central.com/Effects/effects-
        explained.html.

[3] LINX Technologies Technical Staff, Use and Design of T-Attenuation Pads, Linx Technologies,
       1997.

[4] LINX Technologies Technical Staff, HP Series-II Transmitter Module Design Guide, Linx
       Technologies, 1999.

[5] LINX Technologies Technical Staff, HP Series-II Receiver Module Design Guide, Linx
       Technologies, 1999.

				
DOCUMENT INFO
Shared By:
Categories:
Stats:
views:12
posted:7/8/2011
language:English
pages:28