`

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();
    }
}
 
分享到:
评论

相关推荐

    Voice activity detection (VAD) toolkit including DNN, bDNN

    Voice Activity Detection(VAD)工具包是用于识别和分离音频信号中语音部分的关键技术,它在许多领域,如语音识别、语音编码、噪声抑制和通信系统中都有广泛应用。本工具包特别强调了深度学习方法,包括DNN(深度...

    Voice Activity Detection in the Tiger Platform

    声音活动检测(Voice Activity Detection,简称VAD)技术在通信领域扮演着重要的角色。尤其在加密通信终端中,通过有效地区分语音段与非语音段,可以显著减少传输所需带宽并降低延迟。《声音活动检测在Tiger平台中的...

    Voice Application Development for Android

    《Android语音应用开发》是一本关于如何使用开源软件开发Android上先进有趣语音应用的实践指南。这本书作为较新且受欢迎的Android口袋书系列之一,因其内容短小精悍,非常适合用作音频开发的入门书籍,其在亚马逊上...

    voice record on android

    voice record for different sampling rate and store in different format on android. optionally display the audio

    a statistical model-based voice activity detection

    语音活动检测(Voice Activity Detection,VAD)是通信和音频处理领域中的关键技术,它主要用于识别音频信号中是否存在语音成分。统计模型在VAD中扮演着重要角色,因为它们能够捕捉到语音和噪声信号的特性差异,从而...

    voice-music-detection_人声_voice-detection_人声识别_music-detection_用双

    标题中的"voice-music-detection_人声_voice-detection_人声识别_music-detection_用双"涉及到的是音频处理领域中的一个关键技术,即人声与音乐的检测。这个技术主要用于从音频流中分离出人声部分和背景音乐部分,...

    voicebox for matlab

    voicebox for matlab matlab中的voicebox工具箱,主要功能是进行语音分析。 解压到matlab安装路径中的toolbox文件夹中, 之后在matlab主界面点击“设置路径”然后将voicebox工具箱添加路径即可。好东西,不解释。

    Void A fast and light voice liveness detection system.pdf

    标题中提到的“Void: A fast and light voice liveness detection system”指的是一个快速、轻量级的声音活体检测系统,它被命名为“Void”。在声音活体检测的领域,这是一个重要而具体的研究课题,尤其是考虑到随着...

    语音识别数据集-speech analytic--性别识别--Voice Gender Detection using GMMs-1

    标题中的“语音识别数据集-speech analytic--性别识别--Voice Gender Detection using GMMs-1”揭示了这个压缩包文件的主要内容,它是一个用于语音识别的特定任务——性别识别的数据集,采用的方法是基于高斯混合...

    androidvoice

    "androidvoice"这个主题涵盖了许多Android SDK中的核心组件和技术,特别是与音频处理和播放相关的API。在这个项目中,我们将深入探讨如何在Android系统上实现音频播放,并讨论相关的编程概念。 首先,Android为音频...

    voice-music-detection_人声_voice-detection_人声识别

    标题中的“voice-music-detection_人声_voice-detection_人声识别”表明这是一个关于语音与音乐检测,特别是人声识别的技术项目。描述中的“music-detection_用双门限法_源码.rar.rar”揭示了这个压缩包包含了使用...

    FireMonkey-Android-Voice-master

    这个“FireMonkey-Android-Voice-master”项目显然与在Android平台上使用FireMonkey框架来实现语音功能有关。 1. **FireMonkey框架**: FireMonkey 提供了一个高级的、硬件加速的渲染引擎,可以创建具有现代视觉效果...

    Manning.Voice.Applications.for.Alexa.and.Google.rar

    To create their own voice "skills," users need to learn some new device toolkits, the basics of Voice UI design, and some emerging best practices for building and deploying on these diverse platforms....

    Voice Changer Premium「语音转换器」v1.8.1 for Android 支持许多不同的效果,唱卡拉OK和录音更容易.rar

    Voice Changer Premium是一款专为Android用户设计的高级语音转换应用,其主要功能是改变用户的语音,使其听起来有各种独特的效果。这款应用版本号为1.8.1,旨在提供一个简单而有趣的平台,让用户在唱歌、聊天或者...

    语音识别数据集-speech analytic--性别识别--Voice Gender Detection using GMMs-2

    在本文中,我们将深入探讨基于高斯混合模型(GMMs)的语音性别识别技术,这是一个在【标题】"语音识别数据集-speech analytic--性别识别--Voice Gender Detection using GMMs-2"中提到的核心知识点。【描述】中提供...

    voice_detection_impl.rar_processing

    "voice_detection_impl.rar_processing"这个标题暗示我们关注的是一个用于声音检测的实现,可能是一个软件组件或者库,它处理音频数据来识别其中的人声部分。在这个项目中,重点是理解和解析"voice_detection_impl.c...

    android_voice.rar

    "android_voice.rar"这个压缩包可能包含了实现这些功能的示例代码。在这个压缩包中,开发者可以找到如何利用Android SDK中的相关API来处理语音交互的教程。下面我们将深入探讨Android拨打电话和发送短信的原理以及...

    Android代码-voice-overlay-android

    Voice overlay helps you turn your user's voice into text, providing a polished UX while handling for you the necessary permission. Demo You can clone this repo, then run the Demo ...

Global site tag (gtag.js) - Google Analytics