Sound processing of specific sound or at least range of that sound..

Status
Not open for further replies.
this is copy pasted from what i posted from arduino forums..

-------

Hi, i just need to ask.. as to what type of mic/mic module is capable of distinguishing these two sounds..

video: https://www.youtube.com/watch?v=f9Ob0VpEqz0

see, the corner of the floor tiles is producing a sound different from whats in the middle is producing, everytime i tap it.. like in the corner(tik,tik,tik)... middle (tok,tok,tok)..

the one with the "tok tok tok" sounds differently because it seems to have a hollow concrete/adhesive underneath, hence failing tiles..

say the output would be.. LED be logic 1 everytime the tok tok tok sound is recognized by the sensor..

my local electronics supplier suggested I buy this: https://www.adafruit.com/product/1063
and also a piezo ceramic disc: https://i.ebayimg.com/images/g/0bEAAOSwR5VZk6kI/s-l225.jpg

Will this be enough though? are there any studies related to this?

also, I might stay away from using the piezo since i will be attaching a servo motor on a 4wd, and let the servo(attached with stick.. with ball bearing.. etc.) do the tapping.. if piezo is used, im afraid it will be dragged everytime the 4wd moves..

sorry for the english...

-------

will my project be feasible using a teensy? what mic should i use?
arduino forum member suggested i use a pi, but I kinda want to use a platform that is programmable in C.


also, i found this while researching: https://learn.adafruit.com/fft-fun-with-fourier-transforms/spectrogram
 
Any mic should provide sufficient frequency coverage to use an FFT object to look for resonant frequencies.

(FFT is 'Fast Fourier Transform' and is fancy math for converting signals from the time domain (regular audio) into the frequency domain --- albeit normally at a slower updating rate.)

Audio fidelity is unimportant provided the mic is remotely linear over a low-fi audio range as the resonances you are hearing are no more than a few hundred hertz.

A piezo-disc is super cheap and should give a lot of signal but you need some extra electronics to protect Teensy from high voltages. The electret module looks easy to use as the output will already be limited to the supply voltage you feed it (3.3 v presumably) and the input is already biased into the positive range. The piezo may make a better contact mic but that may not be that important.

You may be able to use the 256 bin FFT object if the resonances are far enough apart to distinguish them at the lower bin resolution. The advantage is lower CPU load but if this is all you are doing and you have a T3.2 or better you might was well do the larger bin count.




FFT is pretty complex stuff but Paul's audio library object does the complicated part and provides access to the values in each frequency bin. The value in each bin is the magnitude of that bin's frequency range in the provided signal.

For what you want you may be able to compare ratio of two bins if the main resonant values for each type of sound fall distinctly into each of two bins. Otherwise doing the same using the read for two ranges of bins can be used if the resonant frequencies range outside of a single bin (here's where the low-rez FFT might be easier as the mostly-in-one-bin requirement is much more likely to hold true).

Strongly recommend doing the Audio Library tutorial before you try to make this happen.


Caveat: I'm not an EE nor a DSP expert.

Edit -- it occurs to me you're not comparing a TOCK to a TICK but looking for TOCKs by comparing with some threshold... but I think I'm not too far off on the rest.
 
Any mic should provide sufficient frequency coverage to use an FFT object to look for resonant frequencies.

(FFT is 'Fast Fourier Transform' and is fancy math for converting signals from the time domain (regular audio) into the frequency domain --- albeit normally at a slower updating rate.)

Audio fidelity is unimportant provided the mic is remotely linear over a low-fi audio range as the resonances you are hearing are no more than a few hundred hertz.

A piezo-disc is super cheap and should give a lot of signal but you need some extra electronics to protect Teensy from high voltages. The electret module looks easy to use as the output will already be limited to the supply voltage you feed it (3.3 v presumably) and the input is already biased into the positive range. The piezo may make a better contact mic but that may not be that important.

You may be able to use the 256 bin FFT object if the resonances are far enough apart to distinguish them at the lower bin resolution. The advantage is lower CPU load but if this is all you are doing and you have a T3.2 or better you might was well do the larger bin count.




FFT is pretty complex stuff but Paul's audio library object does the complicated part and provides access to the values in each frequency bin. The value in each bin is the magnitude of that bin's frequency range in the provided signal.

For what you want you may be able to compare ratio of two bins if the main resonant values for each type of sound fall distinctly into each of two bins. Otherwise doing the same using the read for two ranges of bins can be used if the resonant frequencies range outside of a single bin (here's where the low-rez FFT might be easier as the mostly-in-one-bin requirement is much more likely to hold true).

Strongly recommend doing the Audio Library tutorial before you try to make this happen.


Caveat: I'm not an EE nor a DSP expert.

Edit -- it occurs to me you're not comparing a TOCK to a TICK but looking for TOCKs by comparing with some threshold... but I think I'm not too far off on the rest.

Hi oddson, your reply is exactly what i need. Thank you.. I think im all set, and will buy a teensy..

Surprsingly 3.5 and 3.2 is priced almost the same here. https://www.lazada.com.ph/catalog/?q=teensy&_keyori=ss&from=input&spm=a2o4l.home.search.go.5da391e2hcUa9v

I also have the max4466 electret mic prepared. and its the same mic used in design tool example for audio input.

Thanks.. will update on my project.. and might ask further questions if i run into some troubles..
 
You must have a lot of tiles to check to make building this make sense.

And there is the possibility that it doesn't generalize across the set of tiles you intend to use it on in terms of establishing the criterion to distinguish between sound and unsound tiles.

It's an interesting practical application but are you sure you're up for it?
 
Hi Oddson.. i made a sperate topic when i started to build this project. had a lot of questions. The very first task alone, im trying to accomplish is very daunting. although it may be very simple to others..
for the life of me.. i can't even get any input from the mic module. I was hoping maybe you have an asnwer to my problem or suggestion?, no one replies to my topics.

https://forum.pjrc.com/threads/5041...ing-max-4466-and-elec-mic?p=172172#post172172

https://forum.pjrc.com/threads/50477-help-with-teensy-3-5-and-elec-mic
 
I was speaking as someone who knows just enough about these subjects to know they're not trivial.

Simple arithmetical comparisons between bin-range totals might produce results once you understand the actual signals from your sample (which needs to be a whole lot bigger than 3).

But it's also possible (likely?) that a more theoretically based comparison is required to differentiate between two sample groups where the underlying differences are not fixed to points on the spectrum.

An estimate of the original frequency of a peak (local maximum) spread across bins is possible using some fancy sort of moving average... I was able to code it once in SynthMaker's DSP code language (not assembly) but it was long ago and I remember next to nothing about it.

And I'm really not qualified on the mic issue.

You're more likely to get a decent answer if they show no replies than if I give you more half-answers.
 
Something is up with the mic module, since as per the produce page it as a 1/2 supply bias value so the quiet reading should be ~500 and your other link suggests ~200 readings. You may need to revisit the mods you did and work out what they were trying to do and where you have ended up.

One thing to do is to remove the mic module with the the analog read test code in the other thread use resistors to confirm your output swings 0-1024 when connected to gnd and 3.3V. That will prove nothing has happened to the hardware in all this.

edit: re-reading the thread talking about the mic module and matching the audio library it looks like you have modded the bias to work with the audio library, and 0.6V/200 readings is the right state. So teensy is working, bias is working. Question is what the actual mic is up to.
 
Hi Oddson, I understand your reply.. I was desperate for an answer that probably led me to this. in theory also, after collecting all the researches i made, I really think this project is feasible..
But I realize i havent put enough thought on the bins.. I thought it is easy as collecting frequency samples of failing tiles(hollow) and the Okay ones.


In perspective..

i thought it would be something like this(only for visualization purposes):

wJzP1BT.jpg


Say, the one at the top of the image is the average frequency components of the hollow tiles after FFT.

The one below is the average for okay ones..

What I theorized is that.. I can distinguish the hollow tiles from the okay ones.. using these data.

say

if (read(binNumber60)>90) then {led == HIGH;}

This is what i had in mind. I hope im making any sense.



Hi Gremlin, Unfortunately, I might have damaged the module. replaced back the 1m resistor. and its not functioning the way it did. Already have another one, Im having second thoughts of modifying it again.

The unmodified one, is changing its value when i make a sound. My problem right now is to use the module without modifying it.
Also about the bias circuit you are referring to. are you reffering to this?:
adccircuit.png


Im still looking for solution to use the mic without the need to desolder the smd resistor.

Also, using 3.0 and max4466.. this master was able to utilize both without the need of hardware modifications: https://learn.adafruit.com/fft-fun-with-fourier-transforms?view=all
 

Attachments

  • wJzP1BT.jpg
    wJzP1BT.jpg
    21.9 KB · Views: 102
  • adccircuit.png
    adccircuit.png
    60.8 KB · Views: 374
I've attached a screenshot of part of the spectrogram of the audio. The first four vertical lines are a "tick" and the others are a "tock".
They look almost the same except that, as you might expect, the "tock" has more lower frequency components in the 1-3kHz range. This might give you the ability to distinguish the two.
spectrogram_crop.gif

However, there are complicating factors. One is that if you look at an individual tick or tock closely in the time domain, you'll find that it consists of the original sound followed by an echo about 6ms later.
closeup.gif

Then there's the traffic noise :)

Pete
 
I've attached a screenshot of part of the spectrogram of the audio. The first four vertical lines are a "tick" and the others are a "tock".
They look almost the same except that, as you might expect, the "tock" has more lower frequency components in the 1-3kHz range. This might give you the ability to distinguish the two.
View attachment 13370

Then there's the traffic noise :)

Pete

Hi pete, I was trying to upload a code to my teensy that will at least get the frequency components. the example codes use an audio shield. But I tried editing it to work with max4466 but to no avail. it is not reading anything.

Here is the edited code
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputAnalog         adc1;           //xy=181,127
AudioAnalyzeRMS          rms1;           //xy=431,168
AudioAnalyzePeak         peak1;          //xy=433,130
AudioAnalyzeFFT1024      fft1024_1;      //xy=439,211
AudioConnection          patchCord1(adc1, peak1);
AudioConnection          patchCord2(adc1, rms1);
AudioConnection          patchCord3(adc1, fft1024_1);
// GUItool: end automatically generated code

void setup() {
      Serial.begin(9600);
      delay(1000);
      Serial.println("FFT RESULTS");
      fft1024_1.windowFunction(AudioWindowHanning1024);
      AudioMemory(12);
}


int delayValue = 700;


void loop() {

  float n;
  int i;
      
      if (fft1024_1.available()) {

    Serial.print("FFT: ");
    for (i=0; i<40; i++) {
      n = fft1024_1.read(i);
      if (n >= 0.01) {
        Serial.print(n);
        Serial.print(" ");
      } else {
        Serial.print("  -  "); // don't print "0.00"
      }
    }
    Serial.println();

     } 
     
      delay(delayValue); // Delay for a period of time (in milliseconds).

}



it is interesting to see the results you have produced. I am trying to get results same with the first picture you provided, but using only serial monitor.


once i get a visualization of these components, and find patterns relative to the tok sounds and tik sounds. I may select the relevant bins unique to both of them. and use those bins in if else statement. not necessarily accurate but ~.

so far though, using the code above.. it resulted to a zeros

Serial Monitor:

FFT: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
FFT: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
FFT: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
FFT: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
FFT: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
FFT: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
FFT: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
FFT: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
FFT: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --


please note that this is a new mic max4466 i am using.. even without the hardware mod. it is displaying peak and rms valuesand not zeros when i make sounds.. also analogread values change also.

so when using the fft function, shouldnt there be at least small values present? why am i getting zzeros?


P.S. I think i have read some of your reply in arduino forums talking about FHT in arduino uno. is possible using uno?
 
Last edited:
The UNO would be too slow to do something like this and probably hasn't got enough ram either.

The two images I attached were produced by the Goldwave audio editing program on a PC and the input was the audio from the Youtube video.

If you are using the Adafruit MAX4466 have you done this fix recommended by Paul to make it work with Teensy? See Msg #14
https://forum.pjrc.com/threads/4046...io-Lib-results?p=126317&viewfull=1#post126317

I can't figure out how your code produces the serial output you show. I can't see any way that it can print two hyphens side-by-side "--". All the lines except the first have 26 "--" which makes no sense when the loop goes round 40 times for each FFT.

Pete
 
The UNO would be too slow to do something like this and probably hasn't got enough ram either.

The two images I attached were produced by the Goldwave audio editing program on a PC and the input was the audio from the Youtube video.

If you are using the Adafruit MAX4466 have you done this fix recommended by Paul to make it work with Teensy? See Msg #14
https://forum.pjrc.com/threads/4046...io-Lib-results?p=126317&viewfull=1#post126317

I can't figure out how your code produces the serial output you show. I can't see any way that it can print two hyphens side-by-side "--". All the lines except the first have 26 "--" which makes no sense when the loop goes round 40 times for each FFT.

Pete


Yes, I did try replacing 1m resistor with 220k. But ended up breaking the module(I think), since it stops working and all values are constant, even if i make sounds.

I have a new one though. this is the one im testing right now.


for the FFT output.. I basically just typed it in here.... But here is the actual FFT output:

HHY4ZZe.png
 
why am i getting zzeros?

Very likely a mistake or misunderstanding in connecting the hardware.

If you share photos, maybe we'll be able to help see what's wrong.


is possible using uno?

Perhaps not impossible, but extremely difficult and very likely to have low performance even if you do get it working. Uno's 8 bit 16 MHz processor and lack efficient DMA for input is woefully underpowered for this sort of audio analysis project.
 
Very likely a mistake or misunderstanding in connecting the hardware.

If you share photos, maybe we'll be able to help see what's wrong.




Perhaps not impossible, but extremely difficult and very likely to have low performance even if you do get it working. Uno's 8 bit 16 MHz processor and lack efficient DMA for input is woefully underpowered for this sort of audio analysis project.

Hi Paul, This is my connection. this is not the one with the module mod.

xIH8Dze.png


Using this code from another user, the RMS PEAK and FFT values changes when i make sounds..

Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioInputAnalog         adc1;           //xy=181,127
AudioAnalyzeRMS          rms1;           //xy=431,168
AudioAnalyzePeak         peak1;          //xy=433,130
AudioAnalyzeFFT1024      fft1024_1;      //xy=439,211
AudioConnection          patchCord1(adc1, peak1);
AudioConnection          patchCord2(adc1, rms1);
AudioConnection          patchCord3(adc1, fft1024_1);
// GUItool: end automatically generated code

void setup() {
      Serial.begin(9600);
      delay(1000);
      Serial.println("Teensy Audio AudioMemory()");
      AudioMemory(10);
}

int pk = 1, rm = 1, ff = 1;
int delayValue = 700;
unsigned long loopCount = 0;

void loop() {
      Serial.printf("----%lu----\n", loopCount);
      if (peak1.available()) {
            pk = (int)(peak1.read() * 100);
            for (int i = 0; i < pk; i++) {
                Serial.print("p"); 
            }
            Serial.printf("\tPeak: %d\n", pk);
      } else {
            Serial.println("peak1 not available");
      }
      if (rms1.available()) {
            rm = (int)(rms1.read() * 100);
            for (int i = 0; i < rm; i++) {
                Serial.print("r"); 
            }
            Serial.printf("\tRMS: %d\n", rm);
      } else {
            Serial.println("rms1 not available"); 
      }
      if (fft1024_1.available()) {

     
            float fftAccumulator = 0;
            for (int i = 0; i < 512; i++) {
                  fftAccumulator += fft1024_1.read(i);
            }
            ff = (int)(fftAccumulator * 100);
            for (int i = 0; i < ff; i++) {
                  Serial.print("f"); 
            }
            Serial.printf("\tFFT: %d\n", ff);
      } else {
           Serial.println("fft1024_1 not available");
      }


      
      loopCount++;
      
      delay(delayValue); // Delay for a period of time (in milliseconds).

}

So i thought I will also get values when i use the code I mentioned from my previous post.
 
Is there any alternative aside from desoldering the 1M smd resistor? I broke my first elec mic, since i persisted replacing it with a through hole resistor..
 
Status
Not open for further replies.
Back
Top