Some way to read from phone microphone in game

Monkey Targets Forums/Android/Some way to read from phone microphone in game

matty(Posted 2011) [#1]
Hello all,

Just wondering if there is a method by which we can get user input from the microphone on the user's phone. I'd imagine it should not be too difficult to get some kind of reading, much like we do with the GPS..so if anyone has already put something like this together I'd be keen to see it.

I've had a look through the android classes on the android developer webpage but cannot see which one might relate to the microphone. I initially thought the 'sensors' section may, but I'm not sure.

Thanks,
Matt


skid(Posted 2011) [#2]
http://developer.android.com/reference/android/media/AudioRecord.html


therevills(Posted 2011) [#3]
This looks like how you would do it:

http://code.google.com/p/android-labs/source/browse/trunk/NoiseAlert/src/com/google/android/noisealert/SoundMeter.java


matty(Posted 2011) [#4]
thanks I'll have a look at those.


matty(Posted 2011) [#5]
I've had a look at that code - I'm still fairly unsure of myself when it comes to native java code for android...let alone java code full stop but I've tried putting the following together and I get an error on compile about catching an exception not being done...not sure I understand...here is what I have in my code:

"android.java"
import android.media.MediaRecorder;

class SoundMeter {


        static final private double EMA_FILTER = 0.6;
        private static MediaRecorder mRecorder = null;
        private static double mEMA = 0.0;


        static void start() {
    	    if (mRecorder == null)
				{
    	            mRecorder = new MediaRecorder();
                    mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        	        mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
                    mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
                    mRecorder.setOutputFile("/dev/null"); 
					try
					{			
               		mRecorder.prepare();
    				}catch (java.lang.SecurityException e) {
						android.util.Log.e("[Monkey]", "SecurityException: " + android.util.Log.getStackTraceString(e));
					}
					try
					{			
               		mRecorder.start();
					}catch (java.lang.SecurityException e) {
						android.util.Log.e("[Monkey]", "SecurityException: " + android.util.Log.getStackTraceString(e));
					}
	
                    mEMA = 0.0;
                }
				
        }
        
        static void stop() {
                if (mRecorder != null) {
                        mRecorder.stop();       
                        mRecorder.release();
                        mRecorder = null;
                }
        }
        
        static float getAmplitude() {
                if (mRecorder != null)
                        return  (float)(mRecorder.getMaxAmplitude()/2700.0);
                else
                        return 0;

        }

        static float getAmplitudeEMA() {
                float amp = getAmplitude();
                mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
                return (float)mEMA;
        }
}


and in monkey

Strict
Import mojo
Import "android.java"

Extern
	Function StartRecord:Void()="SoundMeter.start"
	Function StopRecord:Void()="SoundMeter.stop"
	Function GetAmplitude:Float()="SoundMeter.getAmplitude"
	Function GetAmplitudeEMA:Float()="SoundMeter.getAmplitudeEMA"
Public

Function Main:Int()

Local myapp:MyApp
myapp = New MyApp

Return 0
End Function 

Class MyApp Extends App

Method OnCreate:Int()

StartRecord()

SetUpdateRate 30
Return 0
End Method

Method OnUpdate:Int()

Return 0
End Method

Method OnRender:Int()

Cls
DrawText String(GetAmplitude()),0,0

Return 0
End Method

End Class


and the error I'm getting on compile:

compile:
    [javac] C:\Program Files\Android\android-sdk\tools\ant\main_rules.xml:384: warning: 'includeantruntime' was not set, defaulting to build.sysclasspath=last; set to false for repeatable builds
    [javac] Compiling 2 source files to C:\MonkeyPro44\MonkeyPro44\androidgps\androidsoundmeter.build\android\bin\classes
    [javac] C:\MonkeyPro44\MonkeyPro44\androidgps\androidsoundmeter.build\android\src\com\monkey\MonkeyGame.java:1663: unreported exception java.io.IOException; must be caught or declared to be thrown
    [javac]                		mRecorder.prepare();
    [javac]                		                 ^
    [javac] Note: C:\MonkeyPro44\MonkeyPro44\androidgps\androidsoundmeter.build\android\src\com\monkey\MonkeyGame.java uses unchecked or unsafe operations.
    [javac] Note: Recompile with -Xlint:unchecked for details.
    [javac] 1 error
BUILD FAILED



I feel as if each time I post one of these questions I end up basically just asking for the code...sorry about that. EDIT - I must admit I don't really know what I'm doing with the java code..


therevills(Posted 2011) [#6]
Try adding another catch statement with the IOException:

static void start() {
	if (mRecorder == null) {
		mRecorder = new MediaRecorder();
		mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
		mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
		mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
		mRecorder.setOutputFile("/dev/null"); 
		try {			
			mRecorder.prepare();
		} catch (java.lang.SecurityException e) {
			android.util.Log.e("[Monkey]", "SecurityException: " + android.util.Log.getStackTraceString(e));
		} catch (IOException e) {
			android.util.Log.e("[Monkey]", "IOException: " + android.util.Log.getStackTraceString(e));
		}
		try {			
			mRecorder.start();
		}catch (java.lang.SecurityException e) {
			android.util.Log.e("[Monkey]", "SecurityException: " + android.util.Log.getStackTraceString(e));
		} catch (IOException e) {
			android.util.Log.e("[Monkey]", "IOException: " + android.util.Log.getStackTraceString(e));
		}

		mEMA = 0.0;
	}	
}


* Not tested ;)


matty(Posted 2011) [#7]
Thanks, tried again but still get an error on compile. Not entirely sure how to code this.


therevills(Posted 2011) [#8]
I added too many } to the code above:



You also need to add this in the AndroidManifest.xml:
<uses-permission android:name="android.permission.RECORD_AUDIO" />


So it now runs, but it doesnt really seem to do much :/


matty(Posted 2011) [#9]
Thanks it works well....


therevills(Posted 2011) [#10]
It does? It didnt seem to do anything on my phone...


matty(Posted 2011) [#11]
Yes...I can blow a little sailing boat around a waterway....(lots of ideas could spring from this)

Simply run the start method in OnCreate, then check GetAmplitude in the OnUpdate method for a result....works fine on my phone.