Go Down

Topic: Analyzing Audio w/ Arduino FFT (Read 6862 times) previous topic - next topic

funfrancis

Hi

I too am working on performing FFT from the received audio signals
In my case I'm using  a Hydrophone(underwater Mic) - http://www.aquarianaudio.com/h3.html
and its Pre-Amplifier - https://www.dropbox.com/s/n8twltvlacc1w1t/PA4_vert14526499545695ade2996ca.jpg?dl=0

The connections are as such -
https://www.dropbox.com/s/8xqu9mx05n426n5/Hydrophone%20-%20PreAmp.png?dl=0
 

I'm using The ArduiniFFT library
Example codes
Code: [Select]
/*
fft_adc.pde
guest openmusiclabs.com 8.18.12
example sketch for testing the fft library.
it takes in data on ADC0 (Analog0) and processes them
with the fft. the data is sent out over the serial
port at 115.2kb.  there is a pure data patch for
visualizing the data.
*/

#define LOG_OUT 1 // use the log output function
#define FFT_N 256 // set to 256 point fft

#include <FFT.h> // include the library

void setup() {
  Serial.begin(115200); // use the serial port
  TIMSK0 = 0; // turn off timer0 for lower jitter
  ADCSRA = 0xe5; // set the adc to free running mode
  ADMUX = 0x40; // use adc0
  DIDR0 = 0x01; // turn off the digital input for adc0
}

void loop() {
  while(1) { // reduces jitter
    cli();  // UDRE interrupt slows this way down on arduino1.0
    for (int i = 0 ; i < 512 ; i += 2) { // save 256 samples
      while(!(ADCSRA & 0x10)); // wait for adc to be ready
      ADCSRA = 0xf5; // restart adc
      byte m = ADCL; // fetch adc data
      byte j = ADCH;
      int k = (j << 8) | m; // form into an int
      k -= 0x0200; // form into a signed int
      k <<= 6; // form into a 16b signed int
      fft_input[i] = k; // put real data into even bins
      fft_input[i+1] = 0; // set odd bins to 0
    }
    fft_window(); // window the data for better frequency response
    fft_reorder(); // reorder the data before doing the fft
    fft_run(); // process the data in the fft
    fft_mag_log(); // take the output of the fft
    sei();
    Serial.write(255); // send a start byte
    Serial.write(fft_log_out, 128); // send out the data
  }
}


I need to connect another "Hydrophone at A1"

How do  address that?
Pls help!!

AWOL

If you start or hijack another thread on this subject, you will get a forum time-out.

Clear?

Duplicates deleted.

funfrancis

Clear

I was desperate for an answer and posted there first but did not get ad so opened a thread of my own.

tmd3

I was desperate ...
Desperate posts often go unanswered.  

Your question lacks clarity.  Do you intend to sample A0, run an FFT, and then sample A1, and run an FFT on that?  Or do you hope to sample A0 and A1 alternately, and run two FFT's?

What will you do with the results of the FFT?  What are you doing with this project?

funfrancis

I intend to connect two Hydrophones on A0 and A1 and wish to see their results simultaneously in the serial monitor

The hydrophones and Arduino UNO will be mounted on a Aerial vehicle and the outputs will be transferred to the base computer using the LoRa module.


tmd3

I intend to connect two Hydrophones on A0 and A1 and wish to see their results simultaneously in the serial monitor
OK.  That doesn't tell me whether you intend to interleave the samples or not.  You can take the FFT of one input channel, and then the other, and show them simultaneously.  Or, you can show them when you get them.  Your sampling interval is short, and the openmusiclabs FFT code is fast.  You won't notice the delay

So, to you intend to interleave the readings of two channels, and take two FFT's?

Quote
The hydrophones and Arduino UNO will be mounted on a Aerial vehicle and the outputs will be transferred to the base computer using the LoRa module.
OK.  That still doesn't reveal what you're doing.  What are you going to use this gizmo for when it's done?

How has your code worked for you so far?

funfrancis

You can take the FFT of one input channel, and then the other, and show them simultaneously. 
That's what I want to do

Show the results simultaneously

The Hydrophones- Arduino UNO will be mounted on a Aerial vehicle whose purpose is to float on water, capture sound of underwater mammals and transmit them to the base station. Transmission  part is easy as I have tried it with other sensors and it works fine

I tried the FFT library but was not sure if the codes were reading it right

tmd3

How did you read the output from your sketch?
I tried the FFT library but was not sure if the codes were reading it right
What output did you get?

funfrancis

Hi

I connected the output from the Pre-Amp to A0 and ran the code

The connections


The FFT codes
Code: [Select]
/*
fft_adc.pde
guest openmusiclabs.com 8.18.12
example sketch for testing the fft library.
it takes in data on ADC0 (Analog0) and processes them
with the fft. the data is sent out over the serial
port at 115.2kb.  there is a pure data patch for
visualizing the data.
*/

#define LOG_OUT 1 // use the log output function
#define FFT_N 256 // set to 256 point fft

#include <FFT.h> // include the library

void setup() {
  Serial.begin(9600); // use the serial port
  TIMSK0 = 0; // turn off timer0 for lower jitter
  ADCSRA = 0xe5; // set the adc to free running mode
  ADMUX = 0x40; // use adc0
  DIDR0 = 0x01; // turn off the digital input for adc0
}

void loop() {
  while(1) { // reduces jitter
    cli();  // UDRE interrupt slows this way down on arduino1.0
    for (int i = 0 ; i < 512 ; i += 2) { // save 256 samples
      while(!(ADCSRA & 0x10)); // wait for adc to be ready
      ADCSRA = 0xf5; // restart adc
      byte m = ADCL; // fetch adc data
      byte j = ADCH;
      int k = (j << 8) | m; // form into an int
      k -= 0x0200; // form into a signed int
      k <<= 6; // form into a 16b signed int
      fft_input[i] = k; // put real data into even bins
      fft_input[i+1] = 0; // set odd bins to 0
    }
    fft_window(); // window the data for better frequency response
    fft_reorder(); // reorder the data before doing the fft
    fft_run(); // process the data in the fft
    fft_mag_log(); // take the output of the fft
    sei();
    for (uint8_t j = 0; j < FFT_N/2; j++) {
    Serial.print(j);
    Serial.print(" ");
    Serial.println(fft_log_out[j]);
    }
  }
}


The output:
Code: [Select]
0 221
1 206
2 118
3 89
4 90
5 65
6 77
7 83
8 78
9 67
10 56
11 54
12 46
13 59
14 16
15 43
16 53
17 41
18 39
19 0
20 42
21 27
22 32
23 30
24 30
25 19
26 24
27 35
28 8
29 27
30 37
31 16
32 37
33 0
34 30
35 19
36 37
37 0
38 30
39 24
40 19
41 19
42 19
43 8
44 30
45 0
46 19
47 19
48 19
49 0
50 25
51 25
52 25
53 24
54 38
55 50
56 51
57 43
58 43
59 27
60 24
61 0
62 8
63 25
64 33
65 32
66 25
67 19
68 0
69 19
70 0
71 16
72 27
73 19
74 19
75 19
76 27
77 0
78 0
79 16
80 19
81 19
82 0
83 16
84 0
85 8
86 19
87 0
88 8
89 8
90 19
91 0
92 27
93 0
94 16
95 25
96 25
97 43
98 27
99 8
100 27
101 8
102 19
103 16
104 0
105 8
106 19
107 8
108 0
109 0
110 16
111 0
112 16
113 8
114 0
115 16
116 16
117 16
118 16
119 8
120 19
121 8
122 0
123 8
124 27
125 0
126 0
127 0
0 167
1 156
2 123
3 91
4 91
5 68
6 84
7 82
8 75
9 44
10 68
11 53
12 63
13 52
14 61
15 16
16 33
17 35

tmd3

Try printing the input data before running the FFT, to make sure that you've actually captured something that looks like audio.

funfrancis

#10
Feb 24, 2016, 05:54 am Last Edit: Feb 24, 2016, 09:35 am by funfrancis
Try printing the input data before running the FFT, to make sure that you've actually captured something that looks like audio.
how do I print the input data

tmd3

What's the problem here?  Is it that you can't identify the input data, or is it that you don't know how to print it?

jremington

Quote
how do I print the input data
Very similar to the way you printed the output data.

pjrc

#13
Feb 24, 2016, 09:36 pm Last Edit: Feb 24, 2016, 09:37 pm by Paul Stoffregen
https://en.wiktionary.org/wiki/give_a_man_a_fish_and_you_feed_him_for_a_day;_teach_a_man_to_fish_and_you_feed_him_for_a_lifetime

Of course, this ancient proverb assumes the hungry man actually wants to learn, rather than keep coming back again and again for another meal.

funfrancis

how do I print the input data
What's the problem here?  Is it that you can't identify the input data, or is it that you don't know how to print it?
I can't identify the input data

Go Up