Hiya all! XD
I've written a simple function to output analog samples through the arduino uno's digital pins using pulse density modulation.
To use, just call it from the loop() section of your sketch. As it works fully in software, the more times you can call it per second, the better it will work!... heh, heh... hopefully your loop runs really fast
So, without further ado:
/*
  playPdmSample8( pin, sample, sampleRate_ms )
 Â
  Plays back the appropriate sample on the indicated pin
  and returns the number of samples to increment for playback
  at the given sample rate.
 Â
  Maintains data for each pin -- you could use all fourteen at once!
  pin       - the digital pin to use as output
  sample     - the 8-bit sample to play
  sampleRate_ms  - number of samples to play per ***MILLISECOND***
*/
static unsigned long playPdmSample8(int pin, byte sample, unsigned long sampleRate_ms) {
  // Pulse density modulation data (pin-dependent)
  static byte      err[14]  = {};
  static byte      out[14]  = {};
 Â
  // Sample rate data
  static unsigned long time[14] = {micros()}; // Relative starting time ***IN MICROSECONDS***
  static unsigned long sampleIncr = 0;      // Number of samples to be incremented to maintain sample rate
 Â
  sampleIncr = (sampleRate_ms * (micros() - time[pin])) >> 10; // The bit shift is a hackish divide-by-1000
 Â
  if(sampleIncr >= 1) {
    // Output a sample using pulse density modulation
   Â
    if(sample > err[pin]) {
      if(out[pin] == 0) {
        digitalWrite(pin, HIGH);
        out[pin] = 255;
      }
    } else {
      if(out[pin] == 255) {
        digitalWrite(pin, LOW);
        out[pin] = 0;
      }
    }
   Â
    err[pin] += (out[pin] - sample);
   Â
   Â
    // Reset the time
    time[pin] = micros();
  }
 Â
  return(sampleIncr);
}
Hopefully you find this marginally useful or at least marginally interesting!