blob: 01700cc1137a73aae1e8384acf0a077ed97ff795 (plain
This is a project for the Altera NIOS Development Kit, Cyclone
Edition, with an AleaREP Lancelot daughtercard (see
http://www.fpga.nl/). It should be easy enough to recompile for other
cards with a CompactFlash socket and binary audio output, just
reconfigure the pin list.
It plays music recorded on the CompactFlash card to the audio out;
currently it expects 44100 Hz 16-bit bigendian stereo sound to be
recorded; this is standard raw CD data.
There has been talk of an MP3 decoder on opencores.org; that could be
added too, of course.
My main goal in doing this was to test out the abilities of a digital
DAC. The Lancelot card only has a single bit audio output per
channel, connected to a low-pass filter with a 3 dB cutoff of only
about 10 kHz. The sound coming out of this design isn't stellar, but
it's definitely much better than you'd think.
Version 1 used a 12-bit PWM DAC, version 2 and 3 used a first-order
delta-sigma DAC clocked at 200 MHz, and version 4 uses a second-order
delta-sigma DAC clocked at 100 MHz.
I suspect most of the remaining noise is due to the analog circuitry,
and the low cutoff of the low-pass filter on this board.
Versions 1-3 were mono due to underrun problems. This turned out to
be a very silly problem -- cf_power was left floating, which resulted
in the CF card running out of power, depending on the access rate.
On a chip with DSP blocks it might be possible to get better
high-frequency response by applying a preemphasis filter; I haven't
explored that since my FPGA is a Cyclone (EP1C20) and doesn't have DSP
blocks. It also would increase the resource requirements hugely --
this design currently takes less than 400 LE.
The meaning of the LEDs are as follows:
D0 - CF card RDY#
D1 - CF card WAIT#
D2 - MSB of left channel
D3 - MSB of right channel
D4 - Left channel bitstream (intensity-modulated with amplitude)
D5 - Right channel bitstream (intensity-modulated with amplitude)
D6 - Data request
D7 - FIFO loaded
7seg - FIFO fill level (00 = empty, FF = full)