• Pic® Basic


  • Simple audio identification with an 8 bit PIC® Microcontroller

    Using a PIC® microcontroller to do audio identification can be done if one thinks past the audio sample rates and associated audio memory requirements.

    Now keep in mind the idea is not to look for single notes in an audio string, although that may also be possible.

    Instead the idea would be to identify a sound if it is played the second time.

    Audio is nothing else than changing of frequency and change in amplitude. If you go out from the assumption that 1kHz is 1kHz and 10kHz is 10kHz then the amplitude plays no roll. Remember the pic does not read the analog value of the signal here, the pic pin has a threshold over which is a one, under which is a 0.

    In my case the PIC® pin I used as an input is not a schmidt input, so the threshold of the input pin is around 1V. Either type of input can be used.

    When audio is played to the pic, the PIC® in other words receives on the input pin an analog value, that either goes over the 1V threshold, or it remains under the 1V threshold.

    The volume with which the audio is played to the PIC® pin is important. If the volume of the audio is reduced, then some of the audio peaks that was exceeding the 1V threshold before, now does not exceed it any more. This means the PIC® pin will see less 1's (or high's) than it would with the volume adjusted higher.

    It would thus be safe to say that a given audio, played at a specific volume, is going to represent a specific frequency on the PIC® pin.

    Any change in the audio frequency, as well as a change in the volume, is going to change the specific frequency on the PIC® pin.

    And frequency is something the PIC® can count very easily.

    There is however one more thing to consider. Just counting the amount of 1's that is received during a time span is not very secure. An adjustable frequency can so easily be played to the PIC® input pin, and at some frequency the pulse count is going to be the same as that of the original audio, hence a faulty identification.

    If a single fixed frequency tone is used as the original audio, then that frequency only should be true.

    However, if a tune is played, then the frequency received changes from moment to moment, however long a moment in this case may be, but that would be the key to make the identification secure.

    If one then take some short time frequency samples then the picture changes considerably.

    For each short time the frequency (and amplitude) has to be the same or a mismatch in comparison will occur. So not only the frequency has to be correct, but also the sequence of the different frequencies has to be in the same order.

    An example for use could be a simple door striker that gets opened, it could be a gate or anything else that needs secure access.

    An easy every day source of an audio signal could be your cell phone containing a pre-recoded audio or even a tune you generated with the phone's composer.

    Remember that the distance you hold the speaker from the mic, the phone's playback volume, and environmental noise could affect the recognition process in this very basic setup.

    Anyone mind to calculate the possible access combinations we can have here ?

    I'm not going to post the full code, only that what will be of use.

    Couple of DIM's. I decided to take 9 samples in sequence


    Code:
    Dim Dur1 As Word                ' Duration 1 Counter
    Dim Dur2 As Word                ' Duration 2 Counter
    Dim Dur3 As Word                ' Duration 3 Counter
    Dim Dur4 As Word                ' Duration 4 Counter
    Dim Dur5 As Word                ' Duration 5 Counter
    Dim Dur6 As Word                ' Duration 6 Counter
    Dim Dur7 As Word                ' Duration 7 Counter
    Dim Dur8 As Word                ' Duration 8 Counter
    Dim Dur9 As Word                ' Duration 9 Counter
     
    Dim Durs1 As Word                ' Duration 1 Counter Saved
    Dim Durs2 As Word                ' Duration 2 Counter Saved
    Dim Durs3 As Word                ' Duration 3 Counter Saved
    Dim Durs4 As Word                ' Duration 4 Counter Saved
    Dim Durs5 As Word                ' Duration 5 Counter Saved
    Dim Durs6 As Word                ' Duration 6 Counter Saved
    Dim Durs7 As Word                ' Duration 7 Counter Saved
    Dim Durs8 As Word                ' Duration 8 Counter Saved
    Dim Durs9 As Word                ' Duration 9 Counter Saved
    Each sample register Dur1 to Dur9 has to be a Word since a Byte can only save up to 255 counts which may be too few for higher frequency counts per duration. DurX is the active counter variable and DursX is the corresponding saved to EEPROM value as learned from the original audio played

    At program start, load the saved values -

    Code:
    Start:
     
          A = 0
          Durs1 = ERead 1         ' Remember a Word takes up 4 bytes...
          Durs2 = ERead 5
          Durs3 = ERead 10
          Durs4 = ERead 15
          Durs5 = ERead 20
          Durs6 = ERead 25
          Durs7 = ERead 30
          Durs8 = ERead 35
          Durs9 = ERead 40
     
    ' Wait for the switch it start a learn or sample the audio if it is received
     
    Start1:
     
           If SW = 1 Then A = 1 : LED = 1 : DelayMS 5000                     'Set flag A for save.  SW is pressed when a learn cycle starts
     
     
           If Ring = 0 Then LED = 0 : GoTo Start1           'check when a signal received. Ring is the Pic Input Pin for the audio frequency
     
     
           Dur1 = Counter Ring, 100                             ' Get freq count for 100ms
           If Dur1 < 50 Then GoTo Start1                     ' Filter below 500 Hz freq out in case noise was received, redo from Start1
     
           LED = 0
     
           Dur2 = Counter Ring, 100                          ' Get freq count for 100ms
           If Dur2 < 50 Then GoTo Start1                     ' Filter below 500 Hz freq out in case noise was received, redo from Start1
     
           ' Receive 200ms of valid audio over 500Hz before can continue
     
           LED = 1
     
           Dur3 = Counter Ring, 100                          ' Get freq count for 100ms
           If Dur3 < 15 Then Dur3 = 15                     ' If the frequency is too low (ie a pause in the audio) then 150Hz is the dummy value
     
           LED = 0
     
           Dur4 = Counter Ring, 100                           ' Get freq count for 100ms
           If Dur4 < 15 Then Dur4 = 15                     ' If the frequency is too low (ie a pause in the audio) then 150Hz is the dummy value
     
           LED = 1
     
           Dur5 = Counter Ring, 100                           ' Get freq count for 100ms
           If Dur5 < 15 Then Dur5 = 15                     ' If the frequency is too low (ie a pause in the audio) then 150Hz is the dummy value
     
           LED = 0
     
           Dur6 = Counter Ring, 100                           ' Get freq count for 100ms
           If Dur6 < 15 Then Dur6 = 15                     ' If the frequency is too low (ie a pause in the audio) then 150Hz is the dummy value
     
           LED = 1
     
           Dur7 = Counter Ring, 100                           ' Get freq count for 100ms
           If Dur7 < 15 Then Dur7 = 15                      ' If the frequency is too low (ie a pause in the audio) then 150Hz is the dummy value
     
           LED = 0
     
           Dur8 = Counter Ring, 100                           ' Get freq count for 100ms
           If Dur8 < 15 Then Dur8 = 15                     ' If the frequency is too low (ie a pause in the audio) then 150Hz is the dummy value
     
           LED = 1
     
           Dur9 = Counter Ring, 100                           ' Get freq count for 100ms
           If Dur9 < 15 Then Dur9 = 15                     ' If the frequency is too low (ie a pause in the audio) then 150Hz is the dummy value
     
           LED = 0
     
           ' 900ms audio sample done -
           '  Note that the same routine is used to learn as well as sample with.  This ensures the most accurate learned values vs comparison
     
     
    Start2:
          LED = 1
          If A = 1 Then                          ' If the Learn button was pressed, then A = 1
     
          EWrite 1, [Dur1]                     ' save the value of each duration
          EWrite 5, [Dur2]
          EWrite 10, [Dur3]
          EWrite 15, [Dur4]
          EWrite 20, [Dur5]
          EWrite 25, [Dur6]
          EWrite 30, [Dur7]
          EWrite 35, [Dur8]
          EWrite 40, [Dur9]
     
          A = 0
          LED = 0 
          DelayMS 3000
          GoTo Start               'done learning, now go load the new audio values    
          EndIf
     
     
    ' Not learning, A = 0, so check if these received values is the same as the saved ones -
     
    Chk1:
           If Dur1 < Durs1 + 14 And Dur1 > Durs1 - 14 Then GoTo Chk2     'Compare error of + / - 14 counts allowed 
           GoTo Start1              'false frequency input
     
    Chk2:
           If Dur2 < Durs2 + 14 And Dur2 > Durs2 - 14 Then GoTo Chk3
           GoTo Start1              'false frequency input
     
    Chk3:
           If Dur3 < Durs3 + 14 And Dur3 > Durs3 - 14 Then GoTo Chk4
           GoTo Start1              'false frequency input
     
    Chk4:
           If Dur4 < Durs4 + 45 And Dur4 > Durs4 - 45 Then GoTo Chk5
           GoTo Start1              'false frequency input
     
    Chk5:
           If Dur5 < Durs1 + 14 And Dur5 > Durs5 - 14 Then GoTo Chk6
           GoTo Start1              'false frequency input
     
    Chk6:
          If Dur6 < Durs6 + 14 And Dur6 > Durs6 - 14 Then GoTo Chk7
           GoTo Start1              'false frequency input
     
    Chk7:
          If Dur7 < Durs7 + 14 And Dur7 > Durs7 - 14 Then GoTo Chk8
           GoTo Start1              'false frequency input
     
    Chk8:
          If Dur8 < Durs8 + 14 And Dur8 > Durs8 - 14 Then GoTo Chk9
           GoTo Start1              'false frequency input
     
    Chk9:
           If Dur9 < Durs9 + 14 And Dur9 > Durs9 - 14 Then GoTo Chk10
           GoTo Start1              'false frequency input
     
    Chk10:                         ' All 9 comparisons valid  
           Rel1 = 1 
           LED = 0                ' gate striker is opened
           DelayMS 800
           Rel1 = 0               ' Relay 1 off
     
           GoTo Start
     
           End
    Note -

    If you can improve this principle of audio identification or can come up with a better way of doing it with an 8 bit PIC® microcontroller then please let us know by posting on the forum. It will be most interesting.
  • Recent Activity

    kbaykar-24295

    Fault in bit wise comparisons on release 3.6.1.2.

    Thread Starter: kbaykar

    Hi Les, I just downloaded the release 3.6.1.2 today and seeing that it supports 18F47K40. I am trying to port my code from 18F4685 to 18F47K40. ...

    kbaykar Today, 17:26 Go to last post
    John Drew-26

    About Define directive...

    Thread Starter: SELCUK

    Hi Les, Thank you for new version of Proton Plus. For both Compiler version 3.6.1.1 and 3.6.1.2 If I define $DEFINE FF $0C ;// Form...

    John Drew Today, 02:10 Go to last post
    towlerg-21522

    Num_Byte on 18F26K42

    Thread Starter: towlerg

    I'm using a macro that was created by the generator Dump Macro P1 #if (Prm_Count > 1) #error "Dump - Too many parameters" #else ...

    towlerg Today, 19:20 Go to last post
    normnet-324

    Update path?

    Thread Starter: normnet

    I am currently running Proton v3.6.0.2 and would like to update to the latest version. Can i install the latest Update v3.6.1.2 on top of my...

    normnet Today, 14:41 Go to last post