Android program that Streams MIC directly to Speaker of Phone - android

I am writing a Android program that Streams MIC directly to Speaker of Phone.The code works but UI hangs and app hangs.But Still audio transfer is working even if the app hangs.Where is the error..?
RecordBufferSize=AudioRecord.getMinBufferSize(sampleRateInHz,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT);
TrackBufferSize= AudioTrack.getMinBufferSize(sampleRateInHz,AudioFormat.CHANNEL_OUT_MONO,AudioFormat.ENCODING_PCM_16BIT);
am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
Record record = new Record();
record.run();
}
public class Record extends Thread
{
final short[] buffer = new short[RecordBufferSize];
short[] readBuffer = new short[TrackBufferSize];
public void run() {
isRecording = true;
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
AudioRecord arec = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRateInHz,AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,RecordBufferSize);
AudioTrack atrack = new AudioTrack(AudioManager.STREAM_MUSIC,sampleRateInHz,AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, TrackBufferSize, AudioTrack.MODE_STREAM);
//am.setRouting(AudioManager.MODE_NORMAL, AudioManager.ROUTE_EARPIECE, AudioManager.ROUTE_ALL);
atrack.setPlaybackRate(sampleRateInHz);
byte[] buffer = new byte[RecordBufferSize];
arec.startRecording();
atrack.play();
while(isRecording) {
AudioLenght=arec.read(buffer, 0, RecordBufferSize);
atrack.write(buffer, 0, AudioLenght);
}
arec.stop();
atrack.stop();
isRecording = false;
}
}
This is my code.

I tried this and got result.Try this
Java Code I used:-
package com.example.root.akuvo;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.PorterDuff;
import android.media.AudioAttributes;
import android.media.AudioDeviceInfo;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.media.audiofx.AcousticEchoCanceler;
import android.media.audiofx.AutomaticGainControl;
import android.media.audiofx.BassBoost;
import android.media.audiofx.NoiseSuppressor;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
public class MicToSpeakerActivity extends AppCompatActivity {
//Audio
private Button mOn;
private boolean isOn;
private boolean isRecording;
private AudioRecord record;
private AudioTrack player;
private AudioManager manager;
private int recordState, playerState;
private int minBuffer;
//Audio Settings
private final int source = MediaRecorder.AudioSource.CAMCORDER;
private final int channel_in = AudioFormat.CHANNEL_IN_MONO;
private final int channel_out = AudioFormat.CHANNEL_OUT_MONO;
private final int format = AudioFormat.ENCODING_PCM_16BIT;
private final static int REQUEST_ENABLE_BT = 1;
private boolean IS_HEADPHONE_AVAILBLE=false;
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mic_to_speaker);
//Reduce latancy
setVolumeControlStream(AudioManager.MODE_IN_COMMUNICATION);
mOn = (Button) findViewById(R.id.button);
isOn = false;
isRecording = false;
manager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
manager.setMode(AudioManager.MODE_IN_COMMUNICATION);
//Check for headset availability
AudioDeviceInfo[] audioDevices = manager.getDevices(AudioManager.GET_DEVICES_ALL);
for(AudioDeviceInfo deviceInfo : audioDevices) {
if (deviceInfo.getType() == AudioDeviceInfo.TYPE_WIRED_HEADPHONES || deviceInfo.getType() == AudioDeviceInfo.TYPE_WIRED_HEADSET || deviceInfo.getType() == AudioDeviceInfo.TYPE_USB_HEADSET) {
IS_HEADPHONE_AVAILBLE = true;
}
}
if (!IS_HEADPHONE_AVAILBLE){
// get delete_audio_dialog.xml view
LayoutInflater layoutInflater = LayoutInflater.from(MicToSpeakerActivity.this);
View promptView = layoutInflater.inflate(R.layout.insert_headphone_dialog, null);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MicToSpeakerActivity.this);
alertDialogBuilder.setView(promptView);
// setup a dialog window
alertDialogBuilder.setCancelable(false)
.setPositiveButton("Try Again", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
startActivity(new Intent(getIntent()));
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
startActivity(new Intent(MicToSpeakerActivity.this,MainActivity.class));
dialog.cancel();
}
});
// create an alert dialog
AlertDialog alert = alertDialogBuilder.create();
alert.show();
}
initAudio();
mOn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mOn.getBackground().setColorFilter(getResources().getColor(!isOn ? R.color.colorOn : R.color.colorOff), PorterDuff.Mode.SRC_ATOP);
isOn = !isOn;
if(isOn) {
(new Thread() {
#Override
public void run()
{
startAudio();
}
}).start();
} else {
endAudio();
}
}
});
}
public void initAudio() {
//Tests all sample rates before selecting one that works
int sample_rate = getSampleRate();
minBuffer = AudioRecord.getMinBufferSize(sample_rate, channel_in, format);
record = new AudioRecord(source, sample_rate, channel_in, format, minBuffer);
recordState = record.getState();
int id = record.getAudioSessionId();
Log.d("Record", "ID: " + id);
playerState = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
player = new AudioTrack(
new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA).setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build(),
new AudioFormat.Builder().setEncoding(format).setSampleRate(sample_rate).setChannelMask(channel_out).build(),
minBuffer,
AudioTrack.MODE_STREAM,
AudioManager.AUDIO_SESSION_ID_GENERATE);
playerState = player.getState();
// Formatting Audio
if(AcousticEchoCanceler.isAvailable()) {
AcousticEchoCanceler echo = AcousticEchoCanceler.create(id);
echo.setEnabled(true);
Log.d("Echo", "Off");
}
if(NoiseSuppressor.isAvailable()) {
NoiseSuppressor noise = NoiseSuppressor.create(id);
noise.setEnabled(true);
Log.d("Noise", "Off");
}
if(AutomaticGainControl.isAvailable()) {
AutomaticGainControl gain = AutomaticGainControl.create(id);
gain.setEnabled(false);
Log.d("Gain", "Off");
}
BassBoost base = new BassBoost(1, player.getAudioSessionId());
base.setStrength((short) 1000);
}
}
public void startAudio() {
int read = 0, write = 0;
if(recordState == AudioRecord.STATE_INITIALIZED && playerState == AudioTrack.STATE_INITIALIZED) {
record.startRecording();
player.play();
isRecording = true;
Log.d("Record", "Recording...");
}
while(isRecording) {
short[] audioData = new short[minBuffer];
if(record != null)
read = record.read(audioData, 0, minBuffer);
else
break;
Log.d("Record", "Read: " + read);
if(player != null)
write = player.write(audioData, 0, read);
else
break;
Log.d("Record", "Write: " + write);
}
}
public void endAudio() {
if(record != null) {
if(record.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING)
record.stop();
isRecording = false;
Log.d("Record", "Stopping...");
}
if(player != null) {
if(player.getPlayState() == AudioTrack.PLAYSTATE_PLAYING)
player.stop();
isRecording = false;
Log.d("Player", "Stopping...");
}
}
public int getSampleRate() {
//Find a sample rate that works with the device
for (int rate : new int[] {8000, 11025, 16000, 22050, 44100, 48000}) {
int buffer = AudioRecord.getMinBufferSize(rate, channel_in, format);
if (buffer > 0)
return rate;
}
return -1;
}
}
XML Code I Used :
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.root.akuvo.MicToSpeakerActivity">
<Button
android:id="#+id/button"
android:layout_width="104dp"
android:layout_height="102dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:background="#android:drawable/ic_lock_power_off"
android:backgroundTint="#color/colorOff"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.396" />
</android.support.constraint.ConstraintLayout>

Related

Android Realtime Signal not smooth using graphview library

Iam trying to plot realtime signal from arduino to my android tablet. I've using a potentiometer for testing purpose and ADC sampling rate is 256Hz.
My issue is that the graph plotted on the android app is not smooth. The serial communication is working properly but the plotting is not very good.It feels like the App is lagging and it lags further as the data gets plotted.
Below is the app image
app screenshot
package com.example.ecgauth;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import android.Manifest;
import android.app.Activity;
import android.bluetooth.BluetoothSocket;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
//import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import com.felhr.usbserial.UsbSerialDevice;
import com.felhr.usbserial.UsbSerialInterface;
import com.jjoe64.graphview.GraphView;
import com.jjoe64.graphview.GraphView.GraphViewData;
import com.jjoe64.graphview.GraphView.LegendAlign;
import com.jjoe64.graphview.GraphViewSeries;
import com.jjoe64.graphview.GraphViewSeries.GraphViewStyle;
import com.jjoe64.graphview.LineGraphView;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends Activity implements View.OnClickListener{
private static final String ACTION_USB_PERMISSION = "com.example.ecg.USB_PERMISSION";
TextView hr_value_text;
UsbDevice device;
UsbDeviceConnection connection;
UsbManager usbManager;
UsbSerialDevice serialPort;
PendingIntent pendingIntent;
// private Handler mHandler;
public static final int MESSAGE_FROM_SERIAL_PORT = 0;
final static int gMAX_BLOCKS = 32; //Maximum blocks
final static int gMAX_SAMPLES = 8; //'Maximum samples
final static int gMAX_CHANNELS = 4; //'Maximum channels
final static int gSampFreq = 256; //Sampling frequency
final static int gRawBufferSize = gMAX_BLOCKS * gMAX_SAMPLES ;
final static float swpfactor = 0;
final static int gSec =0;
int sample =0;
private static boolean acq1 = false;
static int block =0;
int g_intRawBuffer[][] = new int[gMAX_BLOCKS][gMAX_SAMPLES];
double g_sngDnOutBuf[] = new double[gMAX_SAMPLES ];
#Override
public void onBackPressed() {
// // TODO Auto-generated method stub
// if (Bluetooth.connectedThread != null) {
// Bluetooth.connectedThread.write("Q");}//Stop streaming
super.onBackPressed();
}
//toggle Button
static boolean Lock;//whether lock the x-axis to 0-5
static boolean AutoScrollX;//auto scroll to the last x value
static boolean Stream;//Start or stop streaming
int old_interval=0;
int new_interval=0;
int mean_interval=20;
//Button init
Button bXminus;
Button bXplus;
ToggleButton tbLock;
ToggleButton tbScroll;
ToggleButton tbStream;
boolean startthread = true;
//GraphView init
static LinearLayout GraphView;
static GraphView graphView;
static GraphViewSeries Series;
//graph value
private static double graph2LastXValue = 0;
private static int Xview=1023;
Button bConnect, bDisconnect;
private TextView connectionstatus;
public int control_a = 0;
public int TotalSample=0;
char chdata = 0;
int i =0;
String finaldata = "";
String rawdata = "";
byte highbyte=0;
int data = 0 ;
int plotdata = 0 ;
int databuff = 0;
public int[] buffer_bt = new int[768];
public int[] copy_buffer_bt = new int[768];
public int ind_bt = 0;
UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() { //Defining a Callback which triggers whenever data is read.
#Override
public void onReceivedData(byte[] arg0) {
// lowbyte = arg0;
// highbyte = arg0;
byte[] buffer = arg0;
for (int i = 0; i <= (buffer.length - 1); i++) {
if (buffer[i] != 13) {
if (buffer[i] == 10) {
finaldata = rawdata;
rawdata = "";
} else {
chdata = (char) buffer[i];
rawdata += chdata;
}
}
}
data = Integer.parseInt(finaldata);
mHandler.obtainMessage(MESSAGE_FROM_SERIAL_PORT, data).sendToTarget();
control_a = 1;
buffer_bt[databuff] = data;
// }
//lowbyte = buffer;
//highbyte = buffer;
databuff = databuff + 1;
if (databuff == 767){
databuff=0;
}
//
// for (int uu=0; uu<=767; uu++) {
// copy_buffer_bt[uu] = buffer_bt[uu];
// }
// databuff=0;
// ready_bt=1;
// threadon = true;
// }
}
};
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
requestWindowFeature(Window.FEATURE_NO_TITLE);//Hide title
this.getWindow().setFlags(WindowManager.LayoutParams.
FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);//Hide Status bar
setContentView(R.layout.activity_main);
//set background color
LinearLayout background = (LinearLayout)findViewById(R.id.bg);
background.setBackgroundColor(Color.BLACK);
// mHandler = new Handler();
//GraphView = (LinearLayout) findViewById(R.id.Graph);
usbManager = (UsbManager) getSystemService(this.USB_SERVICE);
connectionstatus = (TextView) findViewById(R.id.tvBluetooth);
bConnect = (Button)findViewById(R.id.bConnect);
bConnect.setOnClickListener(this);
bDisconnect = (Button)findViewById(R.id.bDisconnect);
bDisconnect.setOnClickListener(this);
//X-axis control button
bXminus = (Button)findViewById(R.id.bXminus);
bXminus.setOnClickListener(this);
bXplus = (Button)findViewById(R.id.bXplus);
bXplus.setOnClickListener(this);
//
tbLock = (ToggleButton)findViewById(R.id.tbLock);
tbLock.setOnClickListener(this);
tbScroll = (ToggleButton)findViewById(R.id.tbScroll);
tbScroll.setOnClickListener(this);
tbStream = (ToggleButton)findViewById(R.id.tbStream);
tbStream.setOnClickListener(this);
//init toggleButton
Lock=true;
AutoScrollX=true;
Stream=true;
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(broadcastReceiver, filter);
init();
}
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_USB_PERMISSION)) {
boolean granted =
intent.getExtras().getBoolean(UsbManager.EXTRA_PERMISSION_GRANTED);
if (granted) {
connection = usbManager.openDevice(device);
serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection);
if (serialPort != null) {
if (serialPort.open()) { //Set Serial Connection Parameters.
//setUiEnabled(true); //Enable Buttons in UI
serialPort.setBaudRate(57600);
serialPort.setDataBits(UsbSerialInterface.DATA_BITS_8);
serialPort.setStopBits(UsbSerialInterface.STOP_BITS_1);
serialPort.setParity(UsbSerialInterface.PARITY_NONE);
serialPort.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF);
serialPort.read(mCallback); //
//connectionstatus.setText("Connected");
tvAppend(connectionstatus, " Opened!\n");
} else {
Log.d("SERIAL", "PORT NOT OPEN");
}
} else {
Log.d("SERIAL", "PORT IS NULL");
}
} else {
Log.d("SERIAL", "PERM NOT GRANTED");
}
} else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
onConnect(bConnect);
} else if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
// onClickStop(buttonRestart);
}
}
};
public void onConnect(View view){
HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList();
if (!usbDevices.isEmpty()) {
boolean keep = true;
for (Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) {
device = entry.getValue();
int deviceVID = device.getVendorId();
if (deviceVID == 0x10C4)//Arduino Vendor ID//0x10C4 cp2102 VID
{
PendingIntent pi = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
usbManager.requestPermission(device, pi);
keep = false;
} else {
connection = null;
device = null;
}
if (!keep)
break;
}
}
}
private void tvAppend (TextView tv, CharSequence text){
connectionstatus.setText(" ");
final TextView ftv = tv;
final CharSequence ftext = text;
runOnUiThread(new Runnable() {
#Override
public void run() {
ftv.append(ftext);
}
});
}
void init(){
//Bluetooth.gethandler(mHandler);
//init graphview
GraphView = (LinearLayout) findViewById(R.id.Graph);
// init example series data-------------------
Series = new GraphViewSeries("Signal",
new GraphViewStyle(Color.YELLOW, 2),//color and thickness of the line
new GraphViewData[] {new GraphViewData(0, 0)});
graphView = new LineGraphView(
this // context
, "Electrocardiogram AUTH" // heading
);
graphView.setViewPort(0, Xview);
graphView.setScrollable(true);
graphView.setScalable(false);
graphView.setShowLegend(false);
//graphView.setLegendAlign(LegendAlign.BOTTOM);
graphView.setManualYAxis(true);
graphView.setManualYAxisBounds(2560, 0);
graphView.addSeries(Series); // data
GraphView.addView(graphView);
}
Handler mHandler = new Handler(){
#Override
public void handleMessage(#NonNull Message msg) {
super.handleMessage(msg);
switch (msg.what){
case MESSAGE_FROM_SERIAL_PORT:
plotdata = data;
g_intRawBuffer[block][TotalSample] = plotdata;
TotalSample = TotalSample+1;
if (TotalSample == 8) {
TotalSample = 0;
for (int sample = 0; sample <= (gMAX_SAMPLES - 1); sample++) {
g_sngDnOutBuf[sample] = g_intRawBuffer[block][sample];
}
for (int sample = 0; sample <= (gMAX_SAMPLES - 1); sample++) {
Series.appendData(new GraphViewData(graph2LastXValue, g_sngDnOutBuf[sample]), AutoScrollX);
if (graph2LastXValue >= Xview && Lock == true) {
Series.resetData(new GraphViewData[]{});
graph2LastXValue = 0;
}else
graph2LastXValue += 0.5;
if (Lock == true)
graphView.setViewPort(0, Xview);
else
graphView.setViewPort(graph2LastXValue - Xview, Xview);
//refresh
GraphView.removeView(graphView);
GraphView.addView(graphView);
}
}
}
}
};
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.bConnect:
HashMap<String, UsbDevice> usbDevices = usbManager.getDeviceList();
if (!usbDevices.isEmpty()) {
boolean keep = true;
for (Map.Entry<String, UsbDevice> entry : usbDevices.entrySet()) {
device = entry.getValue();
int deviceVID = device.getVendorId();
if (deviceVID == 0x2341)//Arduino Vendor 2341 ID//0x10C4 cp2102 VID
{
PendingIntent pi = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
usbManager.requestPermission(device, pi);
keep = false;
} else {
connection = null;
device = null;
}
if (!keep)
break;
}
}
break;
case R.id.bDisconnect:
serialPort.close();
tvAppend(connectionstatus, "Serial Connection Closed!\n");
break;
case R.id.bXminus:
if (Xview<30) Xview++;
break;
case R.id.bXplus:
if (Xview>1) Xview--;
break;
case R.id.tbLock:
if (tbLock.isChecked()){
Lock = true;
}else{
Lock = false;
}
break;
case R.id.tbScroll:
if (tbScroll.isChecked()){
AutoScrollX = true;
}else{
AutoScrollX = false;
}
break;
case R.id.tbStream:
if (tbStream.isChecked()){
serialPort.write("a".getBytes());
}else{
serialPort.write("z".getBytes());
control_a = 0;
}
break;
}
}
}

Not able to get audio from bluetooth mic

I want to get the audio from Bluetooth headset and play it on Bluetooth headset itself. I am able to do that on lollipop(5.1.1)(Samsung note 3 neo) but it is not working on android(7.0)(Redmi Note 4).
I am first creating an audio track and then start a new thread for reading audio from mic. First, it starts reading audio from phonemic. After clicking the Bluetooth button it starts Bluetooth SCO.
Can anyone help?
package surya.com.audiorecord;
import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Sample that demonstrates how to record from a Bluetooth HFP microphone using {#link AudioRecord}.
*/
public class BluetoothRecordActivity extends AppCompatActivity {
private static final String TAG = BluetoothRecordActivity.class.getCanonicalName();
private static final int SAMPLING_RATE_IN_HZ = 16000;
private static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO;
private static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
/**
* Factor by that the minimum buffer size is multiplied. The bigger the factor is the less
* likely it is that samples will be dropped, but more memory will be used. The minimum buffer
* size is determined by {#link AudioRecord#getMinBufferSize(int, int, int)} and depends on the
* recording settings.
*/
private static final int BUFFER_SIZE_FACTOR = 2;
/**
* Size of the buffer where the audio data is stored by Android
*/
private static final int BUFFER_SIZE = AudioRecord.getMinBufferSize(SAMPLING_RATE_IN_HZ,
CHANNEL_CONFIG, AUDIO_FORMAT) * BUFFER_SIZE_FACTOR;
/**
* Signals whether a recording is in progress (true) or not (false).
*/
private final AtomicBoolean recordingInProgress = new AtomicBoolean(false);
private AudioRecord recorder = null;
private AudioManager audioManager;
private Thread recordingThread = null;
private Button startButton;
private Button stopButton;
private Button bluetoothButton;
AudioTrack mAudioTrack;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bluetooth);
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
try {
outputBufferSize = AudioTrack.getMinBufferSize(16000,
AudioFormat.CHANNEL_IN_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 16000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, outputBufferSize, AudioTrack.MODE_STREAM);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mAudioTrack.setVolume(100);
}
mAudioTrack.play();
} catch (Exception e) {
e.printStackTrace();
}
startButton = (Button) findViewById(R.id.btnStart);
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startRecording();
}
});
stopButton = (Button) findViewById(R.id.btnStop);
stopButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
stopRecording();
}
});
bluetoothButton = (Button) findViewById(R.id.btnBluetooth);
bluetoothButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
activateBluetoothSco();
}
});
requestAudioPermissions();
}
int outputBufferSize;
#Override
protected void onResume() {
super.onResume();
ButtonEnableSetters();
registerReceiver(bluetoothStateReceiver, new IntentFilter(
AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED));
}
private void ButtonEnableSetters() {
runOnUiThread(new Runnable() {
#Override
public void run() {
bluetoothButton.setEnabled(calculateBluetoothButtonState());
startButton.setEnabled(calculateStartRecordButtonState());
stopButton.setEnabled(calculateStopRecordButtonState());
}
});
}
#Override
protected void onPause() {
super.onPause();
stopRecording();
unregisterReceiver(bluetoothStateReceiver);
}
private void startRecording() {
// Depending on the device one might has to change the AudioSource, e.g. to DEFAULT
// or VOICE_COMMUNICATION
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
SAMPLING_RATE_IN_HZ, CHANNEL_CONFIG, AUDIO_FORMAT, BUFFER_SIZE);
recorder.startRecording();
recordingInProgress.set(true);
try {
recordingThread = new Thread(new RecordingRunnable(), "Recording Thread");
recordingThread.start();
} catch (Exception e) {
e.printStackTrace();
}
ButtonEnableSetters();
}
private void stopRecording() {
if (null == recorder) {
return;
}
recordingInProgress.set(false);
recorder.stop();
recorder.release();
recorder = null;
recordingThread = null;
ButtonEnableSetters();
}
private void activateBluetoothSco() {
if (!audioManager.isBluetoothScoAvailableOffCall()) {
Log.e(TAG, "SCO ist not available, recording is not possible");
return;
}
if (!audioManager.isBluetoothScoOn()) {
audioManager.startBluetoothSco();
audioManager.setBluetoothScoOn(true);
}
}
private void bluetoothStateChanged(BluetoothState state) {
Log.i(TAG, "Bluetooth state changed to:" + state);
if (BluetoothState.UNAVAILABLE == state && recordingInProgress.get()) {
stopRecording();
}
ButtonEnableSetters();
}
private boolean calculateBluetoothButtonState() {
return !audioManager.isBluetoothScoOn();
}
private boolean calculateStartRecordButtonState() {
return audioManager.isBluetoothScoOn() && !recordingInProgress.get();
}
private boolean calculateStopRecordButtonState() {
return audioManager.isBluetoothScoOn() && recordingInProgress.get();
}
private class RecordingRunnable implements Runnable {
#Override
public void run() {
if (mAudioTrack != null) {
if (mAudioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
mAudioTrack.play();
} else {
mAudioTrack.stop();
mAudioTrack.flush();
mAudioTrack.play();
}
}
// final File file = new File(Environment.getExternalStorageDirectory(), "recording.pcm");
final ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE);
while (recordingInProgress.get()) {
int result = recorder.read(buffer, BUFFER_SIZE);
if (result 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay!
// recordAudio();
activateBluetoothSco();
startRecording();
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
Toast.makeText(this, "Permissions Denied to record audio", Toast.LENGTH_LONG).show();
}
return;
}
}
}
private final BroadcastReceiver bluetoothStateReceiver = new BroadcastReceiver() {
private BluetoothState bluetoothState = BluetoothState.UNAVAILABLE;
#Override
public void onReceive(Context context, Intent intent) {
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
switch (state) {
case AudioManager.SCO_AUDIO_STATE_CONNECTED:
Log.i(TAG, "Bluetooth HFP Headset is connected");
handleBluetoothStateChange(BluetoothState.AVAILABLE);
break;
case AudioManager.SCO_AUDIO_STATE_CONNECTING:
Log.i(TAG, "Bluetooth HFP Headset is connecting");
handleBluetoothStateChange(BluetoothState.UNAVAILABLE);
case AudioManager.SCO_AUDIO_STATE_DISCONNECTED:
Log.i(TAG, "Bluetooth HFP Headset is disconnected");
handleBluetoothStateChange(BluetoothState.UNAVAILABLE);
break;
case AudioManager.SCO_AUDIO_STATE_ERROR:
Log.i(TAG, "Bluetooth HFP Headset is in error state");
handleBluetoothStateChange(BluetoothState.UNAVAILABLE);
break;
}
}
private void handleBluetoothStateChange(BluetoothState state) {
if (bluetoothState == state) {
return;
}
bluetoothState = state;
bluetoothStateChanged(state);
}
};
}
This is the project source code
https://bitbucket.org/surya945/audiorecord
welcome to stackoverflow
I think your issue related to
TargetSdkVersion in build.gardle(module:app)
check this

MediaPlayer doesn't continue showing subtitle (.SRT) after pause or seekTo

I'm trying to implement subtitles to videoview. I've used this example project :
package com.example.media.timedtexttest;
import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;
import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnTimedTextListener;
import android.media.MediaPlayer.TrackInfo;
import android.media.TimedText;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends Activity implements OnTimedTextListener {
private static final String TAG = "TimedTextTest";
private TextView txtDisplay;
private static Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtDisplay = (TextView) findViewById(R.id.txtDisplay);
MediaPlayer player = MediaPlayer.create(this, R.raw.video);
try {
player.addTimedTextSource(getSubtitleFile(R.raw.sub),
MediaPlayer.MEDIA_MIMETYPE_TEXT_SUBRIP);
int textTrackIndex = findTrackIndexFor(
TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT, player.getTrackInfo());
if (textTrackIndex >= 0) {
player.selectTrack(textTrackIndex);
} else {
Log.w(TAG, "Cannot find text track!");
}
player.setOnTimedTextListener(this);
player.start();
} catch (Exception e) {
e.printStackTrace();
}
}
private int findTrackIndexFor(int mediaTrackType, TrackInfo[] trackInfo) {
int index = -1;
for (int i = 0; i < trackInfo.length; i++) {
if (trackInfo[i].getTrackType() == mediaTrackType) {
return i;
}
}
return index;
}
private String getSubtitleFile(int resId) {
String fileName = getResources().getResourceEntryName(resId);
File subtitleFile = getFileStreamPath(fileName);
if (subtitleFile.exists()) {
Log.d(TAG, "Subtitle already exists");
return subtitleFile.getAbsolutePath();
}
Log.d(TAG, "Subtitle does not exists, copy it from res/raw");
// Copy the file from the res/raw folder to your app folder on the
// device
InputStream inputStream = null;
OutputStream outputStream = null;
try {
inputStream = getResources().openRawResource(resId);
outputStream = new FileOutputStream(subtitleFile, false);
copyFile(inputStream, outputStream);
return subtitleFile.getAbsolutePath();
} catch (Exception e) {
e.printStackTrace();
} finally {
closeStreams(inputStream, outputStream);
}
return "";
}
private void copyFile(InputStream inputStream, OutputStream outputStream)
throws IOException {
final int BUFFER_SIZE = 1024;
byte[] buffer = new byte[BUFFER_SIZE];
int length = -1;
while ((length = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, length);
}
}
// A handy method I use to close all the streams
private void closeStreams(Closeable... closeables) {
if (closeables != null) {
for (Closeable stream : closeables) {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
#Override
public void onTimedText(final MediaPlayer mp, final TimedText text) {
if (text != null) {
handler.post(new Runnable() {
#Override
public void run() {
int seconds = mp.getCurrentPosition() / 1000;
txtDisplay.setText("[" + secondsToDuration(seconds) + "] "
+ text.getText());
}
});
}
}
// To display the seconds in the duration format 00:00:00
public String secondsToDuration(int seconds) {
return String.format("%02d:%02d:%02d", seconds / 3600,
(seconds % 3600) / 60, (seconds % 60), Locale.US);
}
}
and created exactly the same implementation and it somehow works, but if i stop video and continue subtitle doesn't continue or if i seek video to some time subtitle doesn't continue too.
What i have tried:
Every time before player.start() i set player.selectTrack(textTrackIndex);
I've tried to reregister listener when i'm doing player.start(); player.setOnTimedTextListener(this);
Please help i've spent 4 days on subtitle features... If you have some project example or snippet it would be nice :)
we have the same problem and we must implements OnSeekCompleteListener even if you nothing to do into override method
it's our code:
#Override
public void onSeekComplete(MediaPlayer mediaPlayer) {
}
and it work !!!
I hope that help you

Arduino ADK Mega is not connecting with any of my Android devices! OutputStream is null?

I have closely followed this tutorial: http://assets.en.oreilly.com/1/event/68/Building%20Android%20Accessories%20using%20the%20Open%20Accessory%20Development%20Kit%20and%20Arduino%20Presentation%201.pdf
However, I have made a few modifications so that I send ASCII values each time my text is updated. I still am unable to connect my Android devices (yes, I have multiple, from versions 2.2.3 to 2.2.7). I keep receiving the error in the onscreen Log that the Outputstreams are null. Any help would be greatly appreciated!
OpenAccessoryTest.java
package org.simonmonk.duinodroid;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import com.android.future.usb.UsbAccessory;
import com.android.future.usb.UsbManager;
public class OpenAccessoryTest extends Activity implements Runnable {
private EditText mByteField;
private EditText mResponseField;
private Button mSendButton;
private static final String ACTION_USB_PERMISSION = "com.google.android.DemoKit.action.USB_PERMISSION";
private UsbManager mUsbManager;
private PendingIntent mPermissionIntent;
private boolean mPermissionRequestPending;
private UsbAccessory mAccessory;
private ParcelFileDescriptor mFileDescriptor;
private FileInputStream mInputStream;
private FileOutputStream mOutputStream;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mByteField = (EditText) findViewById(R.id.streamingTextView1);
mResponseField = (EditText) findViewById(R.id.arduinoresponse);
mSendButton = (Button) findViewById(R.id.sendButton);
// String valueStr = mByteField.getText().toString();
mSendButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
sendMessageToArduino();
}
});
setupAccessory();
}
#Override
public Object onRetainNonConfigurationInstance() {
if (mAccessory != null) {
return mAccessory;
} else {
return super.onRetainNonConfigurationInstance();
}
}
#Override
public void onResume() {
log("Resuming");
super.onResume();
if (mInputStream != null && mOutputStream != null) {
log("Resuming: streams were not null");
return;
}
log("Resuming: streams were null");
UsbAccessory[] accessories = mUsbManager.getAccessoryList();
UsbAccessory accessory = (accessories == null ? null : accessories[0]);
if (accessory != null) {
if (mUsbManager.hasPermission(accessory)) {
openAccessory(accessory);
} else {
synchronized (mUsbReceiver) {
if (!mPermissionRequestPending) {
mUsbManager.requestPermission(accessory,
mPermissionIntent);
mPermissionRequestPending = true;
}
}
}
} else {
log("onResume:mAccessory is null");
}
}
#Override
public void onPause() {
log("Pausing");
super.onPause();
}
#Override
public void onDestroy() {
log("Destroying");
unregisterReceiver(mUsbReceiver);
super.onDestroy();
}
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
ValueMsg t = (ValueMsg) msg.obj;
log("Arduino sent: " + t.getFlag() + " " + t.getReading());
}
};
private void log(String string) {
String contents = mResponseField.getText().toString();
mResponseField.setText(contents + "\n" + string);
}
private void setupAccessory() {
log("In setupAccessory");
mUsbManager = UsbManager.getInstance(this);
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
registerReceiver(mUsbReceiver, filter);
if (getLastNonConfigurationInstance() != null) {
mAccessory = (UsbAccessory) getLastNonConfigurationInstance();
openAccessory(mAccessory);
}
}
private void openAccessory(UsbAccessory accessory) {
log("In openAccessory");
mFileDescriptor = mUsbManager.openAccessory(accessory);
if (mFileDescriptor != null) {
mAccessory = accessory;
FileDescriptor fd = mFileDescriptor.getFileDescriptor();
mInputStream = new FileInputStream(fd);
mOutputStream = new FileOutputStream(fd);
Thread thread = new Thread(null, this, "OpenAccessoryTest");
thread.start();
alert("openAccessory: Accessory openned");
log("Attached");
} else {
log("openAccessory: accessory open failed");
}
}
private void closeAccessory() {
log("In closeAccessory");
try {
if (mFileDescriptor != null) {
mFileDescriptor.close();
}
} catch (IOException e) {
} finally {
mFileDescriptor = null;
mAccessory = null;
}
}
private int composeInt(byte hi, byte lo) {
int val = hi & 0xff;
val *= 256;
val += lo & 0xff;
return val;
}
#Override
public void run() {
int ret = 0;
byte[] buffer = new byte[16384];
int i;
while (true) { // keep reading messages forever. There are prob lots of
// messages in the buffer, each 4 bytes
try {
ret = mInputStream.read(buffer);
} catch (IOException e) {
break;
}
i = 0;
while (i < ret) {
int len = ret - i;
if (len >= 2) {
Message m = Message.obtain(mHandler);
int value = composeInt(buffer[i], buffer[i + 1]);
m.obj = new ValueMsg('a', value);
mHandler.sendMessage(m);
}
i += 2;
}
}
}
public void sendMessageToArduino() {
String valueStr = mByteField.getText().toString();
try {
for (int x = 0; x < valueStr.length(); x++) {
sendCommand((byte) valueStr.charAt(x));
log("Sending to Arduino: " + (byte) valueStr.charAt(x));
}
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
alert("The Byte should be a number between 0 and 255");
}
}
public void sendCommand(byte value) {
log("Sent: " + value);
byte[] buffer = new byte[1];
buffer[0] = value;
if (mOutputStream != null) {
try {
mOutputStream.write(buffer);
} catch (IOException e) {
log("Send failed: " + e.getMessage());
}
} else {
log("Send failed: mOutStream was null");
}
}
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
UsbAccessory accessory = UsbManager.getAccessory(intent);
if (intent.getBooleanExtra(
UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
openAccessory(accessory);
} else {
log("USB permission denied");
}
}
} else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
UsbAccessory accessory = UsbManager.getAccessory(intent);
if (accessory != null && accessory.equals(mAccessory)) {
log("Detached");
closeAccessory();
}
}
}
};
public void alert(String message) {
AlertDialog alertDialog = new AlertDialog.Builder(this).create();
alertDialog.setTitle("Alert");
alertDialog.setMessage(message);
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
return;
}
});
alertDialog.show();
}
}`
StreamingTextView.java
package org.simonmonk.duinodroid;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.EditText;
public class StreamingTextView extends EditText {
public StreamingTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public StreamingTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public StreamingTextView(Context context) {
super(context);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
((OpenAccessoryTest) super.getContext()).sendCommand(toAscii(event));
return super.onKeyDown(keyCode, event);
}
private byte toAscii(KeyEvent event) {
byte ch = (byte) event.getUnicodeChar();
if (ch == 0) {
switch(event.getKeyCode()){
case KeyEvent.KEYCODE_DEL:
ch = 8;
break;
case KeyEvent.KEYCODE_ENTER:
ch = 10;
break;
}
}
return ch;
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Byte 0 (decimal)" />
<org.simonmonk.duinodroid.StreamingTextView
android:id="#+id/streamingTextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="StreamingTextView" >
<requestFocus />
</org.simonmonk.duinodroid.StreamingTextView>
<Button
android:id="#+id/sendButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Send to Arduino" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Log" />
<EditText
android:id="#+id/arduinoresponse"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:editable="false"
android:lines="10" />
</LinearLayout>
android version must be > to 2.2 . That start working with Google api version 2.3.4 I think

I want to check the loudness of voice in android

I am developing an application where I have to detect the loudness of voice. Means some on shouts on the mobile and it will show the loudness level on the screen.
Which API can be used for this?
Look at http://developer.android.com/reference/android/media/AudioRecord.html
When you read the buffer the byte values will represent the amplitude. The higher the byte value the louder the sound.
Here is a scaled-down version of something I used in an app I wrote a while back:
Add this to your mainifest.xml
<uses-permission android:name="android.permission.RECORD_AUDIO" />
soundlevel.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ToggleButton
android:id="#+id/togglebutton_record"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ToggleButton" />
<ProgressBar
android:id="#+id/progressbar_level"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
SoundLevel.java
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.widget.CompoundButton;
import android.widget.ProgressBar;
import android.widget.ToggleButton;
public class SoundLevel extends Activity {
private static final int sampleRate = 11025;
private static final int bufferSizeFactor = 10;
private AudioRecord audio;
private int bufferSize;
private ProgressBar level;
private Handler handler = new Handler();
private int lastLevel = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.soundlevel);
level = (ProgressBar) findViewById(R.id.progressbar_level);
level.setMax(32676);
ToggleButton record = (ToggleButton) findViewById(R.id.togglebutton_record);
record.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if (isChecked) {
bufferSize = AudioRecord.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT) * bufferSizeFactor;
audio = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
audio.startRecording();
Thread thread = new Thread(new Runnable() {
public void run() {
readAudioBuffer();
}
});
thread.setPriority(Thread.currentThread().getThreadGroup().getMaxPriority());
thread.start();
handler.removeCallbacks(update);
handler.postDelayed(update, 25);
} else if (audio != null) {
audio.stop();
audio.release();
audio = null;
handler.removeCallbacks(update);
}
}
});
}
private void readAudioBuffer() {
try {
short[] buffer = new short[bufferSize];
int bufferReadResult;
do {
bufferReadResult = audio.read(buffer, 0, bufferSize);
for (int i = 0; i < bufferReadResult; i++){
if (buffer[i] > lastLevel) {
lastLevel = buffer[i];
}
}
} while (bufferReadResult > 0 && audio.getRecordingState() == AudioRecord.RECORDSTATE_RECORDING);
if (audio != null) {
audio.release();
audio = null;
handler.removeCallbacks(update);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private Runnable update = new Runnable() {
public void run() {
SoundLevel.this.level.setProgress(lastLevel);
lastLevel *= .5;
handler.postAtTime(this, SystemClock.uptimeMillis() + 500);
}
};
}

Categories

Resources