Android Question using microphone input

jonas4

Member
Licensed User
Longtime 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
Longtime 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.
 
Upvote 0

Isa Paine

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

jonas4

Member
Licensed User
Longtime 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...
 
Upvote 0

Isa Paine

Member
Licensed User
Longtime 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?
 
Upvote 0

Isa Paine

Member
Licensed User
Longtime 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
 
Upvote 0

jonas4

Member
Licensed User
Longtime 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
 
Upvote 0

jonas4

Member
Licensed User
Longtime 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.
 
Upvote 0

jonas4

Member
Licensed User
Longtime 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
 
Upvote 0

Isa Paine

Member
Licensed User
Longtime 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?
 
Upvote 0

Isa Paine

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