A/D to D/A audio conversion

I want to build a project that starts with analog audio (from an external source like a CD player) and is converted to digital (A/D conversion) then in turn sent to an D/A converter to convert it back to analog. The experiment would show the effects of digitization of a live audio signal. I will be using an external analog audio input source and external oscilloscope to analyze the analog output. (1.) Not sure if Arduino blocks can handle live audio frequencies nor (2.) what blocks I would need to buy. Thanks for your help.

I think your experiment has a fatal flaw. CDs have digital data.

...R

I would be using the analog output of a CD player or some other analog audio source but the source would be analog. Yes a CD is digitally recorded but the output is from a D/A converter and is analog. In any event the input will be compared to the output to see the effects of digitization. A pure analog signal generator could be used for the test as well. The question is.... is it possible?

Sure it is. Millions of devices have that function, for example smart phones. I'm pretty sure you can find DAC and ADC boards for Arduino, although I haven't played with them yet.

The question is.... is it possible?

Yes it is, you don't even need an Arduino.

The experiment would show the effects of digitization of a live audio signal.

There are two aspects to this:- 1) Quantisation error - the loss of date in constricting the amplitude to fixed levels, that is not continuously variable. Given by the resolution ( number of bits ) of the conversion.

2) Sampling error - in effect the quantisation of the time axis, cutting it in to discrete parts. Given by the sample rate.

The results of applying digitization on an audio signal range from - Can't tell any difference to crap.

Do you plan to change these two factors? Not much point in the experiment if you don't.

Incidentally when I was researching this in the mid 70s my favorite academic paper title was:- "The effects of alcohol on perceived quantisation noise" Basically the more you drink the less you care, who would have thought that!

LaryyD: I would be using the analog output of a CD player or some other analog audio source but the source would be analog.

The point I did not make clearly is that when people complain about the sound quality from CDs it is the AtoD process that has already taken place that they complain about. I have cloth ears and I prefer the signal to noise ration of CDs compared to vinyl.

For your test to be meaningful you must start with a genuine analog signal that has never been digitized.

...R

Not sure if Arduino blocks can handle live audio frequencies nor (2.) what blocks I would need to buy.

From what I understand, the Arduino's ADC can only sample at around half the 44.1kHz sample rate of a CD. And of course, it's only 10 bits.

The Arduino itself should be able read/write fast enough for CD-quality audio if you use an external ADC & DAC. But if you just want to test the effects of A/D and D/A conversion, you don't need the Arduino in-between your ADC & DAC. ;)

The experiment would show the effects of digitization of a live audio signal.

Your soundcard can so that, although there will be a short delay (multitasking computers require input/output buffers).

Or if you don't mind a longer delay, you can record and then play back. For a line-level signal (from a CD player, etc.) you need a "regular" soundcard with a line-input. The mic input on a laptop will "work" but it's a mismatch and you'll get poor sound quality.

Of course, the results will depend on the quality of your ADC & DAC. Some consumer soundcards are noisy. But with a half-way decent ADC & DAC there will be no audible difference, although there may be a measurable difference (but probably not enough difference to see on a 'scope.) That's assuming your ADC & DAC are running at the same or better resolution than the original CD.

The "standard experiment" would be to compare the original to a recording where the recording has gone through the extra A/D & D/A conversions. Experiments have been done with several generations of conversion & recording to show there's no audible damage done by the conversion process.

If you have two digital recordings, you can easily subtract one from the other with an audio editor to get the difference. But, you do have to be carefulwiht the results because the sound of the difference is NOT the same as the difference in sound... Of course, if subtraction shows no difference there can be no difference in sound, but something like a few milliseconds of delay will create a "huge and loud" comb-filtered difference file, although there is no difference in the sound.

Great information just what I needed. I’ll just build an A/D to D/A board. Thanks to everyone for their input!

If your intent is to show the effects of digitization you can use a Due. It has an ADC and a DAC and is faster than a Uno. It will not reproduce the sound with CD quality but your stated goal is to show the theoretical effects of digitizing, not to reproduce CD quality. The quality will not be all that bad. You will be able to tinker with the resolutions of the ADC, DAC, and sampling time.

You can pick up a knock off Due for about $17.

I'll see if I can pick one up. That would save some time. Thank you!

Here is something to try. Produce a tone on the Due, send it out the first DAC (the Due has 2 DACs) and route it to the ADC input, then route the ADC input to the second DAC. Now you will have two DAC outputs to compare: (1) the original tone, and (2) the reproduced tone through the ADC and second DAC.

Here is the code to do it…

#include <DueTimer.h>

#define SYNTHOUT    DAC0
#define DACOUT      DAC1
#define ANALOGIN    A5

const float pi = 3.14159 ;
float T = 20 ;    // sample time in microseconds
const float freq = 2000 ;  // frequency of tone in hertz
const float omega = 2*pi*freq ;
const float A = 490 ;  // amplitude
// next line initializes oscillation with amplitude A
float a[3]={0.0, A*sin(omega*T/1000000.0),0.0}; 
// c1 is the difference equation coefficient
const float c1 = (8.0 - 2.0*pow(omega*T/1000000.0,2))/(4.0+pow(omega*T/1000000.0,2));

void setup()  { 
  pinMode(SYNTHOUT, OUTPUT);
  analogWriteResolution(10);
  analogReadResolution(10);
  Timer1.attachInterrupt(compute );
  Timer1.start(T) ;
} 

void loop()  { 
} 

void compute(){
  a[2] = c1*a[1] - a[0] ;  // recursion equation
  a[0] = a[1] ;
  a[1] = a[2] ;
  analogWrite(SYNTHOUT, 500 + a[2] );
  analogWrite(DACOUT, analogRead(ANALOGIN));
}

Fantastic. Thank you again!

charliesixpack Got the SainSmart DUE. Ran the blink program OK. Ran the "Hello" program OK, so have it working to that point. I pasted your code into IDE and got the following error code. I'm sure I'm doing something wrong. First one is with verbose turned off...

Arduino: 1.6.6 Hourly Build 2015/09/11 02:42 (Windows 10), Board: "Arduino Due (Programming Port)"

Build options changed, rebuilding all sketch_sep12a:9: error: stray '#' in program sketch_sep12a:9: error: 'include' does not name a type sketch_sep12a:18: error: 'pi' was not declared in this scope sketch_sep12a.ino: In function 'void setup()': sketch_sep12a:25: error: redefinition of 'void setup()' sketch_sep12a:1: error: 'void setup()' previously defined here sketch_sep12a:29: error: 'Timer1' was not declared in this scope sketch_sep12a.ino: In function 'void loop()': sketch_sep12a:33: error: redefinition of 'void loop()' sketch_sep12a:6: error: 'void loop()' previously defined here stray '#' in program

This report would have more information with "Show verbose output during compilation" enabled in File > Preferences. ...............................................................................................

Verbose version

Arduino: 1.6.6 Hourly Build 2015/09/11 02:42 (Windows 10), Board: "Arduino Due (Programming Port)"

C:\Users\Larry\AppData\Local\Arduino15\packages\arduino\tools\arm-none-eabi-gcc\4.8.3-2014q1/bin/arm-none-eabi-g++ -c -g -Os -w -ffunction-sections -fdata-sections -nostdlib -fno-threadsafe-statics --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -Dprintf=iprintf -MMD -mcpu=cortex-m3 -DF_CPU=84000000L -DARDUINO=10606 -DARDUINO_SAM_DUE -DARDUINO_ARCH_SAM -D_SAM3X8E_ -mthumb -DUSB_VID=0x2341 -DUSB_PID=0x003e -DUSBCON -DUSB_MANUFACTURER="Unknown" -DUSB_PRODUCT="Arduino Due" -IC:\Users\Larry\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.4\system/libsam -IC:\Users\Larry\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.4\system/CMSIS/CMSIS/Include/ -IC:\Users\Larry\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.4\system/CMSIS/Device/ATMEL/ -IC:\Users\Larry\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.4\cores\arduino -IC:\Users\Larry\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.4\variants\arduino_due_x C:\Users\Larry\AppData\Local\Temp\build7972189213562191603.tmp\sketch\sketch_sep12a.cpp -o C:\Users\Larry\AppData\Local\Temp\build7972189213562191603.tmp\sketch\sketch_sep12a.cpp.o sketch_sep12a.ino:9:2: error: stray '#' in program sketch_sep12a.ino:9:3: error: 'include' does not name a type sketch_sep12a.ino:18:23: error: 'pi' was not declared in this scope sketch_sep12a.ino: In function 'void setup()': sketch_sep12a.ino:25:6: error: redefinition of 'void setup()' sketch_sep12a.ino:1:6: error: 'void setup()' previously defined here sketch_sep12a.ino:29:3: error: 'Timer1' was not declared in this scope sketch_sep12a.ino: In function 'void loop()': sketch_sep12a.ino:33:6: error: redefinition of 'void loop()' sketch_sep12a.ino:6:6: error: 'void loop()' previously defined here stray '#' in program

Seemed to be missing DueTimer.h so found one on the internet. Now it is loading but no output at DAC).

sketch\sketch_sep12d.cpp.o: In function setup': C:\Users\Larry\Desktop\DUE\arduino-nightly/sketch_sep12d.ino:21: warning: undefined reference toDueTimer::attachInterrupt(void (*)())' C:\Users\Larry\Desktop\DUE\arduino-nightly/sketch_sep12d.ino:22: warning: undefined reference to Timer1' C:\Users\Larry\Desktop\DUE\arduino-nightly/sketch_sep12d.ino:22: warning: undefined reference toDueTimer::start(long)'

Sketch uses 34,472 bytes (6%) of program storage space. Maximum is 524,288 bytes. Erase flash Write 36716 bytes to flash

[ ] 0% (0/144 pages) [== ] 6% (10/144 pages) [==== ] 13% (20/144 pages) [====== ] 20% (30/144 pages) [======== ] 27% (40/144 pages) [========== ] 34% (50/144 pages) [============ ] 41% (60/144 pages) [============== ] 48% (70/144 pages) [================ ] 55% (80/144 pages) [================== ] 62% (90/144 pages) [==================== ] 69% (100/144 pages) [====================== ] 76% (110/144 pages) [========================= ] 83% (120/144 pages) [=========================== ] 90% (130/144 pages) [============================= ] 97% (140/144 pages) [==============================] 100% (144/144 pages) Verify 36716 bytes of flash

[ ] 0% (0/144 pages) [== ] 6% (10/144 pages) [==== ] 13% (20/144 pages) [====== ] 20% (30/144 pages) [======== ] 27% (40/144 pages) [========== ] 34% (50/144 pages) [============ ] 41% (60/144 pages) [============== ] 48% (70/144 pages) [================ ] 55% (80/144 pages) [================== ] 62% (90/144 pages) [==================== ] 69% (100/144 pages) [====================== ] 76% (110/144 pages) [========================= ] 83% (120/144 pages) [=========================== ] 90% (130/144 pages) [============================= ] 97% (140/144 pages) [==============================] 100% (144/144 pages) Verify successful Set boot flash true CPU reset.

Problem seems to be with the libraries. Larry

sketch\sketch_sep12e.cpp.o: In function setup': C:\Users\Larry\Desktop\DUE\arduino-nightly/sketch_sep12e.ino:21: warning: undefined reference toDueTimer::attachInterrupt(void (*)())' C:\Users\Larry\Desktop\DUE\arduino-nightly/sketch_sep12e.ino:22: warning: undefined reference to Timer1' C:\Users\Larry\Desktop\DUE\arduino-nightly/sketch_sep12e.ino:22: warning: undefined reference toDueTimer::start(long)'

Sketch uses 34,472 bytes (6%) of program storage space. Maximum is 524,288 bytes. Erase flash Write 36716 bytes to flash

[ ] 0% (0/144 pages) [== ] 6% (10/144 pages) [==== ] 13% (20/144 pages) [====== ] 20% (30/144 pages) [======== ] 27% (40/144 pages) [========== ] 34% (50/144 pages) [============ ] 41% (60/144 pages) [============== ] 48% (70/144 pages) [================ ] 55% (80/144 pages) [================== ] 62% (90/144 pages) [==================== ] 69% (100/144 pages) [====================== ] 76% (110/144 pages) [========================= ] 83% (120/144 pages) [=========================== ] 90% (130/144 pages) [============================= ] 97% (140/144 pages) [==============================] 100% (144/144 pages) Verify 36716 bytes of flash

[ ] 0% (0/144 pages) [== ] 6% (10/144 pages) [==== ] 13% (20/144 pages) [====== ] 20% (30/144 pages) [======== ] 27% (40/144 pages) [========== ] 34% (50/144 pages) [============ ] 41% (60/144 pages) [============== ] 48% (70/144 pages) [================ ] 55% (80/144 pages) [================== ] 62% (90/144 pages) [==================== ] 69% (100/144 pages) [====================== ] 76% (110/144 pages) [========================= ] 83% (120/144 pages) [=========================== ] 90% (130/144 pages) [============================= ] 97% (140/144 pages) [==============================] 100% (144/144 pages) Verify successful Set boot flash true CPU reset. Invalid library found in C:\Users\Larry\Desktop\DUE\arduino-nightly\libraries\examples: C:\Users\Larry\Desktop\DUE\arduino-nightly\libraries\examples Invalid library found in C:\Users\Larry\Desktop\DUE\arduino-nightly\libraries\examples: C:\Users\Larry\Desktop\DUE\arduino-nightly\libraries\examples

charlessixpack

Problem solved. Just needed to load the proper libraries. The DueTimer library in particular. Now I have 2k output as it should be. Now I can go on with the experiment. Thanks for your help and providing the code. Could not have done it without your kind help. Have a great day. Larry

Larry, I just saw that you were having problems. Glad to see it's working now.