USB Audio Streamer A Microchip PIC based USB sound card
The idea for creating a USB sound card based on a PIC came from discussions of other people creating one on the Microchip USB forum. The hardware of the card is based on all Microchip products. The software uses a modified version of the Microchip USB framework which is interrupt driven instead of the traditional polling. The device is a USB composite device. The first device is an implementation of the USB Audio 1.0 interface and the other device is a custom interface based on a HID interface. The purpose of the custom interface is for programming the device serial number, upgrading the firmware, and in the future any other configuration that isn’t supported directly by USB Audio 1.0. In a previous version, WinHTTP was oringally used. After testing the card for awhile, I decided it’s better to not require drivers for the card especially since the HID/WinUSB interface is rarely used.
The sound card runs at a sample rate of 48KHz, 32KHz or 24KHz selectable by the OS with 12 bits per sample. The quality approaches commercial grade as the sample rate is higher then CDs. 44.1KHz was not implemented due to the difficultly and additional processing overhead. The sample rates that were implemented are all a multiple of the 1ms USB frame meaning each frame sends the same amount of data. 44.1KHz requires the card to handle different amounts of data each frame requiring more advanced buffering and synchronization techniques and more processing power. Microsoft Windows automatically resamples the 44.1KHz audio found on CDs to 48KHz.
The hardware for the sound card is based on the Microchip PIC18F2550 USB processor. The processor is clocked at 48MHz which is the maximum rate for this processor and is also a multiple of the audio sample rate. The microcontroller is connected via the SPI port to duel Microchip MCP4822 12bit D/A converters. Volume control is implemented by the Microchip MCP41010 variable res– ders are controlled via SPI by the microcontroller via a dedicated bit-banged SPI port. The purpose of using a separate port is so that volume control can run inside the processor at a different priority level then sample output. The Microchip MCP6022 op-amp is used as an output driver.
The MCP6022 op-amp has an output drive capacity large enough to power a pair of cheap headphones without much distortion. The resistance of my headphones is approximately 25ohms. The op-amps are not powerful enough to drive speakers which are usually 8 or 4 ohms. The MCP41010 and MCP6022 can output near rail to rail voltage although some nonlinear effects can be heard if the volume is too loud or the signal is near the minimum or maximum. Since USB has a single rail 5V power supply, the sound card only uses a positive rail instead of a traditional duel rail system which is how standard 16bit PCM is encoded. As a result, the signal needs to be biased in software to 2.5V.
One terminal of the MCP41010 is connected to the signal for that channel and the other terminal is connected to the midpoint or bias voltage. Previous versions of this sound card connected the second terminal to GND. The advantage of connecting the terminal to the bias is that as the volume is changed, the signal grows or shrinks around the midpoint rather then shifting toward GND. The signal is kept as far away from the rails as possible.
The software for USB Audio Streamer is composed of several components. These are the audio card firmware, a C++ library that wraps HID and WinUSB, and a command line utility for flashing. I am giving out the source code as a learning tool for other people. I don’t care what you do with it but I am not responsible for any damage that might happen from using it. NOTE: Improper use of hardware or software may cause serious injury or death.:)
I use Visual Studio 2005 Professional but I have heard that the project will build with Visual Studio Express. To build the project it is necessary to download the latest version of the WDK to get the headers and library files for HID and WinUSB. The default directories in Visual studio need to be modified to point to the directories of these resources in the WDK. If you use Visual Studio Express it’s necessary to recreate all the project files and change the default calling convention to _stdcall.
inc General Include Directory
boot Boot Loader(Build first)
audiostream Sound card firmware
usbdevprogramer Programmer command line utility(Build last)
A trick is used when building the sound card firmware since it is two separate projects that need to be merged together. Build the boot directory first, which is the code responsible for upgrading the firmware. Then build the sound card firmware itself. Before flashing, goto Configure/Settings/Program Loading and clear the option to clear program memory upon loading a new program. After the sound card firmware is build, goto file/import and import the hex file for the boot loader. The two projects will be merged together without any cutting and pasting. At this point, it is OK to flash the PIC. Note the bootloader is only necessary for flashing firmwares without a ICD/Pickit. When debugging actual card functionality, it’s ok to leave out the bootloader. This Requires no modifications to the sounce or linker scripts. Simply don’t merge the boot loader into the image
SOUND CARD FIRMWARE
The sound card firmware is based on a modified version of the Microchip USB framework. The framework has been collapsed into a single source file with callbacks between the framework and the main code. The framework( in my case it’s more of a library ) has been modified to use interrupts instead of the traditional polling method. Instead of calling USBDriverService in a loop, this function is called whenever the USB interrupt fires. The library is response for handling control requests on endpoint 0. The framework handles standard USB requests and the body code is responsible for handling class specific USB requests nonstandard requests. The body code is responsible for handling I/O on all other endpoints.
USB Audio Streamer is a composite device of a USB Audio 1.0 device and a custom HID interface. With USB Audio 1.0 all of the sample data is transferred through a separate endpoint then control requests. Control requests such as controlling volume is through endpoint 0(the control endpoint.) HID uses it’s own endpoint. Since each function of the card has a separate endpoint, each of the functions can be implemented at a different priority level without preemption problems. The PIC18F2550 has two interrupt priorities plus the main handler. This gives a total of three priorities. Since playing sound data is the most critical function it was given the highest priority. Next comes control endpoint requests which include the standard requests plus Audio 1.0 requests. Since these functions have relatively low timeouts, these were assigned low priority. HID functions are in the main body code because actions such as querying the firmware version, settings the serial number, or flashing the firmware are not time critical at all.
For more detail: USB Audio Streamer A Microchip PIC based USB sound card
EasyEDA: Ideas for Circuit Design, Innovation for Electronics Access
Free Circuit Design: Schematic – Simulation – PCB Layout – Gerber Viewer
JLCPCB Prototype: Only $2 for 10pcs 10×10cm, 24 hours Quick Turn, DHL Delivery in 3 days
Current Project / Post can also be found using:
- microprocessor sound project
- pic microcontroller audio projects