Delta-Sigma audio delay in Arduino?

Started by earthtonesaudio, December 05, 2011, 09:16:04 AM

Previous topic - Next topic

earthtonesaudio


g_u_e_s_t

i just remembered that that arduino has a built in comparator
so you can make the whole thing with just a resistor and capacitor
of course some input and output buffers would be nice too

i wrote up a quick test of this
its running at 2MHz sample rate
which is the fastest it can get through the loop
and its not storing anything to memory at the moment
but it wouldnt be too tough to use the internal memory
that would probably knock it down to 1MHz

heres the code if you want to try it


// 1 bit sigmadelta converter using arduino internal comparator
// there is a 2 clock cycle setup time on the comparator
//
// D5 = PD5 = digital output
// D6 = PD6 = AIN0 = comparator positive
// D7 = PD7 = AIN1 = comparator negative

void setup() {
  DIDR1 = 0x03; // turn off digital inputs for analog comparator
  ACSR = 0x00; // setup analog comparator
  DDRD |= (1<<DDD5); // set PORTD5 as output
  TIMSK0 = 0x00; // turn off delay timer to reduce jitter
}

void loop() {
  while(1) { // speeds up loop time
    byte input = ACSR & (1<<ACO); // get comparator data
    if (input == (1<<ACO)) {
      asm("nop"); // even up loop times
      PORTD |= (1<<PORTD5);
    }
    else {
      PORTD &= ~(1<<PORTD5);
    }
  }
}


im getting -60dB third harmonic distortion at 1khz
and this goes to -24dB at 5khz
but i think thats my capacitor being too big
im using a 10k resistor and 15nF capacitor for the filter

earthtonesaudio

That is very cool, thank you for sharing.  I'll try that as soon as I get a chance.

AdamM

This thread is looking quite interesting. I can visualise a pretty decent sounding digital delay with tap tempo & based around a handful of chips. Could fit in a 1590b...

Now, didn't somebody come up with a micro controlled LFO too? Modulated delay anybody? Add some serious low pass filtering, maybe some companding & we've got a Carbon Copy clone that goes to 1s and beyond.

I'd contribute more if I had the time to do more than just think & read about stuff like this - keep it coming guys, its good brain fodder!

defaced

#24
QuoteNow, didn't somebody come up with a micro controlled LFO too?
Yep. Electric Druid's Tap Tempo LFO, open source too (both functions, one chip?).  http://www.electricdruid.net/index.php?page=projects.taplfo
This project sounds interesting to me too, LFO madness only makes it sound more interesting.  
-Mike

DavenPaget

Quote from: free electron on December 13, 2011, 04:06:31 AM
Quote from: earthtonesaudio on December 12, 2011, 03:28:22 PM
Whether the ADC is clocked at 1MHz or just sampled at 1MHz seems to not matter very much in my mind.
There are two important facts if you a planning to use atmega328 for experiments:
1. The ADC converters are not 1bit Sigma-Delta, but 10bit successive approximation.
2. The max clock you can use for ADC at 10bit resolution is about 200kHz. It can go higher if you reduce the bit resolution.

Let's say the ADC is clocked at 200kHz, it doesn't mean that the sampling frequency will be the same value. The adc conversion process is split in two parts: sample&hold and conversion. Both use a multiple ADC clock cycles to complete. Take a look at the datasheet:
http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf
page 253
to see how the ADC module on Atmega operates.
Usually you'd need to set up a timer to trigger an interrupt at the required conversion frequency (f.e. 32kHz) and do all the process (sampling, storing in RAM, reading from RAM, sending to DAC) in the interrupt subroutine.

QuoteIt seems to me there are two main ways to get a variable delay time using two RAMs.  One way would be to vary the clock frequency.  Another would be to use a fixed clock frequency but use a variable amount of the available RAM.  For example write 1000 bits and then switch to the other RAM.  It seems like the second method would be less resource-intensive.
The usual approach is the second method + the use of interpolation techniques to calculate the values that are between the samples to get a smooth delay time change.

Here's another nice board to play with DSP:
http://www.st.com/internet/evalboard/product/252419.jsp
I've bought it recently for about 16EUR. Not bad for an 32bit MCU with 1MB flash, 192kB RAM (!), intergrated DAC ond lots of other interesting stuff.


Man ... i bought the STM32F4-Discovery , thanks for the discovery , literally ! ( 20$ SGD )
It's cheaper then a arduino !
Hiatus

earthtonesaudio

Just bumping this thread to say I got an Arduino Nano for Christmas, and I just ordered some memory chips.  Since my current plan involves only partially filling the SRAM, 64k versus 256k makes no difference, so I went for the 256k.  Perhaps I'll want more memory for something else in the future.

At the moment I'm a total Arduino Noob, so simply getting an LED to blink according to a program is a cause for celebration for me.  :)

DavenPaget

Hiatus

earthtonesaudio

The flash one is HUGE and has a lot of cool features, but it looks like it would need significantly more programming to get data in and out.
The 23k256 is exactly what I ordered, the main reason being the sequential r/w modes which would hopefully allow for simple programming.

DavenPaget

Quote from: earthtonesaudio on December 28, 2011, 02:51:18 PM
The flash one is HUGE and has a lot of cool features, but it looks like it would need significantly more programming to get data in and out.
The 23k256 is exactly what I ordered, the main reason being the sequential r/w modes which would hopefully allow for simple programming.
I bet it would do me useful in the future if i order both eh .  :icon_mrgreen:
Hiatus

earthtonesaudio


g_u_e_s_t

nice christmas present

i was looking at the 23k256 datasheet
and it says it runs off 3.3V
so be careful when connecting it to the 5v arduino
you might need to put a level shifter or resistors
on the data out lines

also note that the 3.3v rail on the arduino nano
is only available when usb is plugged in

earthtonesaudio

Yeah, thanks.  That part (hardware) is the easy part for me.  The part I'm struggling with now is figuring out how the physical pins connect to their names in the code you posted, and what the various commands do.  I'm doing my homework though.

g_u_e_s_t

my code is not in the traditional arduino language
which makes it a bit confusing
but the arduino commands take too long to execute

its written in C for AVR
if you have any specific questions
feel free to ask

if youre good with hardware
then the best place to start is with the arduino nano schematic
and the atmega328p datasheet
they list all the register names in the datasheet
and you can just write to them by name

otherwise you can get something up and running with the arduino language
and then make it go faster by working on a bit at a time

DavenPaget

Quote from: earthtonesaudio on December 28, 2011, 07:44:54 PM
Not a bad idea.   8)
Oh by the way , i found some EEPROM's that are cheaper then SRAM's ... What's the main difference between them ?
Hiatus

earthtonesaudio

EEPROM is ROM, so it's good for holding programs but not suitable as RAM.

DavenPaget

Quote from: earthtonesaudio on January 01, 2012, 10:05:39 AM
EEPROM is ROM, so it's good for holding programs but not suitable as RAM.
Forget it ... I found out DRAM is only SMD
Hiatus

earthtonesaudio

Quote from: g_u_e_s_t on December 31, 2011, 03:10:32 AM
my code is not in the traditional arduino language
which makes it a bit confusing
but the arduino commands take too long to execute

its written in C for AVR
if you have any specific questions
feel free to ask

if youre good with hardware
then the best place to start is with the arduino nano schematic
and the atmega328p datasheet
they list all the register names in the datasheet
and you can just write to them by name

otherwise you can get something up and running with the arduino language
and then make it go faster by working on a bit at a time

Okay, sure!  My first question:  is there a resource for learning all those speed-up tricks for arduino?
I have been perusing the atmega328 data sheet, particularly going between your code and the register and instruction set summary pages, but I could not find some of the names you used, such as DDRD.  
Also, could you explain why you used a compound bit wise or/and rather than a simple bit wise or/and?

Thanks again!

g_u_e_s_t

Quote from: DavenPaget on January 01, 2012, 10:08:32 AM
Quote from: earthtonesaudio on January 01, 2012, 10:05:39 AM
EEPROM is ROM, so it's good for holding programs but not suitable as RAM.
Forget it ... I found out DRAM is only SMD

there are dip dram
the 41256 for example
its 256k x 1bit
which is perfect for 1bit converters
jameco has good stock

g_u_e_s_t

Quote from: earthtonesaudio on January 01, 2012, 10:17:55 AM
Quote from: g_u_e_s_t on December 31, 2011, 03:10:32 AM
my code is not in the traditional arduino language
which makes it a bit confusing
but the arduino commands take too long to execute

its written in C for AVR
if you have any specific questions
feel free to ask

if youre good with hardware
then the best place to start is with the arduino nano schematic
and the atmega328p datasheet
they list all the register names in the datasheet
and you can just write to them by name

otherwise you can get something up and running with the arduino language
and then make it go faster by working on a bit at a time

Okay, sure!  My first question:  is there a resource for learning all those speed-up tricks for arduino?
I have been perusing the atmega328 data sheet, particularly going between your code and the register and instruction set summary pages, but I could not find some of the names you used, such as DDRD.  
Also, could you explain why you used a compound bit wise or/and rather than a simple bit wise or/and?

Thanks again!

i dont think there is a single resource for arduino tricks
but writing in C is usually a good first step
and can save hundreds of clock cycles

i dont have a great reference for learning C
i picked it up by reading "Kernighan and Ritchie"
but i wouldnt really reccomend that
perhaps ask around at avrfreaks.net

so the register DDRD is the Data Direction Register for port D
you will probably find it in the datasheet listed as DDRx
as there is one for every port (DDRB, DDRC, etc)
there is also PORTC, PORTD for the port register and PIND, PINC for the pin registers
each pin can be acessed via PORTB1, or PINB1, etc
DDRx sets wether its an in or an out
PORTx sets an output to high or low
PINx reads an input to see if its high or low

so if you want to set PORTB1 as an output you could do it one of 3 ways
DDRD = 0x02; (or 0b00000010, or (1<<PORTB1))
DDRD |= 0x02;
DDRD = DDRD | 0x02; (does the same as the one above)

the |= 0x02 will ensure that you only set the bit you want to change
and the rest will be left alone
the = 0x02 will change the whole port

people generally use the format DDRD |= (1<<PORTB1), and DDRD &= ~(1<<PORTB1)
to make sure they only set the bits they want
and so it easy to understand which pins are being changed