IR Mixer

Note: This page was written in 2004. Think PIII and NetBSD 2.0 when you read this.

My roommates and I have been working on a whole-home audio distribution system as a fun project since January 2004. We have close to 400 of our CDs encoded and stored on our server. With some neat software Dan and I have been working on, the albums are listed and can be queued up via a web-based interface. Recently Dan has made a Flash interface for the system which offers much faster response. Our software on the server generates four shoutcast streams which can be played from any computer in the house. The streams operate at 320kbps, so currently they are confined to our LAN unless we get a faster internet connection or a faster computer than can recode the streams to something more DSL-friendly.

Our main floor consists of three large rooms which do not have any doors between them. The livingroom, middle room and the kitchen are all one large space. Each of these rooms has a set of speakers, and all the speaker wiring runs to a 6 channel Rotel amplifier in the livingroom. Because of the open concept, it is only practical to listen to one music stream at a time on the main floor. We have a computer that continuously plays one of our shoutcast streams on the main floor. Until now we have not had a good way to control the volume in the three rooms. We tried using three sound cards as mixers with a web-based interface to allow the volume in each room to be changed. But it takes a long time to go to a web page, and there is only one permanent computer set up in the main floor. We found that when the phone would ring, it was very difficult to turn down the music in time, and we often resorted to switching off the amplifier.

An IR Controlled Mixer

I have long been fascinated with IR remote controls, but have never had the chance to make any circuits that decode them. I recently found an IR receiver module in one of my drawers and decided that it might be useful for something. Yesterday Dan and I decided that the best way for us to control the volume in our main floor would be with IR remotes. We went to a video store and found a Zenith universal remote for $17. It feels quite solid, and supports every brand you could possibly imagine.

The basic design concept was to have a single stereo input and three stereo outputs. Each output volume could be adjusted separately, and could be muted separately. A master mute button would mute and unmute all outputs together. Indicators on the device would show which outputs were muted, and which room was currently selected to adjust the volume and mute. Below is a diagram showing how the mixer works:

IR Mixer Block Diagram

Making it Go

Dan and I conceived the IR mixer idea at about 6pm when we were out looking for a Nintendo Gamecube. Unfortunately, since it was Sunday evening, our shopping experience was less than successful. In order to save myself from buying an overpriced Gamecube at the video store, we got a $17 universal remote control instead. This would keep me busy for a while and suppress the urge to get a video game console. (something I have never had, btw) By late last night I had most of the IR mixer working, and I finished it this morning.

I hooked up the IR receiver module and connected it to my scope so I could see the data from the remote. After a bit of looking on the web, I decided that the Sony protocol looked the best, and so I set the remote to Sony. The remote sends each code over and over when a button is held down, so it’s easy to look and see what the data looks like for each key. I was able to write down the codes for the keys I wanted to use. Sony uses a 12 bit code where the first 7 are the command (the button pressed) and the remaining 5 bits are the address of the device. Each device type uses a different address. Google for a more complete description of the data format.

The main part of my circuit is a PIC18F252 microcontroller running at 4MHz. I used the mcc18 C compiler from Microchip. The PIC controls the volume controls, decodes the IR remote codes, and drives the LEDs that indicate the current status.

Surprisingly it was very easy to decode the remote signals. I thought it would be the hardest part, but after tweaking the timing of my delays, it was working properly. I use PORTA bit 0 to read the IR codes and simply spin in an endless loop until the start of a code is detected. Then the code is read using some sanity checking and a carefully selected delay time. So far the code has worked perfectly in reading codes, and the IR module detects the remote from at least 25′ away.

I then wrote code that defines the behaviour of the device. There are 6 LEDs which show the currently selected room, and which rooms are muted. The number buttons 1, 2, and 3 on the remote select which room the volume and mute buttons will operate on. The remote we got has channel buttons which are located in a more ergonomic place, so my program supports both channel and volume buttons for changing the volume. Mute is accomplished by turning down the volume but saving the old volume value so that when unmuting, the old volume is restored. The 0 button on the remote mutes all rooms at the same time. They can be unmuted all together or individually and all will return to their previous volume settings when unmuted. There is currently no way to control all volumes at the same time, although I’m not sure that this is a desirable feature.

The actual volume controlling is accomplished with 2 x LM1973 digital pot chips. These chips have a clocked serial shift register interface using 3 lines. Each chip can control 3 channels and can attenuate from 0dB to more than -70dB, and then mute to -104dB. Because they have shift registers, they can be daisy chained so that a number of chips need only 3 wires connected to the microcontroller. I had played with the LM1973 many years ago, so luckily I had some lying around, and knew how to use them. Because the LM1973 is a passive resistor ladder, it has a high output impedance. Thus I buffered each output with a channel of a TL084 running at unity gain. Each LM1973 controls one of either the left or right channel, with all its inputs wired together. No input buffering is used. Also, no capacitors are used in the signal path, so the sound quality should not suffer very much.

There is a single simple routine that sends data to the LM1973. As the PIC runs only at 4MHz (1MIP) it is possible to bang the I/O lines at full speed without delays and still be well within spec of the LM1973 chips. Unfortunately, because I built my circuit on proto board, it was not practical to separate audio and data grounds or make ground planes, so at very low volumes data noise can be heard when changing the volume. When idle the circuit doesn’t seem to inject any unwanted noise into the audio paths.

Circuit and Code

Here you can download the schematic and a tarball of the C code used in the PIC. Use mcc18 for compiling. Don’t email me asking how to compile code or burn the PIC. There are plenty of good tutorials on the web. I would be glad to help anyone who appears to have done their homework. If you have questions or comments, please get in touch with me.

Updates

There are some minor tweaks to the circuit and code. Nothing too groundbreaking, but since we use this thing so much now, it’s nice to have it as close to perfect as possible.

Input Coupling Change

I found that when using a long cable to an unbalanced source located at a very different electrical potential, turning up the volume all the way caused a weird noise. I suspected a DC bias or something forcing the output opamps into a latchup condition. A bit of input coupling seems to correct this problem here’s what I added to each of the two inputs:

The input resistor R1 could be any low value around a few K. I used a large capacitor because hey, bigger is usually better when coupling audio. And R2 serves to provide a constant input load. This seems to make things better, and it sounds fine.

Conclusion

So far I am very impressed with the circuit. It didn’t take very long to make, I had all the parts laying around, and I learned about IR remotes in the process. Time will tell what features need to be added, but I think this will be a definitely useful addition to our music system.