Go Down

Topic: Real Time Audio Processing (Read 3352 times) previous topic - next topic

MarkT

By static do you mean aliasing/quantization noise?  Do you have a sample of this to listen to?

What frequency is timer2 running at?
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Lucario448

What frequency is timer2 running at?
Assuming the typical 16 MHz clock frequency, then the interrupt is firing up at a rate of 64.25 KHz (every 15.56 microseconds).
Although with the ADC's default prescaler, effective sampling rate is more like 10 KHz or even less. Successive approximation ADCs aren't known for fast conversions; so in order to achieve high sampling rates, their clock shouldn't be too slow.





PD: the map() function is rather slow also. The CPU is 8 bits "wide" (against the 32-bit variables it uses inside), and its ALU lacks integer division support (such operation is actually done in software, and the function needs it).
Since you're scaling two power-of-two-wide ranges, the fastest way to accomplish the same result, is to move around some bits. Narrowing 10-bit values into an 8-bit input is possible simply by discarding two least significant bits (aka right shift 2 bits). In the end, it's something like this:
Code: [Select]
analogWrite(10, analogRead(A0) >> 2);

Furthermore, you may even want to change the duty cycle quicker. Instead of analogWrite(), you can set a single register to achieve the same effect.
Pin 10 belongs to the channel B of the timer1, so the correct register is called OCR1BL (ends with 'L' because that's a 16-bit timer and you only need the LSB to set the duty cycle). Improving that line even more:
Code: [Select]
OCR1BL = analogRead(A0) >> 2;

I'm suggesting all this because 15 microseconds is a quite tight time budget for an AVR microcontroller, thus having to do everything as "low level" as possible.




PD 2: I've just realized another problem: you're using a timer1 output, which defaults to a prescaler of 64 and runs in "phase-correct" mode; resulting in a carrier frequency of just 490 Hz. I don't think you'll manage to modulate like that any meaningful audio signal, do you?

MarkT

SAR converters can be fast, but not so much the one the ATmega chip...

(I know this because I'm just starting to play with an ADS8885, 400kSPS 18 bit SAR ADC chip with 1.2µs
settling time to full precision...)
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

zkhan


Quote
I don't think you'll manage to modulate like that any meaningful audio signal, do you?
I can actually have really bad quality signal come out of it. You can make out the sounds and words a little bit. And thank you for the insight. Furthermore, is there a way I can increase the quality of the sound in a low level aspect? Thank you!

JarkkoL

#19
Feb 24, 2019, 05:51 am Last Edit: Feb 24, 2019, 05:51 am by JarkkoL
8bit R2R DAC can generate decent sound and you should definitely make out the sounds and words. Here's a reference of 8bit DAC playing audio on Arduino Uno and this doesn't even have any filter, just resistors: https://youtu.be/VHn9NBTj-ME

You need to eliminate the issue in the components you have. E.g. is your DAC actually producing proper signal. If you don't have oscilloscope, make little program to output sine wave for example and listen do you get proper output. Is the analog input working? With silent sound what's the value. How does the range of values change as the sound gets louder (record min & max). Is there clipping when you direct input to output?

zkhan

The file you sent have very complex code probably not suitable for me. Moreover, I wanted to know if i can optimize my code above to get better quality. Thank you for the insight though.


Quote
8bit R2R DAC can generate decent sound and you should definitely make out the sounds and words.

PieterP

#21
Feb 24, 2019, 10:03 am Last Edit: Feb 24, 2019, 11:41 am by PieterP
While many great points have been raised, and even though it's interesting as a proof of concept, I think it's just a waste of time.

An Arduino UNO is not suited for this task, especially if the OP just wants his/her project working and has limited experience with the topic.

@OP, you still haven't told us what you really want to do. Having the Arduino read an input voltage and output the same voltage is not really useful, and only causes signal degradation.
What kind of "real time audio processing" do you want to do?

Edit: it seems like OP has opened a new thread on the same topic: http://forum.arduino.cc/index.php?topic=599651.0

Grumpy_Mike

Reported other thread.

Do not cross post.

MarkT

No the contribution of the most significant bit must be as accurate as the least. Because 0111 1111 must be lower than 1000 0000
Nope, you are assuming all the currents from each bit are
(a) the same (they are not), and
(b) all contribute equally to the output node (they do not).

Basically in an R-2R ladder each bit has half the influence of the previous one, so tolerances for resistors
and voltage references get less strict along the string.

When outputing 10000000, the node on the string next to the LSB is at about 20mV, so changes in
the value of the resistor there have a tiny effect compared to bit 7 whose resistor sees about 2.5V

For instance if R = 5k and 2R = 10k, bit 0 is sinking 2µA, bit 6 sinking ~125µA, bit 7 sourcing ~250µA

Switching to 01111111 reverses the sense of all the voltages and currents, but bit 0 only changes from
sinking to sourcing 2µA, a 4µA change
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

zkhan

#24
Feb 25, 2019, 12:01 am Last Edit: Feb 25, 2019, 03:52 am by zkhan
Quote
@OP, you still haven't told us what you really want to do
Thank you for all the information. Sorry for cross Posting. Moreover, I wanted to create/manipulate a timer function that can allow better sound quality, because Ive seen individuals creating really good quality sound with a R2R resister ladder.

Sorry again for the many question, however reading more forums i found that you can "If you need 16 bits, you can use 2 R2R ladders and tie the output of the low byte R2R to the input of the high byte R2R and get a clean 16 bit analog output". Do y'all think it would increase the audio signal, because currently I'm using a 1 R2R resistor ladder? But the built in ADC is 8 bit, so will that aswell cause problems?


Thank you

Grumpy_Mike

The built in A/D is 10 bits.
Making a home built 16 bit D/A using two ladders is an illusion and put on the web by people who frankly don't know what they are doing and don't know how to test it correctly. The accuracy of the resistor ratios needed is just not attainable from fixed resistors.

How can a timer function create better audio?
Pleas tell us what you actually want to do.

MarkT

You can synthesize upto 16 bit accuracy from 2 8-bit PWM signals and two accurate resistors in the ratio 1:256,
which hasn't been mentioned on this thread yet.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

PieterP

#27
Feb 25, 2019, 12:38 pm Last Edit: Feb 25, 2019, 12:39 pm by PieterP
You can synthesize upto 16 bit accuracy from 2 8-bit PWM signals and two accurate resistors in the ratio 1:256,
which hasn't been mentioned on this thread yet.

Would it be enough for the PWM signals to have the same frequency and phase offset? Edge-aligned or phase-correct PWM?
Or should both signals be LPF'ed first, and then combined?

I think it's probably easier to just use Timer1 for 16-bit PWM.

However, a 16-bit DAC isn't of much use if your ADC is only 10 bits or even 8 bits at higher speeds, but I don't think OP realizes this ...

MarkT

But you can also combine two 5 bit PWMs to get 10 bit, and 5 bit PWM can run a lot faster for easier
low-pass filtering on the output.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

PieterP

But you can also combine two 5 bit PWMs to get 10 bit, and 5 bit PWM can run a lot faster for easier
low-pass filtering on the output.
True, I didn't think about that!

Go Up