Android Question using microphone input

jonas4

Member
Licensed User
Hi there,
does someone got experiences in using the microphone socket for reading voltage levels? I looked in the forum for oscilloscope applications, but it seems they all use bluetooth for input...
Thanks.
 

jonas4

Member
Licensed User
I'll try. I forgot to explain, that it has to be a real time application, that means that my app should display the incoming voltatage (which corresponds to a motor current) i.e. like an analog clock. May be it's possible to analyse the raw data continously?...Thank you erel for the first.
 

Isa Paine

Member
Licensed User
Jonas4, how did you convert the stream of bytes that comes back from the AudioStreamer into a voltage?
 

jonas4

Member
Licensed User
Hi Isa,

I used the MonitorVolume-App to get the voltage level at the microphone socket, which was provided by stevel05, look here: https://www.b4x.com/android/forum/threads/badly-needed-microphone-library.11731/

In the sub AmplitudeCheck_tick I used the divisor, here: 2700.0, to calibrate voltage level.

B4X:
Sub AmplitudeCheck_tick
    level=A.AudioMaxAmplitude/2700.0
    rec.Initialize(20,100,15+level*100,140)
    cn.DrawColor(Colors.RGB(0,0,0))
    cn.DrawRect(rec,Colors.Red,True,5dip)
    Panel1.Invalidate
    'Label1.Text=level
End Sub
For more information about the external connection of the microphone input, look at this:

http://www.nicomania.de/ipod/oszilloskop-tastkopf-fuer-ipod-iphone-und-android


Please don't forget to initialize AudioRecorder Object in Sub ActivityCreate, as I mentioned in my thread:

B4X:
Sub Activity_Create(FirstTime As Boolean)
  
    Activity.LoadLayout("Level")
    cn.Initialize(Panel1)
      
    'Calls sub AmplitudeCheck every 500 milliseconds
    T.Initialize("AmplitudeCheck",100)
  
    'Set up recorder
    A.Initialize
    A.AudioSource=A.AS_MIC
    ...
I finally stopped this project, because I could not mute the internal microphone at my LG optimus 440 E phone. The code, which is given in MonitorVolume App:

B4X:
Sub Activity_Create(FirstTime As Boolean)
   
    'Mute the internal Mic:
    Dim R As Reflector
    R.Target = R.GetContext
    R.Target = R.RunMethod2("getSystemService", "audio", "java.lang.String")                    
    R.RunMethod2("setMicrophoneMute", True, "java.lang.boolean")
does mute both, the internal and the external microphone, so I could not use the microphone input socket anymore.

I hope that this will be helpful...
 

Isa Paine

Member
Licensed User
On the Samsung Galaxy S4 & S5 the internal mic is automatically disabled once an external mic is plugged into the 3.5mm jack.
I am running the project you suggest, but how do I convert 600 Hz (approx.) into a temperature?
 

Isa Paine

Member
Licensed User
Here are the 2 relevant functions

B4X:
Sub Activity_Create(FirstTime As Boolean)
   
    Activity.LoadLayout("Level")
    cn.Initialize(Panel1)
   
   
    'Calls sub AmplitudeCheck every 500 milliseconds
    T.Initialize("AmplitudeCheck",100)
   
    'Set up recorder
    A.Initialize
    A.AudioSource=A.AS_MIC
    A.OutputFormat=A.OF_THREE_GPP
    A.AudioEncoder=A.AE_AMR_NB
    A.setOutputFile("","/dev/null")
    A.prepare
    
    A.start
    T.Enabled=True
End Sub

Sub AmplitudeCheck_tick
    'level=A.AudioMaxAmplitude/2700.0
    level=A.AudioMaxAmplitude/44100
    rec.Initialize(20,100,15+level*100,140)
    cn.DrawColor(Colors.RGB(0,0,0))
    cn.DrawRect(rec,Colors.Red,True,5dip)
    Panel1.Invalidate
    Label1.Text=level
End Sub
 

jonas4

Member
Licensed User
I can't say exactly how to do, but this could be the direction I would go in this case:

If you got a rectangular signal of 600 Hz, the duration for one cycle would be: 1/600 s = 1.6 ms. If you have a mark-to-space ratio of 1:1, then the signal would be for 1.6 / 2 = 0.8 Milliseconds "HIGH" (that means the voltage level should be above a certain level, which has to be defined).

If you can detect the voltage level at the microphone input within a interval, which is much smaller than the duration of a "HIGH", e.g. 0.2 ms, than you can be sure to detect all periods. In Activity_Create is specified am interval of 500 ms using the parameter of 100:

B4X:
    'Calls sub AmplitudeCheck every 500 milliseconds
    T.Initialize("AmplitudeCheck",100)
I don't know if it is possible to down-regulate it to a range we need in this case. Assuming that this is possible ( the CPUs frequency is much higher and should not be the limiting factor), then it would be usefull to count the "HIGHS" in a certain time segment, like this:

BEGIN Loop
Detect Level.
Is Level HIGH?
Yes
 

jonas4

Member
Licensed User
...Continuation:
Yes No
High-Flag is set? Reset High Flag
Yes No
Wait a time increase impuls counter
Set High Flag
Increase Time-counter
Time-counter = Preset Interval Value?
Yes No
Output value Goto BEGIN Loop

... Something like that.

The High Flag prevents an impuls beeing counted more than once.
 

jonas4

Member
Licensed User
.... for a better reading:
B4X:
Start

Reset High-Flag
Set time counter = impulse counter = 0

Begin Loop

Is Level HIGH?
    Yes                                       No
    High Flag set?
    Yes            No
    Wait a time    Increase impulse counter
                   Set High Flag
  
    Increase time counter

    Time counter = preset interval value?
    Yes                No
    Output value       Goto Begin Loop
    Goto Start
 

Isa Paine

Member
Licensed User
I know 600 Hz is being sent into the mic jack, but what is being displayed in the App is .0635 +-. Are the setting for the objects in the two code segments correct?
 

Isa Paine

Member
Licensed User
Frequency. My hardware engineer is saying I need to figure out how to convert the incoming mic jack signal to frequency.
 
Top