Badly Needed: Microphone Library

Highwinder

Active Member
Licensed User
Longtime User
I have seena good number of posts of people looking for this functionality, which seems to still be missing from B4A: a library that allows full access to/monitoring of the Microphone.

1. It needs to be able to actively monitor Microphone levels WITHOUT having to be writing to a file (just listening).

2. It needs to be able to trigger an event when microphone levels get to a certain level (such as start/stop writing to a file). This must be for both above and below definable levels.

3. It needs to provide status, such as "If Microphone1.StillRecording = True then ...", or "If Microphone1.InputLevel >= 50 then...".

4. It needs to record input by way of click events or automatical detection of mic levels for "buttonless" functionality.

5. It needs to be able to save sound to files in memory or SD card in both wav or mp3 formats.


As fantastic as B4A truly is, the microphone is a very important function of any device that runs our B4a apps. Quite honestly, I was very surprised to find that B4A has no Microphone functionlity. It's a brick wall to some of the apps I was developing, which are now on hold.
 
Last edited:

magarcan

Active Member
Licensed User
Longtime User

Highwinder

Active Member
Licensed User
Longtime User
My library is almost complete.
I now just have to test it with Basic4Android.

XverhelstX

I'll be happy to test it for you, I have an immediate need for this library right now. It' s pretty close to being an emergency.

Does your library include the ability to monitor MIC levels?

Really surprised that B4A has pretty much ignored the microphone, especially considering how critical it is as a hardware component. The Mic has been so far been completely left out of the picture.
 

XverhelstX

Well-Known Member
Licensed User
Longtime User
Ok, the library is done and works great, simple and easy.
You can save in many formats, even mp3 and wav.
I did not add your Mic levels, as I don't know what you mean with it.
Howevern I can add that you can mute or unmute your microphone.

XverhelstX
 

Highwinder

Active Member
Licensed User
Longtime User
Ok, the library is done and works great, simple and easy.
You can save in many formats, even mp3 and wav.
I did not add your Mic levels, as I don't know what you mean with it.
Howevern I can add that you can mute or unmute your microphone.

XverhelstX

I'll elaborate. If you build it, they will come. ;-)

1. It must be able to monitor the levels the microphone is recieving. It must be able to do this without having to be writing to a file (just "listening").

2. It must be able to trigger an event when level variables are met (ie, trigger an event when level goes above or below MIC input level variables).

3. So something like this would be possible (forgive me, I'm a VB guy and still relatively new to B4A, so pardon the syntax butchering):

Microphone1.Listen
Do while Microphone1.Listening
If Microphone1.Level >= 50, then
Microphone1.StartRecording(filenamewhatever)
End If

If Microphone1.Level <= 25 then
Microphone1.StopRecording
Microphone1.StopListening
End If
Loop

Something to this effect (above). Produce such a library, and you'll be everyone's hero, starting with me. :sign0188:
 

Highwinder

Active Member
Licensed User
Longtime User
Hmmm...

I must admit that I'm worried about the crickets chirping in here.

The Android is a phone, and we developers need solid access and monitoring of that microphone.

Unless a full-capability lib is written, it will be impossible to write any apps that are sound-triggered.

I'm afraid it's looking like I have to go into nuisance mode.
 

stevel05

Expert
Licensed User
Longtime User
The Audio recorder library already has the ability to do what you are asking, see attached. The method AudioMaxAmplitude returns the highest level since the last call. and using /dev/null means no file is written.

Got the info here.

You'll have to write your own calls from within the timer_tick subroutine.

I don't know what units the returned values are, if that's important I'm sure it's possible to find out.
 

Attachments

  • MonitorVolume.zip
    5 KB · Views: 1,185

stevel05

Expert
Licensed User
Longtime User
@XverhelstX

Thinking about how highwinder would need to capture the audio, is there any chance you could implement the release method in your library. It would make it easier to start recording to a file without multiple Media Recorder Objects being initialized at once (I think).

Thanks

Steve
 

Highwinder

Active Member
Licensed User
Longtime User
Headed in the right direction!

Steve,

I truly appreciate your insight and comments. VERY valuable to me. I am attempting to write software that monitor's microphone input levels using a timer, as your example so wonderfully demonstrates (again, thanks!).

What I'm trying to do:

If the monitored sound level of the microphone is detected to be above a certain noise level, I want to capture audio to a file for as long as a certain audio level is present. Then, once the audio level drops back down, recording ends and I have the file saved for later playback.

XverhelstX, Steve - you're heroes. Any further assistance you can provide to helping me successfully be able to accomplish the above will be like saving my life. I REALLY appreciate it!
 

stevel05

Expert
Licensed User
Longtime User
What you need to do now, is to decide what level your trigger should be at, then write the logic that says stop monitoring and start recording to a file when that level is exceeded while keeping an eye on he level, once it falls Stop recording to a file and start monitoring.

The main problem I can see is that is that sound is a moving thing, so unless your monitoring for something that you know will be loud and continuous, you're likely to get lots of stops and starts even if the overall level seems quite loud to the ear.

You may want to consider recording for a set time and then check again if you need to keep recording, but you still may hit a trough and start again immediately.

You will only get the best set up once you've tried it.
 

NeoTechni

Well-Known Member
Licensed User
Longtime User
The Audio recorder library already has the ability to do what you are asking, see attached. The method AudioMaxAmplitude returns the highest level since the last call. and using /dev/null means no file is written.

Got the info here.

You'll have to write your own calls from within the timer_tick subroutine.

I don't know what units the returned values are, if that's important I'm sure it's possible to find out.

I got

Compiling code. Error
Error compiling program.
Error description: Unknown member: audiosource
Occurred on line: 45
A.AudioSource=A.AS_MIC
Word: audiosource

NVM, imy library needed updating
 
Last edited:

stevel05

Expert
Licensed User
Longtime User
Have you got the latest version of the audiorecorder library?
 

Gigatron

Member
Licensed User
Longtime User
Microphone Input Level

Hi all

This time i will show you a little exemple to capture Microphone input level.

Based an old source the output level is DOUBLE and Divided by 270.0.
Here is the original code:

B4X:
public double getAmplitude() {
                if (mRecorder != null)
                        return  (mRecorder.getMaxAmplitude()/2700.0);
                else
                        return 0;

        }

And now the B4a Code Based on existing source


B4X:
'Activity module
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.

End Sub

Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.

   Dim T As Timer
   Dim A As AudioRecorder
   Dim level As Double
   Dim Panel1 As Panel
   Dim xitbtn As Button
   Dim cn As Canvas
   Dim rec As Rect
   Dim Label1 As Label
End Sub

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.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 Activity_Resume



End Sub

Sub Activity_Pause (UserClosed As Boolean)
   T.Enabled=False
   A.stop
   
   
End Sub
Sub Text1_Click
   Log("Clicked")
End Sub
Sub AmplitudeCheck_tick
   Level=A.AudioMaxAmplitude/2700.0
   rec.Initialize(20,100,100+level*100,140)
   cn.DrawColor(Colors.RGB(0,0,0))
   cn.DrawRect(rec,Colors.Red,True,5dip)
   panel1.Invalidate
   Label1.Text=level
End Sub

Sub xitbtn_Click
   Activity.Finish
End Sub

Zip example here:

Have fun
 

Attachments

  • Microlevel.zip
    6.6 KB · Views: 1,050
  • pic.jpg
    pic.jpg
    3.8 KB · Views: 800
Last edited:

Cableguy

Expert
Licensed User
Longtime User
This is the easiest way. Wait for someone to do your job :D

Thanks for your library.

I dont agree with that point of view...and I'm sure that you don't either...

There has been some discussion at times, about users that just want a quick fix to their problem, and don't even try to tackle it them-selfs..Others just ask for a comple solution (app)...

We at this forum, like to help others, and mostly, by doing so, we end-up by learning new skills...But NO ONE likes to do other jobs, and mostly, have no credit for it...
(Yeah, I know...a bit off topic, but I just couldn't help it)
 
Last edited:

stevel05

Expert
Licensed User
Longtime User
It appears that the returned value has no real unit see this link
 
Top