Voice Detection in Android Application

Voice Detection in Android Application

Just add this code to your application and you will detect when user start to speak and when he stops.

public void onCreate(Bundle savedInstanceState) 
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// Get the minimum buffer size required for the successful creation of an AudioRecord object.
int bufferSizeInBytes = AudioRecord.getMinBufferSize( RECORDER_SAMPLERATE,
RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING
);
// Initialize Audio Recorder.
AudioRecord audioRecorder = new AudioRecord( MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE,
RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING,
bufferSizeInBytes
);
// Start Recording.
audioRecorder.startRecording();

int numberOfReadBytes = 0;
byte audioBuffer[] = new byte[bufferSizeInBytes];
boolean recording = false;
float tempFloatBuffer[] = new float[3];
int tempIndex = 0;
int totalReadBytes = 0;
byte totalByteBuffer[] = new byte[60 * 44100 * 2];

// While data come from microphone.
while( true )
{
float totalAbsValue = 0.0f;
short sample = 0;

numberOfReadBytes = audioRecorder.read( audioBuffer, 0, bufferSizeInBytes );

// Analyze Sound.
for( int i=0; i<bufferSizeInBytes; i+=2 )
{
sample = (short)( (audioBuffer[i]) | audioBuffer[i + 1] << 8 );
totalAbsValue += Math.abs( sample ) / (numberOfReadBytes/2);
}

// Analyze temp buffer.
tempFloatBuffer[tempIndex%3] = totalAbsValue;
float temp = 0.0f;
for( int i=0; i<3; ++i )
temp += tempFloatBuffer[i];

if( (temp >=0 && temp <= 350) && recording == false )
{
Log.i("TAG", "1");
tempIndex++;
continue;
}

if( temp > 350 && recording == false )
{
Log.i("TAG", "2");
recording = true;
}

if( (temp >= 0 && temp <= 350) && recording == true )
{
Log.i("TAG", "Save audio to file.");

// Save audio to file.
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath,"AudioRecorder");
if( !file.exists() )
file.mkdirs();

String fn = file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".wav";

long totalAudioLen = 0;
long totalDataLen = totalAudioLen + 36;
long longSampleRate = RECORDER_SAMPLERATE;
int channels = 1;
long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * 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(fn);
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();
}

//*/
tempIndex++;
break;
}

// -> Recording sound here.
Log.i( "TAG", "Recording Sound." );
for( int i=0; i<numberOfReadBytes; i++ )
totalByteBuffer[totalReadBytes + i] = audioBuffer[i];
totalReadBytes += numberOfReadBytes;
//*/

tempIndex++;

}
}

Check this link.

Detect voice by audio recorder in android studio

Well, I solved my problem, here is my solution.
I modified the code came from this url:
Voice Detection in Android Application

private static final String TAG = "MainActivity";

private static int RECORDER_SAMPLERATE = 44100;
private static int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
private static int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;

private Button btn, btn_convert, btn_play;
private TextView txv;

boolean isRecording = false;
private File file;
private AudioRecord audioRecord;
int bufferSizeInBytes = 0;
Context context = MainActivity.this;

// path
final String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/final.pcm" ;
final String outpath = path.replace(".pcm", ".wav");

public void autoRecording(){
// Get the minimum buffer size required for the successful creation of an AudioRecord object.
bufferSizeInBytes = AudioRecord.getMinBufferSize( RECORDER_SAMPLERATE,
RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING
);
// Initialize Audio Recorder.
AudioRecord audioRecorder = new AudioRecord( MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE,
RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING,
bufferSizeInBytes
);
// Start Recording.
txv.setText("Ing");
audioRecorder.startRecording();
isRecording = true;

// for auto stop
int numberOfReadBytes = 0;
byte audioBuffer[] = new byte[bufferSizeInBytes];
boolean recording = false;
float tempFloatBuffer[] = new float[3];
int tempIndex = 0;

// create file

file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/final.pcm");
Log.d(TAG, "recording: file path:" + file.toString());

if (file.exists()){
Log.d(TAG,"file exist, delete file");
file.delete();
}
try {
Log.d(TAG,"file created");
file.createNewFile();
} catch (IOException e) {
Log.d(TAG,"didn't create the file:" + e.getMessage());
throw new IllegalStateException("did not create file:" + file.toString());
}

// initiate media scan and put the new things into the path array to
// make the scanner aware of the location and the files you want to see
MediaScannerConnection.scanFile(context, new String[] {file.toString()}, null, null);

// output stream
OutputStream os = null;
DataOutputStream dos = null;
try {
os = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(os);
dos = new DataOutputStream(bos);
} catch (FileNotFoundException e) {
e.printStackTrace();
}

// While data come from microphone.
while( true )
{
float totalAbsValue = 0.0f;
short sample = 0;

numberOfReadBytes = audioRecorder.read( audioBuffer, 0, bufferSizeInBytes );

// Analyze Sound.
for( int i=0; i<bufferSizeInBytes; i+=2 )
{
sample = (short)( (audioBuffer[i]) | audioBuffer[i + 1] << 8 );
totalAbsValue += (float)Math.abs( sample ) / ((float)numberOfReadBytes/(float)2);
}

// read in file
for (int i = 0; i < numberOfReadBytes; i++) {
try {
dos.writeByte(audioBuffer[i]);
} catch (IOException e) {
e.printStackTrace();
}
}

// Analyze temp buffer.
tempFloatBuffer[tempIndex%3] = totalAbsValue;
float temp = 0.0f;
for( int i=0; i<3; ++i )
temp += tempFloatBuffer[i];

if( (temp >=0 && temp <= 2100) && recording == false ) // the best number for close to device: 3000
{ // the best number for a little bit distance : 2100
Log.i("TAG", "1");
tempIndex++;
continue;
}

if( temp > 2100 && recording == false )
{
Log.i("TAG", "2");
recording = true;
}

if( (temp >= 0 && temp <= 2100) && recording == true )
{

Log.i("TAG", "final run");
//isRecording = false;

txv.setText("Stop Record.");
//*/
tempIndex++;
audioRecorder.stop();
try {
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
break;
}
}
}

The function of this function:
if you call this function, the recorder will start recording, and once you make sound(Notify if there are some noise it will stop too.) it will stop recording and save into file(pcm format).

How to enable Android Open Application voice interaction

As far as I am aware, Google simply iterates over a list of installed applications and opens the corresponding application if it finds an exact match.

To test this, use the following Intent

        final String PACKAGE_NAME_GOOGLE_NOW = "com.google.android.googlequicksearchbox";
final String GOOGLE_NOW_SEARCH_ACTIVITY = ".SearchActivity";
final String APP_NAME = "Open " +getString(R.string.app_name);

final Intent startMyAppIntent = new Intent(Intent.ACTION_WEB_SEARCH);
startMyAppIntent.setComponent(new ComponentName(PACKAGE_NAME_GOOGLE_NOW,
PACKAGE_NAME_GOOGLE_NOW + GOOGLE_NOW_SEARCH_ACTIVITY));

startMyAppIntent.putExtra(SearchManager.QUERY, APP_NAME);
startMyAppIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

try {
startActivity(startMyAppIntent);
} catch (final ActivityNotFoundException e) {
e.printStackTrace();
}

If this opens your application, then it is simply a case of the phonetics of your application name, or how Google interprets your pronunciation of it.

I do think that there should be an option to add a 'phonetic app label' to the application's manifest (or some other globally available configuration file), so Google could open your application if the unique name is not common enough to generate a voice search result.

If this doesn't open your application, check that you are correctly defining your application name in the manifest as follows:

<application
android:label="@string/app_name"

How To: Voice Commands into an android application

If you want to add voice recognition to your group's Android app it is very simple.

Throughout this tutorial you will need to add imports as you paste in the code.

  1. Create an xml file or use an existing one and make sure that you add a button and a listview.
  2. In a java class you need to extend activity and implement OnClickListener
    You will get an error that says you have unimplemented methods. Hover over it and add the unimplemented methods. We will add to this later.
  3. Next set up the button and listview in your java.

    public ListView mList;
    public Button speakButton;

    also add:

    public static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;
  4. Next, make an OnCreate Method and set up the button and listener.

    speakButton = (Button) findViewById(R.id.btn_speak);
    speakButton.setOnClickListener(this);

    also add this method(we will set it up next)

    voiceinputbuttons();

    Remember to setContentView for the xml you are showing.

  5. Outside of your oncreate make a new method that looks like this.

    public void voiceinputbuttons() {
    speakButton = (Button) findViewById(R.id.btn_speak);
    mList = (ListView) findViewById(R.id.list);
    }
  6. Now you will have to set up your voice recognition activity by using the following code.

    public void startVoiceRecognitionActivity() {
    Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
    intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
    RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
    intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
    "Speech recognition demo");
    startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
    }
  7. Next, inside your onclick method from step 2 add the activity from step 6.

    startVoiceRecognitionActivity();
  8. Next we will have to set up another method. Copy and paste the following code.

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) {
    ArrayList<String> matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
    mList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, matches));

    matches is the result of voice input. It is a list of what the user possibly said. Using an if statement for the keyword you want to use allows the use of any activity if keywords match it is possible to set up multiple keywords to use the same activity so more than one word will allow the user To use the activity (makes it so the user doesn't have to memorize words from a list) To use an activity from the voice input information simply use the following format;

    if (matches.contains("information")) {
    informationMenu();
    }

    NOTE: you can format the code any time by pressing ctrl+shift+F in eclipse.

  9. Now we are going to set up our method used by the code in step 8. This code creates an intent to direct the user to a new menu. You will need another xml and java class for this. Also, remember to add an activity to your manifest.

    public void informationMenu() {
    startActivity(new Intent("android.intent.action.INFOSCREEN"));
    }
  10. Finally you need to set up some code that will let the user know if the mic is operational. Paste this code inside of the OnCreate method at the end.

    // Check to see if a recognition activity is present
    // if running on AVD virtual device it will give this message. The mic
    // required only works on an actual android device
    PackageManager pm = getPackageManager();
    List activities = pm.queryIntentActivities(new Intent(
    RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
    if (activities.size() != 0) {
    voiceButton.setOnClickListener(this);
    } else {
    voiceButton.setEnabled(false);
    voiceButton.setText("Recognizer not present");
    }

FINAL NOTE: Voice Recognition will not work on a virtual emulator because they can't access the mic on your computer. The voice recognition will only work with an internet connection.

This is approx. what your final code should look like in your java.

package com.example.com.tutorialthread;

import java.util.ArrayList;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.speech.RecognizerIntent;
import android.support.v4.app.NavUtils;

public class main extends Activity implements OnClickListener {

public ListView mList;
public Button speakButton;

public static final int VOICE_RECOGNITION_REQUEST_CODE = 1234;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

speakButton = (Button) findViewById(R.id.btn_speak);
speakButton.setOnClickListener(this);

voiceinputbuttons();
}

public void informationMenu() {
startActivity(new Intent("android.intent.action.INFOSCREEN"));
}

public void voiceinputbuttons() {
speakButton = (Button) findViewById(R.id.btn_speak);
mList = (ListView) findViewById(R.id.list);
}

public void startVoiceRecognitionActivity() {
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL,
RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
intent.putExtra(RecognizerIntent.EXTRA_PROMPT,
"Speech recognition demo");
startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE);
}

public void onClick(View v) {
// TODO Auto-generated method stub
startVoiceRecognitionActivity();
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

if (requestCode == VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) {
// Fill the list view with the strings the recognizer thought it
// could have heard
ArrayList matches = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
mList.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, matches));
// matches is the result of voice input. It is a list of what the
// user possibly said.
// Using an if statement for the keyword you want to use allows the
// use of any activity if keywords match
// it is possible to set up multiple keywords to use the same
// activity so more than one word will allow the user
// to use the activity (makes it so the user doesn't have to
// memorize words from a list)
// to use an activity from the voice input information simply use
// the following format;
// if (matches.contains("keyword here") { startActivity(new
// Intent("name.of.manifest.ACTIVITY")

if (matches.contains("information")) {
informationMenu();
}
}
}

voice recognition for Android application

Why don't you consider about SpeechRecognizer. This class provides access to the speech recognition service. This service allows access to the speech recognizer. Do not instantiate this class directly, instead, call createSpeechRecognizer(Context). This class's methods must be invoked only from the main application thread.

I hope this will help you.

How to add Continues Speech Recognition in my Android Application?

I found the solution to reducing the time between speaking and receiving the results.

Request PARTIAL RESULTS as these are delivered before the FULL RESULTS.

I used these EXTRAS:-

mRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
mRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, Locale.getDefault().getLanguage().trim());
mRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, this.getPackageName());
mRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
mRecognizerIntent.putExtra(RecognizerIntent.EXTRA_PARTIAL_RESULTS, true);
mRecognizerIntent.putExtra(RecognizerIntent.EXTRA_SPEECH_INPUT_COMPLETE_SILENCE_LENGTH_MILLIS, 100);

mRecognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 3);

mSongSpeechRecognitionListener = new SongSpeechRecognitionListener(mRippleBackground, mFloatingActionButton);

mSpeechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
mSpeechRecognizer.setRecognitionListener(mSongSpeechRecognitionListener);

Then in partial results

public void onPartialResults(final Bundle partialResults) {
Log.i(LOG_TAG, "onPartialResults()");

final List<String> partialResultList = partialResults.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);

for (final String result : partialResultList) {

if (result.isEmpty()) {
} else {
mPartialResults++;
if (mPartialResults == mPartialResultsMAX) {
Log.i(LOG_TAG, "onPartialResults() EXECUTE");
mFloatingActionButton.setEnabled(true);
mAsyncTask.execute(result);
break;
}
}
}
}

I set mPartialResultsMAX to 2 as it seemed the first partial result was only ever a single word

When you receive PARTIAL RESULTS you may want to cancel the speech recogniser.



Related Topics



Leave a reply



Submit