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 , 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 . 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  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 . 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  J. Dattorro, “Effect Design Part 1: Reverberator and Other Filters,” J. Audio Eng. Soc., vol. 45, No. 9, pp. 660-684, Sept. 1997.  S. Lehman, “Effects Explained,” September 1997, http://www.harmony-central.com/Effects/effects- explained.html.  LINX Technologies Technical Staff, Use and Design of T-Attenuation Pads, Linx Technologies, 1997.  LINX Technologies Technical Staff, HP Series-II Transmitter Module Design Guide, Linx Technologies, 1999.  LINX Technologies Technical Staff, HP Series-II Receiver Module Design Guide, Linx Technologies, 1999.