Voice detection for Android

Here it is, my fist JAVA application for Android. This is very simple application which introduce how you can get sound from microphone of your phone analyze it and record it on your phones SD card. What new I learn writing this application

  • Initializing AudioRecorder
  • Analyzing every byte of audio buffer
  • Create .wav file from existing audio buffer.

Below you can see whole code of my application. As this is mt first JAVA application for Android maybe it contains some mistakes, but I promise to modify this version.

 

package com.vproject.voicedetection;
 
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
 
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
 
public class VoiceDetectionActivity extends Activity 
{
	// Constant members.
	private static final int SAMPLE_RATE_IN_HZ = 8000;
	private static final int RECORDER_BPP      = 16;
	private static final int CHANNEL_CONFIG    = AudioFormat.CHANNEL_IN_MONO;
	private static final int AUDIO_FORMAT      = AudioFormat.ENCODING_PCM_16BIT;
	private static final int AUDIO_SOURCE      = MediaRecorder.AudioSource.MIC;
	private static final String TAG            = "VoiceDetection";
	private static final int MAX_VOL           = 600;
	private static final int MIN_VAL           = 0;
	private static final int START_RECORD_FROM = 350;
	private static final int CHECK_BLOCK_COUNT = 5;
 
	private Thread onCreateThread     = null;
	private AudioRecord audioRecorder = null;
	private int minBufferSizeInBytes  = 0;
 
 
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
 
        TextView textView = (TextView)findViewById(R.id.textView3); 
		Button button     = (Button)findViewById(R.id.button1);
 
        button.setVisibility( android.view.View.INVISIBLE );
		textView.setVisibility( android.view.View.VISIBLE );
 
        Start();
    }
 
    public void Start( )
    {
    	// Create Handler
        final Handler handler = new Handler() {
 
        	 @Override
             public void handleMessage(Message msg) 
        	 {
        		 int value         = msg.what;
        		 ImageView picture = (ImageView) findViewById(R.id.imageView);
 
        		 int resID[] = { 
        				         R.drawable.image0001, R.drawable.image20, R.drawable.image40,
        				         R.drawable.image60,   R.drawable.image80, R.drawable.image100
        				       };
 
        		 for( int i=MIN_VAL, step = (MAX_VOL - MIN_VAL)/resID.length; i<resID.length; i++ ) {
        			 if( value >= i*step && value <= i*step + step )
        				 picture.setImageResource( resID[i] );
        		 }
 
        		 // Set image for maximum value.
        		 if( value >= MAX_VOL )
    				 picture.setImageResource( R.drawable.image100 );
             }
        };
 
        // Text change handler
        final Handler changeTexthandler = new Handler() {
 
        	@Override
            public void handleMessage(Message msg) 
       	 	{
        		TextView textView = (TextView)findViewById(R.id.textView3); 
        		Button button     = (Button)findViewById(R.id.button1);
 
        		switch( msg.what )
        		{
        			case 0: 
        				textView.setText("Waiting");
        				button.setVisibility( android.view.View.INVISIBLE );
        				textView.setVisibility( android.view.View.VISIBLE );
        				break;
        			case 1:
        				textView.setText("Recording");
        				button.setVisibility( android.view.View.INVISIBLE );
        				textView.setVisibility( android.view.View.VISIBLE );
        				break;
        			default:
        				button.setVisibility( android.view.View.VISIBLE );
        				textView.setVisibility( android.view.View.INVISIBLE );
        				break;
 
        		}
 
       	 	}
 
        };
 
        // Initialize minimum buffer size in bytes.
        minBufferSizeInBytes = AudioRecord.getMinBufferSize( SAMPLE_RATE_IN_HZ,
        		                                             CHANNEL_CONFIG,
        		                                             AUDIO_FORMAT
        		                                            );
 
        if( minBufferSizeInBytes == AudioRecord.ERROR_BAD_VALUE )
        	Log.e( TAG, "Bad Value for \"minBufferSize\", recording parameters are not supported by the hardware" );
 
        if( minBufferSizeInBytes == AudioRecord.ERROR )
        	Log.e( TAG, "Bad Value for \"minBufferSize\", implementation was unable to query the hardware for its output properties" );
 
        // Initialize Audio Recorder.
        try {
        	audioRecorder = new AudioRecord( AUDIO_SOURCE,
        									 SAMPLE_RATE_IN_HZ,
        									 CHANNEL_CONFIG,
        									 AUDIO_FORMAT,
        									 minBufferSizeInBytes 
        		                            );
        }
        catch(IllegalArgumentException ex) {
        	Log.e( TAG, "Illegal Arguments: " + ex.getMessage() );
        }
 
        // Launch Thread.
        onCreateThread = new Thread( new Runnable() {
 
			@Override
			public void run() 
			{
				// Starts recording from the AudioRecord instance. 
				audioRecorder.startRecording();
 
				int numberOfBytesRead  = 0;
				byte audioBuffer[]     = new byte[minBufferSizeInBytes];
				float tempBuffer[]     = new float[CHECK_BLOCK_COUNT];
				int tempIndex          = 0;
				boolean isRecording    = false;
				int totalReadBytes     = 0;
			    byte totalByteBuffer[] = new byte[60 * 44100 * 2];
 
				// While data coming from microphone.
				while( true )
				{
					float totalAbsValue = 0.0f;
		        	short sample        = 0; 
					numberOfBytesRead   = audioRecorder.read( audioBuffer, 0, minBufferSizeInBytes );
 
					// Analyze income sound. 
					for( int i=0; i<minBufferSizeInBytes; i+=2 ) {
		       	 		sample = (short)( (audioBuffer[i]) | audioBuffer[i + 1] << 8 );
		       	 		totalAbsValue += Math.abs( sample ) / (numberOfBytesRead/2);
		       	 	}
 
					// Set Animation of microphone.
					handler.sendEmptyMessage((int)totalAbsValue);
 
					// Analyze tempBuffer.
					tempBuffer[tempIndex%CHECK_BLOCK_COUNT] = totalAbsValue;
					float tempBufferTotalCount              = 0.0f;
		       	 	for( int i=0; i<CHECK_BLOCK_COUNT; ++i )
		       	 		tempBufferTotalCount += tempBuffer[i];
 
		       	 	// Finalize value.
		       	 	tempBufferTotalCount = tempBufferTotalCount/CHECK_BLOCK_COUNT;
 
		       	 	// Waiting for load speak to start recording.
		       	 	if( (tempBufferTotalCount >=0 && tempBufferTotalCount <= START_RECORD_FROM) && !isRecording )
		       	 	{
		       	 		Log.i("TAG", "Waiting for voice to start record.");
		       	 		tempIndex++;
		       	 		changeTexthandler.sendEmptyMessage(0);
		       	 		continue;
		       	 	}
 
		       	 	if( tempBufferTotalCount > START_RECORD_FROM && !isRecording )
		       	 	{
		       	 		Log.i("TAG", "Recording");
		       	 		changeTexthandler.sendEmptyMessage(1);
		       	 		isRecording = true;
		       	 	}
 
		       	 	// Stop Recording and save data to file.
		       	 	if( (tempBufferTotalCount >= 0 && tempBufferTotalCount <= START_RECORD_FROM) && isRecording )
		       	 	{
		       	 		Log.i("TAG", "Stop Recording and Save data to file");
		       	 		changeTexthandler.sendEmptyMessage(2);	
 
		       	 		audioRecorder.stop();
		       	 		audioRecorder.release();
		       	 		audioRecorder = null;
 
 
		       	 	    SaveDataToFile( totalReadBytes, totalByteBuffer );
		       	 	    totalReadBytes = 0;	
 
		       	 		tempIndex++;
		       	 		break;
		       	 	}
 
		       	 	// Record Sound.
		       	 	for( int i=0; i<numberOfBytesRead; i++ )	
		       	 		totalByteBuffer[totalReadBytes + i] = audioBuffer[i];
 
		       	 	totalReadBytes += numberOfBytesRead;
		       	 	tempIndex++;
				}
 
			}
 
        }, "Voice Detection Thread" );
 
        // Run the Thread.
        onCreateThread.start();
        //*/
    }
 
    public void SaveDataToFile( int totalReadBytes, byte[] totalByteBuffer )
    {
    	// Save audio to file.
	 	String filepath = Environment.getExternalStorageDirectory().getPath();
	 	File file = new File( filepath, "VioceDetectionDemo" );
	 	if( !file.exists( ) )
	 		file.mkdirs();
 
	 	// String fileName = file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".wav";
	 	// File always saved by same name.
	 	String fileName = file.getAbsolutePath() + "/" + "VoiceDetectionDemo" + ".wav";
 
	 	long totalAudioLen  = 0;
	 	long totalDataLen   = totalAudioLen + 36;
	 	long longSampleRate = SAMPLE_RATE_IN_HZ;
	 	int channels        = 1;
	 	long byteRate       = RECORDER_BPP * SAMPLE_RATE_IN_HZ * channels/8;
	 	totalAudioLen       = totalReadBytes;
	 	totalDataLen        = totalAudioLen + 36;
        byte finalBuffer[]  = new byte[totalReadBytes + 44];
 
        finalBuffer[0]  = 'R';  // RIFF/WAVE header
        finalBuffer[1]  = 'I';
        finalBuffer[2]  = 'F';
        finalBuffer[3]  = 'F';
        finalBuffer[4]  = (byte) (totalDataLen & 0xff);
        finalBuffer[5]  = (byte) ((totalDataLen >> 8) & 0xff);
        finalBuffer[6]  = (byte) ((totalDataLen >> 16) & 0xff);
        finalBuffer[7]  = (byte) ((totalDataLen >> 24) & 0xff);
        finalBuffer[8]  = 'W';
        finalBuffer[9]  = 'A';
        finalBuffer[10] = 'V';
        finalBuffer[11] = 'E';
        finalBuffer[12] = 'f';  // 'fmt ' chunk
        finalBuffer[13] = 'm';
        finalBuffer[14] = 't';
        finalBuffer[15] = ' ';
        finalBuffer[16] = 16;  // 4 bytes: size of 'fmt ' chunk
        finalBuffer[17] = 0;
        finalBuffer[18] = 0;
        finalBuffer[19] = 0;
        finalBuffer[20] = 1;  // format = 1
        finalBuffer[21] = 0;
        finalBuffer[22] = (byte) channels;
        finalBuffer[23] = 0;
        finalBuffer[24] = (byte) (longSampleRate & 0xff);
        finalBuffer[25] = (byte) ((longSampleRate >> 8) & 0xff);
        finalBuffer[26] = (byte) ((longSampleRate >> 16) & 0xff);
        finalBuffer[27] = (byte) ((longSampleRate >> 24) & 0xff);
        finalBuffer[28] = (byte) (byteRate & 0xff);
        finalBuffer[29] = (byte) ((byteRate >> 8) & 0xff);
        finalBuffer[30] = (byte) ((byteRate >> 16) & 0xff);
        finalBuffer[31] = (byte) ((byteRate >> 24) & 0xff);
        finalBuffer[32] = (byte) (2 * 16 / 8);  // block align
        finalBuffer[33] = 0;
        finalBuffer[34] = RECORDER_BPP;  // bits per sample
        finalBuffer[35] = 0;
        finalBuffer[36] = 'd';
        finalBuffer[37] = 'a';
        finalBuffer[38] = 't';
        finalBuffer[39] = 'a';
        finalBuffer[40] = (byte) (totalAudioLen & 0xff);
        finalBuffer[41] = (byte) ((totalAudioLen >> 8) & 0xff);
        finalBuffer[42] = (byte) ((totalAudioLen >> 16) & 0xff);
        finalBuffer[43] = (byte) ((totalAudioLen >> 24) & 0xff);
 
        for( int i=0; i<totalReadBytes; ++i )
        	finalBuffer[44+i] = totalByteBuffer[i];
 
        FileOutputStream out;
		try {
			out = new FileOutputStream(fileName);
			 try {
					out.write(finalBuffer);
					out.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
 
		} catch (FileNotFoundException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
    }
 
    public void OnClickButtonTryAgain(View view)
    {
    	Start();
    }
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值