I am busy with making a nice arduino synth and allready chose for an IC DAC (TDA1543) and dual opAmp(NE5532). I started reading the datasheet and figured out that it was not that simple. What i've learned is that you need too clock serial data too the DAC and also use a Bit Clock Input too time the clock's. I don't really know a lot about serial writing in 16-bit.. (by the way there is also a word select input, but for now i'm using mono)
My question is: How do i produce 16-bit serial data and send it too the DAC? Is there any reverence material? Any libraries even maybe?
Anybody had any experience with it yet?
Here is a scheme i made, and figured out i needed also a amplifier before sending it too the speaker (bye the way this one is not mono, but i changed my mind about that) It's also saying it's pwm, but i know now that you must use serial.
That data sheet shows the DAC using I2C protocol to clock data into it. The Arduino site has a library of software routines to support I2C called the "wire" library.
Thanks, it's a lot clearer now... i'd never heard of that protocol!
If i understand it right. i have too send 16-bit data too the DAC and the DAC will translate it into sweet sounds :)... How do i know how fast i have too update these messages? What is the theory behind making 16-bit sinus waves?
I understand for instance that with the PWM synth method you can control the frequency by speeding up or slowing down the delay()'s, i understand that part, but how is this done with a 16-bit data string? I think i don't know enough about audio generating...
I'm not that experienced with DAC audio applications, but there is a relationship between the highest audio frequency you wish to process and how fast you have to send the data to the chip. Something about Nyquist theory that the sample rate has to be at least twice the speed of the highest frequency to be produced or reproduced.
I'm sure there is more experienced people around here to help you, but the first fact to be verified is can the Arduino will move data fast enough to the DAC to be able to reproduce the audio frequency range you wish to process?
Two things,
First that diagram will not work. Not only is the interface to the Arduino not right (as mentioned above) but the wiring to Vref is not right. This is a voltage reference, look in the data sheet to see what value it should be.
When you have sent a 16 bit word to the D/A you will have a DC voltage level on the output. So you have to keep on sending them to get an AC waveform. You also need a filter on the output of the D/A to remove the quantisation noise, that is the noise generated at your sample rate. You don't have to bother if you can feed samples at greater than 25KHz or so but otherwise you have to have one to prevent the high pitch whine.
To produce a sin wave you are best to have a look up table of how ever many samples you want, 20 is a good number, and feed them continuously into the A/D. To change the frequency you can do one of two things:-
Change the number of samples and feed them at the same rate.
or
Change the rate you feed the samples in and keep the number of samples the same.
That data sheet shows the DAC using I2C protocol to clock data into it. The Arduino site has a library of software routines to support I2C called the "wire" library.
Actually the datasheet says the DAC uses the I2S protocol. I figured out it also workes with serial data, but i'm not sure where they are different from eachother. In general i know that ones you outputted the signal you have to send a bit too the data-clock or something like it too "confirm" the data, but i don't really understand the working of this.
Is there anyone with experience in Arduino and the I2S protocol, does it works similar as the I2C protol?
I don't even understand the basics of how too send serial sound data, for instance how can i generate a simple tone like in "playing melodys with an piezo speaker" tutorial in the learning part, but then trough a DAC?
I hope somebody can help me on my way in understanding this.
The I2S protocol isn't the same as the I2C as far as I remember. I also remember getting confused with the difference at first (oh sweet! this supports the protocol!...wait...). If you look at pg 9 in the datasheet it shows you how the I2C protocol works. You need to generate a 9.2 MHz bit clock (just up-down-up-down-up-down) and a feed data (LSB first) at the same rate but with a slight phase offset (2ns it says). Every 16 cycles of BCK you flip the word clock to feed the other channel.
The protocol itself is pretty simple, generating that 9.2MHz bit clock...hmm..not so much. One saving point might be that it says 9.2Mhz is the minimum rate, so you might be able to get away with 10 or 12 Mhz by dividing down the arduino's own clock.
I2S is only used in sound chips (hence inter-ic sound). It suuuure would be nice if somebody would write a library for it...WINK WINK NUDGE NUDGE
Quick digital audio primer, hopefully this helps your understanding - 16 bit sound means that for each sample you represent it by a word that has 16 "letters", those letters being 1 or 0. Obviously you can spell more words with 16 spaces than you can with 8 or 12. Now to make a sound you string a bunch of 16 bit samples together and play them back at an appropriate rate. That rate must be 2x the highest frequency you want to generate (called the Nyquist Freq). So for human hearing the highest pitch is 20kHz (really ~16kHz for most people) so you need to have your DAC spit out samples at 40kHz+. In CDs the sampling rate is 44.1kHz, and in most pro audio stuff its 48kHz (or more).
Now your DAC handles the rate thing, you just need to feed it samples. You can either blast 16 bits at it every 1/40,000th of a second - this is called parallel data - or feed it one bit at a time 16 times as fast which is called serial data. In parallel you would need 16 data lines and probably a clock line too, in serial you need 1 data line and 1 clock line.
Fun Fact - Generating sinusoidal tones for audio synthesis is kind of a pain in the neck. Generating a sinusoid of one freq easy, making one tunable over 3 decades...not so much. As Mr. Mike pointed out the easiest way digitally is to use a lookup table. More points = better sine.
I would start with a simple square or saw just to get started then go on to sines or more complex waveforms (aka wavetable synthesis).
Hope that helps / hope somebody has some idea of how to make 9.2Mhz bit clocks.
I've allready read about a couple of solutions for the clock speed, it was in a reference link from a synth code from the arduino website (i can't find it right now), but they where talking about 2 ways of getting the clock speed on a surten (9.2Mhz) speed, One was to write bits double.
The other one was to only skip a bit (or 16-bit's for the paralel way) when the "new clockspeed" was reached. Soo then i have to check: 16/9,2 = 1,74... Then i know that if i would devide the 16 Mhz trough the 1,74 i would get the 9,2 Mhz and by that know i have too skip 26 of the 16 Mhz cycles too get too 9,2Mhz?(i made a jump in the math: 1,74 is 74% of 16 Mhz, soo to get to 100% i would need to add 26%)
Is this indead a solution for getting 16Mhz too 9.2Mhz? But it's simpeler if it would run also at 10 Mhz etc.
I would really like a library for I2S also, and i would like too try too write this, BUT i'm a beginner in microprocessors, i do know some programming, but it streches not as far as microprocessors.
Whoops I just realized the max BCK is 9.2Mhz (that's what i get for writing this at 3am), so you could just divide the arduino's clock by some int to get 8, 4, 2mhz whatever. My thought is to try 4 or 2 so that you have enough time for processing samples, e.g. the arduino runs at about 1 MIPS / Mhz so having a few extra instruction cycles could be handy.
Yes that is wavetable synthesis, but it seems silly to use wavetables for easily rendered waveforms like square/saw/triangle.
Saw - just count up +1 (or down)
Sqr - 1 for half the time, 0 for the other
Tri - count up for half the time, down for the other half
It would be a better use of memory to load up complex waveforms (i think, maybe the arduino can't produce the basic ones in fast enough).
here they are working with the interupt library, is this library possible too use too get the 16Mhz too another clock speed. I'm also asking myself, if it's minimal 9,2 Mhz, can i not use the 16 Mhz full speed clock of the arduino or will that be an overkill for the DAC?
Is there anybody capable and willing too write an I2S library, i would like too help for as far as i can, and i came pretty far on my one i think (with a lot of help, from you guys ;)) I don't know how difficult it really is; what problems will accure in the future