Contrary to some claims around the web, with the fast mode write the MCP4725 can produce credible, if low-fidelity, audio output. For example, see the demo at http://www.youtube.com/watch?v=lAZ0fpSPscw, which uses fast mode writes -- although it also uses quite a bit more and more complex code than is shown here.
Furthermore, the sample rate can be nearly doubled over the 11.025KHz used in that demo, while staying within the 'official I2C' clocking range, and it also appears to be possible to drive the MCP4725 with an I2C clock significantly above 400KHz without obviously ill effects.
/* -*- mode:C++ -*- * * Sketch description: Demonstration of driving an MCP4725 DAC via * I2C, using 'fast mode writes'. This sketch makes a fairly * plausible (and annoying) alarm sound, generating sawtooth waves * that repeatedly sweep upward in frequency (with the frequency also * changing in a sawtooth pattern, hmm). * * Schematic: * U1: IXM * U2: MCP4725 * * +--------------+ +--------------+ * VSS-|GND N U1 | D3-|VDD ANALOG|-> To some kind of amp * VDD-|D3 | GND-|VSS U2 | * SDA-|Tx LED | RX-|SCL | * |12V FACE E| TX-|SDA | * SCL-|Rx | +--------------+ * |D2 | * |GND S | * +--------------+ * * Sketch author: Dave * */ #define I2C_ADDR 0x60 // MCP4725 SFBHWI2C i2c(I2C_1); // Create object 'i2c', set up for I2C controller 1 u32 nextLevel = 0; // Sound level we're currently sending // INTERRUPT LEVEL: I2C 'next byte' function. u32 i2cByteSource(int bytes) { u32 ret; if ((bytes&1)==0) { // Every other sample, get new level u32 step = ((bytes>>8)&0xff)+70; // Determine current frequency bump nextLevel = (nextLevel+step)&0xfff; ret = (nextLevel>>8)&0xf; // Get high four bits to send } else ret = nextLevel&0xff; // Get low eight bits to send return ret; } void setup() { pinMode(WEST_D3_PIN,OUTPUT); // The DAC draws little power, digitalWrite(WEST_D3_PIN,HIGH); // so we feed it off an output pin.. i2c.init(I2C1_PINS_WEST_TX_RX,400); // Range is officially 100..400KHz, // but higher values also work // in this sketch (e.g., 800KHz) i2c.setByteSource(i2cByteSource); // i2c will call this for each byte i2c.transmit(I2C_ADDR, 0, 0); // Start an I2C transmission } void loop() { ledSet(NORTH_LED_PIN,millis()&0x40); // Of course need heartattack- ledSet(SOUTH_LED_PIN,!(millis()&0x40)); // inducing 'law enforcement' ledSet(BODY_RGB_RED_PIN,millis()&0xc0); // lights to go with.. } #define SFB_SKETCH_CREATOR_ID B36_4(d,a,v,e) #define SFB_SKETCH_PROGRAM_ID B36_5(a,l,a,r,m) #define SFB_SKETCH_COPYRIGHT_NOTICE "2011 Dave Ackley Placed in the public domain"