1. the Vref generator can be used as a DAC (pin 25 on PIC32MX250F128B). While 4-bits of dynamic range is not going to hack it for playing back Grateful Dead albums, it is good enough for a quick sound effect or medium quality voice production. There are several steps. First get a low dynamic range WAV file. I use the AT&T text-to-voice site to produce aWAV file with a male voice saying the digits zero to nine. Then the WAV file is processed with a Matlab program to adjust the sample rate, truncate the PCM values to 4-bits, then pack two four bit samples into each byte for storage efficiency. Next the Matlab program produces a header file of the packed samples formated so that it is loaded into flash memory. Then the playback programrunning on the PIC32 traverses the packed array at 16 KHz and drops the unpacked samples onto the Vref DAC. The low sample rate means that the male voices at the AT&T site sound better because we can more heavily filter and not lose too much voice content. The following image used matlab's spectrogram utility to compare the original and 4-bit quantized sounds. The top image is the 8 KHz sampled voice. The bottom image uses the signal quantized to 16 levels, then lowpass filtered with a RC filter with a cutoff of 1700 Hz. Each digit (0 to 9) is visible and the overall structure is the same, but not as crisp. The actual playback circuit used an RC filter consisitng of a 100k resistor and 1nf capacitor to get the lowpass. The quantized, filtered matlab output sounds very much like the PIC output.
    spectrogram
    -- The 4-bit data is highly redundant. Looking at the difference between sequential samples shows that over 98% of the transitions between sequenctial samples are plus/minus one or zero. This means that if we encode the difference as a two bit number, we can make a smaller header file without losing too much information. The matlab encoder takes the differences, truncates them, resynthesises the wave from the truncated derivitive and plays the digits. Still to be done: Pack the four 2-bit difference samples into one byte and write the header file and decoder in C. The following images show the spectrogram of the raw speech after sampling to 8 kHz and the spectrogram of the waveform reconstructed from 2-bit differences.
    dcpm spectrogram
  2. Using Vref output as a 4-bit DAC, following the lead of Tahmid's Blog
    -- The Vref generator can be connected to an external pin (pin 25 on PIC32MX250F128B) and can be set to 16 values between zero and two volts. The first example generates a 16-sample square wave to investigate the settling time of the DAC. According to the Reference Manual, the output impedance at output level 0 (about zero volts) is about 500 ohms, while the output impedance at output level 15 (about 2 volts) is around 10k ohms. The first screen dump shows the Vref voltage output on the bottom trace and the same signal passed through an LM358 opamp, set up as a unity gain impedance buffer, on the top trace. Rise time (level 15) is about 0.5 microSec (to 63%) and fall time (level 0) is about 0.05 microSec. The rise/fall times are dominated by the RC circuit formed by the output impedance of Vref and the capacitance of the white board (10-20 pf) and the scope (20 pf). The LM358 is slew-rate limited and thus produces a triangle wave.
    -- The next example generates a sawtooth with a period of 128 phase increments (17.4 kHz). The bottom trace is taken directly from the Vref pin, while the top trace is from the output of the unity gain LM258 follower. Notice the slew-rate limiting on the falling edge of the sawtooth.To unload the Vref pin, the output was connected to the opamp follower through a 100k resistor. A lowpass filter using the 100k resistor and a 10 pf capacitor with a time constant of around 1 microSec smooths and denoises the opamp trace (third image).
    raw rise time sawtoothsmoothed sawtooth
    -- Any real application is going to use ISR-driven timing to output samples to the DAC. The next example uses Direct Digital Synthesis (DDS) running in an ISR at 100 kHz to generate sine waves. Tiiming the ISR using a toggled bit in MAIN, suggests that the 47 assembler instruction ISR executes (with overhead) in 1.5 microSeconds. The first image shows the DDS sine wave (but at very high frequency) on the top trace and the bit being toggled in MAIN on the bottem trace. You can clearly see the 1.5 microsecond pause in MAIN every time a new sine wave value is produced. The second image is a sine generated at Middle C (261.6 Hz). The top trace in the lowpassed opamp output. The bottom is the raw Vref pin.The code is structured as a timer ISR running the DDS. The output frequency is settable within a millHertz, but accuracy is determined by the cpu clock. Sixteen voltage levels introduces some harmonic distortion. The first error harmonic is about a factor of 30 in amplitude below the fundamental and at 3 times the frequency. This is in line with Bennett for 4-bit signals. The matlab image shows the full and 16-level sampled sine waves on the left and their spectra on the right (code). Listening to the signal gives a sense of very high frequency spikes. Lowpass filtering with a time constant equal to about 1/(sample-rate) gets rid of most of the sampling noise..
    DDS DDS middle C
    distortion