I am currently working on a project making a digital filter with an arduino uno board.
I have successfully implemented the filter with audio output, but am getting some noise in my output. I believe it is due to aliasing in my audio due to my sample rate having a delay between samples, but not being packaged as a standard period.
I am looking to force my samples into one time range, as opposed to delaying time between samples, in an attempt to counteract differences in time between various values and my arithmetic.
I am aware of the arduino time library, but it seems the smallest time period there is seconds, and I'm hoping to go smaller, to milliseconds, and possibly microseconds if that's available.
I know in java I can do a system time call to get the current nanoseconds, and then compare that with a later system call. Is there a similar practice with arduino?
How is your audio connected to the analog inputs? The analog inputs expect a signal in the range 0-5V which it encodes in the range 0 - 1023. I haven't checked your code closely but presumably it also outputs values in the range 0 - 1023 to the DACs. Is that what they are expecting?
since the ADC produces 0 - 1023, shouldn't your code offset this by subtracting 512, do the filter, and then add back in whatever offset is required for the DAC?
A 10bit analogRead takes about 100 microseconds. The SPI transfers will also take time so I'm guessing that the entire loop() takes on the order of 400 microseconds which is a sampling rate of 2500Hz. Is that what you were expecting? The best-csae scenario would be 200 microseconds and that's still only 5kHz. You can speed up the ADC by specifying fewer bits, but that obviously increases the noise.
What kind of hardware do you have on the input/output? What happens if you simply pass-through the data (analog-to-digital-to-analog) with no filtering/processing?
I believe it is due to aliasing in my audio due to my sample rate having a delay between samples, but not being packaged as a standard period.
Aliasing is caused by having a signal that's more than half the sample-rate. If you are getting aliasing, you you have two choices - You can use a higher sample-rate (and there are limits with the Arduino), or you can low-pass filter the signal before analog-to-digital conversion.
However, you could be getting glitches & noise if the processor can't keep-up with the data-flow.
I've never tried any DSP with the Arduino... From what I understand, it's a little slow for high-quality audio (such as 16-bit 44.1kHz, "CD quality"). Plus, the ADC is only 10-bits and there is no built-in DAC.
How is your audio connected to the analog inputs? The analog inputs expect a signal in the range 0-5V which it encodes in the range 0 - 1023. I haven't checked your code closely but presumably it also outputs values in the range 0 - 1023 to the DACs. Is that what they are expecting?
since the ADC produces 0 - 1023, shouldn't your code offset this by subtracting 512, do the filter, and then add back in whatever offset is required for the DAC?
A 10bit analogRead takes about 100 microseconds. The SPI transfers will also take time so I'm guessing that the entire loop() takes on the order of 400 microseconds which is a sampling rate of 2500Hz. Is that what you were expecting? The best-csae scenario would be 200 microseconds and that's still only 5kHz. You can speed up the ADC by specifying fewer bits, but that obviously increases the noise.
On the UNO a 'double' is actually a 'float'.
Pete
I am inputting form either an iPod or my laptop, depending on my iPods charge. I have added some AA batteries with my input to bring up the power a bit, and I am aware it is a 0-1023 scale. I have a bitmapping to output 1023, I've messed with the numbers a bit to find the best (so far at least) output to my DACs, which are MCP4921s.
Your time estimations for the different functions are very helpful, so thank you there. Do you have a source for where you came up with those numbers? That could help me further my research and learn a bit more. I'm looking to learn all about this stuff as well as get an answer, so even if I don't get a solution, any extra knowledge is great!
I'm doing function calls from my main loop to my filter and audio output, and from my understanding drawn from software classes, while they will all be close, and negligible in time difference to a person, it can change a bit for electronics.
I'm looking to force every iteration of my loop to be the same time, rather than assuming each iteration will be the same.
Do you know an arduino function call to give me the current time in milliseconds. Relative to any starting point (as long as it stays uniform throughout the code) would be useful.
DVDdoug:
What kind of hardware do you have on the input/output? What happens if you simply pass-through the data (analog-to-digital-to-analog) with no filtering/processing?
Aliasing is caused by having a signal that's more than half the sample-rate. If you are getting aliasing, you you have two choices - You can use a higher sample-rate (and there are limits with the Arduino), or you can low-pass filter the signal before analog-to-digital conversion.
However, you could be getting glitches & noise if the processor can't keep-up with the data-flow.
I've never tried any DSP with the Arduino... From what I understand, it's a little slow for high-quality audio (such as 16-bit 44.1kHz, "CD quality"). Plus, the ADC is only 10-bits and there is no built-in DAC.
To reiterate my last reply (which I just posted, after your reply) I am inputting from my laptop or iPod depending on charge for my iPod.
I am not certain the issue is aliasing, I'm guessing a bit. I'm new to both arduinos and audio processing. I knew going in that there would be issues with noise being added in from my circuit, my main goal is to limit that noise.
You mentioned low pass filtering the audio before the analog to digital conversion. I assume that would be passing my input through a low pass filter (basic RC circuit set up?) and from there inputting it into my arduino?
Any suggestions on raising sample rate for the arduino? I have my delay between samples at 1 microsecond, which from what I've seen is the lowest delay I can do. If you know a lower way I'd appreciate suggestions!
I have added some AA batteries with my input to bring up the power a bit
What does this mean exactly? The audio input to the ADC should be an A/C signal with a maximum amplitude of -2.5V to +2.5V and this should have a +2.5V DC bias added so that the voltage at the ADC is 0 to 5V.
I have my delay between samples at 1 microsecond, which from what I've seen is the lowest delay I can do.
The fact that the analogRead functions take around 100 microseconds each means that an additional microsecond delay is going to make no difference at all. You need to speed the loop up, not slow it down.
Do you know an arduino function call to give me the current time in milliseconds.
millis()
But that isn't going to help you get a constant sampling interval at a rate of more than 1kHz.
el_supremo:
What does this mean exactly? The audio input to the ADC should be an A/C signal with a maximum amplitude of -2.5V to +2.5V and this should have a +2.5V DC bias added so that the voltage at the ADC is 0 to 5V.
The fact that the analogRead functions take around 100 microseconds each means that an additional microsecond delay is going to make no difference at all. You need to speed the loop up, not slow it down.
millis()
But that isn't going to help you get a constant sampling interval at a rate of more than 1kHz.
What sampling rate do you need?
Pete
The input I had was being clipped on the bottom end, so I added 1.5V (AA Battery) to the signal to prevent clipping.
I am delaying it by 1 microsecond specifically because, from what I have read, the void loop is delayed by 1 millisecond if you do not explicitly list a delay. Meaning my 1 microsecond delay is actually speeding the sampling up, not slowing it down.
I don't necessarily have a particular sample rate goal, I just want to make sure that my sample rates are as uniform as possible. So I'm hoping to use the millisecond function to make "package" (for lack of a better term) my code into a uniform time period.
Whether this is correct or not, thanks for the function call. What library is that from?
And if this idea is incorrect, do you have any suggestions to either stop, or rule out aliasing for my issue?
Here is a screen shot of my circuit, in case it's helpful for answering any of my questions or understanding what I'm going for:
I've never seen an A/C voltage raised by 1.5V that way and have no idea if it would work properly.
I don't necessarily have a particular sample rate goal
You've got to have some idea. What range of frequencies is the filter supposed to affect and what does it output? If, as an example, it was a 10kHz high-pass filter there would be no point having a sampling rate of 2kHz.
I am inputting form either an iPod or my laptop
OK, so what are you inputting from the Ipod? Music? speech? What is the filter supposed to do to it?
el_supremo:
I've never seen an A/C voltage raised by 1.5V that way and have no idea if it would work properly.
You've got to have some idea. What range of frequencies is the filter supposed to affect and what does it output? If, as an example, it was a 10kHz high-pass filter there would be no point having a sampling rate of 2kHz.
OK, so what are you inputting from the Ipod? Music? speech? What is the filter supposed to do to it?
Pete
It isn't one particular song or speech. It's general output. And I understand that it would need to be different for each song/speech/audio sample.
My main goal is to package the filter into a uniform sample rate so that for each audio source I could change a minimum number of values to get the filter sampling at the best rate.
Hopefully that makes sense.
Initially I would simply go into the code and change the value there, if I get that working well I'll be seeking an initial (possibly initial, possibly variable) input from the user to determine the sample rate. So they could either start off with the correct sample rate, or possibly change the sample rate throughout the audio sampling to tweak the outputted sound.
Again I don't know much about this, or arduinos yet. It's a learning experience for me. Any tips or suggestions are more than appreciated, I don't wish to seem ungrateful towards any inputs, I appreciate all of it!