How do I get files synchronized from Firebase in Android? - android

I am trying to make an application that works with audio files. I have to import and merge audio files from Firebase in a part of the application.
Here is the code block from merge operations;
protected void combine() {
String randomFileName = String.valueOf(System.currentTimeMillis());
lastRecordedFilePath = Environment.getExternalStorageDirectory() + "/MueasycoCombinedAudios/" + randomFileName + ".wav";
lastRecordedFileName = randomFileName + ".wav";
File folder = new File(Environment.getExternalStorageDirectory() + "/MueasycoCombinedAudios");
File folder1 = new File(Environment.getExternalStorageDirectory() + "/MueasycoDownloadedAudios");
if (!folder.exists()) {
folder.mkdirs();
}
if (!folder1.exists()) {
folder1.mkdirs();
}
int counter = 0;
int counter1 = 0;
int counter2 = 0;
try {
DataOutputStream amplifyOutputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(Environment.getExternalStorageDirectory() + "/MueasycoCombinedAudios/" + randomFileName + ".wav")));
DataInputStream[] mergeFilesStream = new DataInputStream[trackList.size()];
long[] sizes = new long[trackList.size()];
for (Iterator<TrackModel> i = trackList.iterator(); i.hasNext(); ) {
TrackModel item = i.next();
final StorageReference fileReference = mStorageRef.child("AudioRecords/" + item.fileName);
final File file = new File(Environment.getExternalStorageDirectory() + "/MueasycoDownloadedAudios/" + item.fileName);
fileReference.getFile(file).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Log.e("firebase ", ";local tem file created created " + file.toString());
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle any errors
}
});
sizes[counter] = (file.length() - 44) / 2;
counter++;
}
for (Iterator<TrackModel> i = trackList.iterator(); i.hasNext(); ) {
TrackModel item = i.next();
while (true) {
File control = new File(Environment.getExternalStorageDirectory() + "/MueasycoDownloadedAudios/" + item.fileName);
if (control.exists()) {
mergeFilesStream[counter1] = new DataInputStream(new BufferedInputStream(new FileInputStream(Environment.getExternalStorageDirectory() + "/MueasycoDownloadedAudios/" + item.fileName)));
break;
} else {
Log.e("mueasyco ", "Dosya yok" + control.getName());
}
}
if (counter1 == trackList.size() - 1) {
mergeFilesStream[counter1].skip(24);
byte[] sampleRt = new byte[4];
mergeFilesStream[counter1].read(sampleRt);
ByteBuffer bbInt = ByteBuffer.wrap(sampleRt).order(ByteOrder.LITTLE_ENDIAN);
RECORDER_SAMPLERATE = bbInt.getInt();
mergeFilesStream[counter1].skip(16);
} else {
mergeFilesStream[counter1].skip(44);
}
counter1++;
}
for (Iterator<TrackModel> i = trackList.iterator(); i.hasNext(); ) {
TrackModel item = i.next();
final StorageReference fileReference = mStorageRef.child("AudioRecords/" + item.fileName);
for (int a = 0; a < (int) sizes[counter2]; counter2++) {
byte[] dataBytes = new byte[2];
try {
dataBytes[0] = mergeFilesStream[counter2].readByte();
dataBytes[1] = mergeFilesStream[counter2].readByte();
} catch (EOFException e) {
amplifyOutputStream.close();
}
short dataInShort = ByteBuffer.wrap(dataBytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
float dataInFloat = (float) dataInShort / 37268.0f;
short outputSample = (short) (dataInFloat * 37268.0f);
byte[] dataFin = new byte[2];
dataFin[0] = (byte) (outputSample & 0xff);
dataFin[1] = (byte) ((outputSample >> 8) & 0xff);
amplifyOutputStream.write(dataFin, 0, 2);
}
counter2++;
}
amplifyOutputStream.close();
for (int a = 0; a < trackList.size(); a++) {
mergeFilesStream[a].close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
long size = 0;
try {
FileInputStream fileSize = new FileInputStream(Environment.getExternalStorageDirectory() + "/MueasycoCombinedAudios/" + randomFileName + ".wav");
size = fileSize.getChannel().size();
fileSize.close();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
final int RECORDER_BPP = 16;
long datasize = size + 36;
long byteRate = (RECORDER_BPP * RECORDER_SAMPLERATE) / 8;
long longSampleRate = RECORDER_SAMPLERATE;
byte[] header = new byte[44];
header[0] = 'R'; // RIFF/WAVE header
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
header[4] = (byte) (datasize & 0xff);
header[5] = (byte) ((datasize >> 8) & 0xff);
header[6] = (byte) ((datasize >> 16) & 0xff);
header[7] = (byte) ((datasize >> 24) & 0xff);
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
header[12] = 'f'; // 'fmt ' chunk
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 16; // 4 bytes: size of 'fmt ' chunk
header[17] = 0;
header[18] = 0;
header[19] = 0;
header[20] = 1; // format = 1
header[21] = 0;
header[22] = (byte) 1;
header[23] = 0;
header[24] = (byte) (longSampleRate & 0xff);
header[25] = (byte) ((longSampleRate >> 8) & 0xff);
header[26] = (byte) ((longSampleRate >> 16) & 0xff);
header[27] = (byte) ((longSampleRate >> 24) & 0xff);
header[28] = (byte) (byteRate & 0xff);
header[29] = (byte) ((byteRate >> 8) & 0xff);
header[30] = (byte) ((byteRate >> 16) & 0xff);
header[31] = (byte) ((byteRate >> 24) & 0xff);
header[32] = (byte) ((RECORDER_BPP) / 8); // block align
header[33] = 0;
header[34] = RECORDER_BPP; // bits per sample
header[35] = 0;
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
header[40] = (byte) (size & 0xff);
header[41] = (byte) ((size >> 8) & 0xff);
header[42] = (byte) ((size >> 16) & 0xff);
header[43] = (byte) ((size >> 24) & 0xff);
try {
RandomAccessFile rFile = new RandomAccessFile(Environment.getExternalStorageDirectory() + "/MueasycoCombinedAudios/" + randomFileName + ".wav", "rw");
rFile.seek(0);
rFile.write(header);
rFile.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
uploadFile();
}
The problem is that the code that downloads firebase files continues to work. As you can see, I tried to repair this with an infinite loop, but the Firebase creates files when it did not load properly, so the solution was not successful.
fileReference.getFile(file).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Log.e("firebase ", ";local tem file created created " + file.toString());
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle any errors
}
});
I tried to write the array I created for joining in the onSuccess event but in this case I will not be able to fully prepare the arrays to use.
I am using this post to merge.

There's a bit much going on in your code, so I'm going to focus on one part of it only.
The problem is caused by the fact that Firebase downloads the files from the server asynchronously. And while the file is downloading, instead of blocking your code, it continues to run your code. So if you don't take this asynchronous behavior into account, you'll be merging the files before their data has actually been downloaded.
The easiest way to see what's happening is with a few log statements:
Log.i("Firebase", "Starting downloading from storage");
fileReference.getFile(file).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
Log.i("Firebase", "Download done");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Log.e("Firebase", "Download failed: "+exception.toString());
}
});
Log.i("Firebase", "After starting download from storage");
If you run this code you'll get:
Starting downloading from storage
After starting download from storage
Download done
This is probably not what you expected, but perfectly explains why your merging code fails: the data that it wants to merge is not available yet.
The solution is to change the order in which you invoke the code. After the download of a file is completed, check if that was the final file. If so, start the merge:
for (Iterator<TrackModel> i = trackList.iterator(); i.hasNext(); ) {
TrackModel item = i.next();
final StorageReference fileReference = mStorageRef.child("AudioRecords/" + item.fileName);
final File file = new File(Environment.getExternalStorageDirectory() + "/MueasycoDownloadedAudios/" + item.fileName);
fileReference.getFile(file).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
#Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
sizes[counter] = (file.length() - 44) / 2;
counter++;
if (counter == trackList.size()) {
Log.i("Firebase", "Downloads completed");
// TODO: merge the downloaded files here
}
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
Log.e("Firebase", "Download failed: "+exception.toString());
}
});
}

Related

write .wav empty after receive data from wear

I'm working on a android wear app. This app records local audio from microphone of smartwatch and sends it to the handle device. The handle device receives data and writes a .wav file. The file is created, but when I listen the file is empty , I can listen only silence.
this is the wear code:
public void replyAudioByByte(final byte data[]) {
final String path = "/start_activity";
final Byte[] text= new Byte[1024];
GoogleApiClient client = new GoogleApiClient.Builder(getApplicationContext())
.addApi(Wearable.API)
.build();
new Thread(new Runnable() {
#Override
public void run() {
NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(mApiClient).await();
for (Node node : nodes.getNodes()) {
MessageApi.SendMessageResult result = Wearable.MessageApi.sendMessage(
mApiClient, node.getId(),AUDIO_RECORDER, data).await();
if (result.getStatus().isSuccess()) {
Log.d("sendMessage","Message send!!");
for (int j=0; j<data.length; j++ ){
Log.v("Mobile", "Message: {" + data[j] + "} sent to: " + node.getDisplayName());
}
} else {
// Log an error
Log.v("Mobile", "ERROR: failed to send Message");
}
}
}
}).start();
client.disconnect();
Log.d("MOBILE", "send message end");
}
public void startRecordingAudio() {
recorder = findAudioRecord();
Log.d("recorder:","recorder="+recorder.toString());
CountDownTimer countDowntimer = new CountDownTimer(8000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
try {
//Toast.makeText(getBaseContext(), "Stop recording Automatically ", Toast.LENGTH_LONG).show();
Log.d("wear", "stopRecorder=" + System.currentTimeMillis());
recorder.stop();
Log.d("formato registrazione","recorderformat="+recorder.getAudioFormat()+"-----rate=");
Log.d("formato registrazione","recordersamplerate=" +recorder.getSampleRate());
isRecording=false;
replyAudioByByte(data);
for (int j=0; j< data.length;j++){
Log.d("watch audio registrato", "data[]="+data[j]);
}
Log.d("wear", "recorder.stop ok!");
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e("wear", "recorder.stop catch");
e.printStackTrace();
}
}
};
recorder.startRecording();
countDowntimer.start();
Log.d("wear", "startRecorder=" + System.currentTimeMillis());
isRecording = true;
recordingThread = new Thread(new Runnable() {
public void run() {
while (isRecording ) {
recorder.read(data, 0, bufferSize);
Log.d("WEAR","recorder.read="+recorder.read(data, 0, bufferSize));
}
recorder.stop();
recorder.release();
for (int i = 0; i < bufferSize; i++) {
Log.d("startrecording", "data=" + data[i]);
}
}
}, "AudioRecorder Thread");
recordingThread.start();
int a= recorder.getSampleRate();
Log.d("formato registrazione","recorderformat="+recorder.getAudioFormat()+"-----rate="+a);
Log.d("formato registrazione","recordersamplerate=" +recorder.getSampleRate());
}
public AudioRecord findAudioRecord() {
/** The settings that i must use are not the same for every device, so i try if they work */
for (int rate : mSampleRates) {
for (short audioFormat : audioF) {
for (short channelConfig : channelC) {
try {
//Log.d("Check", "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: " + channelConfig);
int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);
if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {
//It checks if it can instantiate the audiorecorder without problems
AudioRecord recorder = new AudioRecord(AudioSource.MIC, rate, channelConfig, audioFormat, bufferSize + 2000);
Log.d("AudioRecorder data","AudioSource.Default="+ AudioSource.MIC);
Log.d("AudioRecorder data","Rate="+ rate);
Log.d("AudioRecorder data","Channel.config="+ channelConfig);
Log.d("AudioRecorder data","AudioFormat= "+audioFormat);
bufferSize=bufferSize+2000;
Log.d("AudioRecorder data","buffersize="+ bufferSize );
if (recorder.getState() == AudioRecord.STATE_INITIALIZED)
Log.d("audiorec","rate="+rate);
return recorder;
}
} catch (Exception e) {
Log.e("Check", rate + "Exception, keep trying.", e);
}
}
}
}
return null;
}
this is the handle code:
public Void doInBackground(byte [] dataToWrite) {
Log.d("doInBackground","entrato");
byte data[] = new byte[bufferSize];
String tempfilename = "";
FileOutputStream os = null;
//if(allowRecorder){
tempfilename = getTempFilename();
Log.d("doInBackground","getTempFilename=" +tempfilename.toString());
try {
os = new FileOutputStream(tempfilename);
Log.d("doInBackground","os new ok" );
} catch (FileNotFoundException e) {
e.printStackTrace();
}
dbData = new ArrayList<Double>();
Log.d("doInBackGround", "dateToWrite.length=" + dataToWrite.length);
for (int j = 0; j < dataToWrite.length; j++) {
try {
os.write(dataToWrite);
Log.d("os,write", "dataToWrite");
} catch (IOException e) {
e.printStackTrace();
}
}
if(data[data.length-1]!=0){
double Db = 20 * Math.log10(Math.abs((data[data.length-1]/51805.5336) / 0.00002));
dbData.add(Db);
}
try {
os.close();
Log.d("os.close", "dataToWrite");
copyWaveFile(tempfilename,getFilename());
deleteTempFile();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private void copyWaveFile(String inFilename,String outFilename){
FileInputStream in = null;
FileOutputStream out = null;
long totalAudioLen = 0;
long totalDataLen = 0;
long longSampleRate = 8000;
System.out.println("SAMPLE RATE = "+longSampleRate);
int channels = 12;
audioFormat = 16;
long byteRate = audioFormat * longSampleRate * channels/8;
byte[] data = new byte[bufferSize];
try {
in = new FileInputStream(inFilename);
out = new FileOutputStream(outFilename);
totalAudioLen = in.getChannel().size();
totalDataLen = totalAudioLen + 36;
Log.d("RecorderRead","totalAudioLen=" +totalAudioLen);
Log.d("RecorderRead","totalDatalen=" +totalDataLen);
System.out.println("Temp File size: " + totalDataLen);
Log.d("AudioRecorder data","AudioSource.Default="+ AudioSource.DEFAULT);
Log.d("AudioRecorder data","Rate="+ longSampleRate);
Log.d("AudioRecorder data","Channel.config="+ channels);
Log.d("AudioRecorder data","AudioFormat= "+audioFormat);
//bufferSize=bufferSize+2000;
Log.d("AudioRecorder data","buffersize="+ bufferSize );
if(totalDataLen != 36){
writeWaveFileHeader(out, totalAudioLen, totalDataLen,
longSampleRate, channels, byteRate);
Log.d("writeWAVEFILE", "chiamato");
while(in.read(data) != -1){
out.write(data);
}
System.out.println("Wav File size: " + out.getChannel().size());
}
else{
System.out.println("Non creo il file .wav");
}
in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void writeWaveFileHeader(
FileOutputStream out, long totalAudioLen,
long totalDataLen, long longSampleRate, int channels,
long byteRate) throws IOException {
byte[] header = new byte[44];
header[0] = 'R'; // RIFF/WAVE header
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
header[4] = (byte) (totalDataLen & 0xff);
header[5] = (byte) ((totalDataLen >> 8) & 0xff);
header[6] = (byte) ((totalDataLen >> 16) & 0xff);
header[7] = (byte) ((totalDataLen >> 24) & 0xff);
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
header[12] = 'f'; // 'fmt ' chunk
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 16; // 4 bytes: size of 'fmt ' chunk
header[17] = 0;
header[18] = 0;
header[19] = 0;
header[20] = 1; // format = 1
header[21] = 0;
header[22] = (byte) channels;
header[23] = 0;
header[24] = (byte) (longSampleRate & 0xff);
header[25] = (byte) ((longSampleRate >> 8) & 0xff);
header[26] = (byte) ((longSampleRate >> 16) & 0xff);
header[27] = (byte) ((longSampleRate >> 24) & 0xff);
header[28] = (byte) (byteRate & 0xff);
header[29] = (byte) ((byteRate >> 8) & 0xff);
header[30] = (byte) ((byteRate >> 16) & 0xff);
header[31] = (byte) ((byteRate >> 24) & 0xff);
header[32] = (byte) (2 * 16 / 8); // block align
header[33] = 0;
header[34] = (byte) audioFormat; // bits per sample
header[35] = 0;
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
header[40] = (byte) (totalAudioLen & 0xff);
header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
out.write(header, 0, 44);
}
in wear mainifest I have
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
in handle manifest I have
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
when I run app in the logfile of wear app I have this error:
AudioRecord-JNI: Error -4 during AudioRecord native read
What should I do to solve it?
someone can help me? What's wrong? every type of help is appreciated, code or tutorial.
Thanks in advance
You need to set the audio encoder to be used for recording.
void setAudioEncoder (int audio_encoder)
If this method is not called, the output file will not contain an audio track. Call this after setOutputFormat() but before prepare().
Try to follow listed steps below:
Create a new instance of android.media.MediaRecorder.
Set the audio source using MediaRecorder.setAudioSource(). You will probably want to use MediaRecorder.AudioSource.MIC.
Set output file format using MediaRecorder.setOutputFormat().
Set output file name using MediaRecorder.setOutputFile().
Set the audio encoder using MediaRecorder.setAudioEncoder().
Call MediaRecorder.prepare() on the MediaRecorder instance.
To start audio capture, call MediaRecorder.start().
To stop audio capture, call MediaRecorder.stop().
When you are done with the MediaRecorder instance, call MediaRecorder.release() on it. Calling MediaRecorder.release() is always recommended to free the resource immediately.
Here's a sample code how to record audio and to play the recorded audio: https://developer.android.com/guide/topics/media/audio-capture.html#example

Audio Recording not smooth and continuous

Please help me to figure out that i am recording sound .
I want to record via service which produces jerks in sound while recording.I have buttons in activity from where i Start Recording and Stop Recording.
The Same code work absolutely fine if i do in activity.
The Service i am providing below
public class ServiceMusic extends Service {
private static String LOG_TAG = "BoundService";
private static final int RECORDER_BPP = 16;
private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".wav";
private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
private static final String AUDIO_RECORDER_TEMP_FILE = "record_temp.raw";
private static final int RECORDER_SAMPLERATE = 8000;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private AudioRecord recorder = null;
private int bufferSize = 0;
private Thread recordingThread = null;
private boolean isRecording = false;
private static ServiceMusic self = null;
#Override
public void onCreate() {
super.onCreate();
Log.v(LOG_TAG, "in onCreate");
}
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.i("onStartComman?d", "onStartCommand");
self = ServiceMusic.this;
self.bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING);
self.recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,RECORDER_SAMPLERATE, RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING, bufferSize);
TelephonyManager mgr=(TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if (mgr!=null)
{
mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
return START_REDELIVER_INTENT;
}
#Override
public void onRebind(Intent intent) {
Log.v(LOG_TAG, "in onRebind");
super.onRebind(intent);
}
#Override
public boolean onUnbind(Intent intent) {
Log.v(LOG_TAG, "in onUnbind");
return true;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.v(LOG_TAG, "in onDestroy");
// mChronometer.stop();
}
private String getFilename(){
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath,AUDIO_RECORDER_FOLDER);
if(!file.exists()){
file.mkdirs();
}
return (file.getAbsolutePath() + "/" + "Ravindra" + AUDIO_RECORDER_FILE_EXT_WAV);
}
private String getTempFilename(){
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath,AUDIO_RECORDER_FOLDER);
if(!file.exists()){
file.mkdirs();
}
File tempFile = new File(filepath,AUDIO_RECORDER_TEMP_FILE);
if(tempFile.exists())
tempFile.delete();
return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE);
}
void startRecording(final boolean b){
if (self.recorder==null) {
//Log.i("startRecording", "iffffffffffffffffffff");
self.recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,RECORDER_SAMPLERATE, RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING, bufferSize);
}
self.recorder.startRecording();
isRecording = true;
self.recordingThread = new Thread(new Runnable() {
#Override
public void run() {
writeAudioDataToFile(b);
}
},"AudioRecorder Thread");
self.recordingThread.start();
}
void stopRecording(boolean b){
Log.i("stopRecording", "stopRecording");
if(self.recorder != null){
isRecording = false;
self.recorder.stop();
self.recorder.release();
self.recorder = null;
self.recordingThread = null;
Log.i("stopRecording", "nulll");
}
Log.i("stopRecording", "outer");
if(b == true){
Log.i("stopRecording", "true");
copyWaveFile(getTempFilename(),getFilename());
deleteTempFile();
}
}
private void deleteTempFile() {
File file = new File(getTempFilename());
file.delete();
}
private void writeAudioDataToFile(boolean b){
byte data[] = new byte[bufferSize];
String filename = getTempFilename();
FileOutputStream os = null;
try {
os = new FileOutputStream(filename,b);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int read = 0;
if(os != null){
while(isRecording){
read = self.recorder.read(data, 0, bufferSize);
if(AudioRecord.ERROR_INVALID_OPERATION != read){
try {
os.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void copyWaveFile(String inFilename,String outFilename){
FileInputStream in = null;
FileOutputStream out = null;
long totalAudioLen = 0;
long totalDataLen = totalAudioLen + 44;
long longSampleRate = RECORDER_SAMPLERATE;
int channels = 2;
long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels/8;
byte[] data = new byte[bufferSize];
try {
in = new FileInputStream(inFilename);
out = new FileOutputStream(outFilename);
totalAudioLen = in.getChannel().size();
totalDataLen = totalAudioLen + 44;
//AppLog.logString("File size: " + totalDataLen);
WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
longSampleRate, channels, byteRate);
while(in.read(data) != -1){
out.write(data);
}
in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void WriteWaveFileHeader(
FileOutputStream out, long totalAudioLen,
long totalDataLen, long longSampleRate, int channels,
long byteRate) throws IOException {
byte[] header = new byte[44];
header[0] = 'R'; // RIFF/WAVE header
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
header[4] = (byte) (totalDataLen & 0xff);
header[5] = (byte) ((totalDataLen >> 8) & 0xff);
header[6] = (byte) ((totalDataLen >> 16) & 0xff);
header[7] = (byte) ((totalDataLen >> 24) & 0xff);
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
header[12] = 'f'; // 'fmt ' chunk
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 16; // 4 bytes: size of 'fmt ' chunk
header[17] = 0;
header[18] = 0;
header[19] = 0;
header[20] = 1; // format = 1
header[21] = 0;
header[22] = (byte) channels;
header[23] = 0;
header[24] = (byte) (longSampleRate & 0xff);
header[25] = (byte) ((longSampleRate >> 8) & 0xff);
header[26] = (byte) ((longSampleRate >> 16) & 0xff);
header[27] = (byte) ((longSampleRate >> 24) & 0xff);
header[28] = (byte) (byteRate & 0xff);
header[29] = (byte) ((byteRate >> 8) & 0xff);
header[30] = (byte) ((byteRate >> 16) & 0xff);
header[31] = (byte) ((byteRate >> 24) & 0xff);
header[32] = (byte) (2 * 16 / 8); // block align
header[33] = 0;
header[34] = RECORDER_BPP; // bits per sample
header[35] = 0;
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
header[40] = (byte) (totalAudioLen & 0xff);
header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
out.write(header, 0, 44);
}
Acquire a wakelock when you start recording, and release it when you stop. Otherwise the device may go to sleep. For an example, see line 820 onwards of the android sound recorder app https://android.googlesource.com/platform/packages/apps/SoundRecorder/+/master/src/com/android/soundrecorder/SoundRecorder.java
(You may consider using a partial wake lock instead of a screen dim wake lock in the code above, if you are running in a background service)
See http://developer.android.com/reference/android/os/PowerManager.html

Android concat 2 audio (wav or mp3) files

I must concat 2 or more audio (wav or mp3) files and get one audio file.
How can I do that in android?
Thanks in advance.
The below code section will work as how many selections have been made.Selection means how much files are selected.
Put your two wav files in /sdcard0/SSoftAudioFiles/ as 1.wav and 2.wav.
And Just execute this method.
public void SSoftAudCombine()
{
try {
String[] selection=new String[2];
selection[0]="1.wav";
selection[1]="2.wav";
DataOutputStream amplifyOutputStream = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(Environment.getExternalStorageDirectory() + "/SSoftAudioFiles/" + year +"-"+ month +"-"+ date +"-"+ hour+"-" + min +"-"+ sec+"ME.wav")));
DataInputStream[] mergeFilesStream = new DataInputStream[selection.length];
long[] sizes=new long[selection.length];
for(int i=0; i<selection.length; i++) {
File file = new File(Environment.getExternalStorageDirectory() + "/SSoftAudioFiles/" +selection[i]);
sizes[i] = (file.length()-44)/2;
}
for(int i =0; i<selection.length; i++) {
mergeFilesStream[i] =new DataInputStream(new BufferedInputStream(new FileInputStream(Environment.getExternalStorageDirectory() + "/SSoftAudioFiles/" +selection[i])));
if(i == selection.length-1) {
mergeFilesStream[i].skip(24);
byte[] sampleRt = new byte[4];
mergeFilesStream[i].read(sampleRt);
ByteBuffer bbInt = ByteBuffer.wrap(sampleRt).order(ByteOrder.LITTLE_ENDIAN);
RECORDER_SAMPLERATE = bbInt.getInt();
mergeFilesStream[i].skip(16);
}
else {
mergeFilesStream[i].skip(44);
}
}
for(int b=0; b<selection.length; b++) {
for(int i=0; i<(int)sizes[b]; i++) {
byte[] dataBytes = new byte[2];
try {
dataBytes[0] = mergeFilesStream[b].readByte();
dataBytes[1] = mergeFilesStream[b].readByte();
}
catch (EOFException e) {
amplifyOutputStream.close();
}
short dataInShort = ByteBuffer.wrap(dataBytes).order(ByteOrder.LITTLE_ENDIAN).getShort();
float dataInFloat= (float) dataInShort/37268.0f;
short outputSample = (short)(dataInFloat * 37268.0f);
byte[] dataFin = new byte[2];
dataFin[0] = (byte) (outputSample & 0xff);
dataFin[1] = (byte)((outputSample >> 8) & 0xff);
amplifyOutputStream.write(dataFin, 0 , 2);
}
}
amplifyOutputStream.close();
for(int i=0; i<selection.length; i++) {
mergeFilesStream[i].close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
long size =0;
try {
FileInputStream fileSize = new FileInputStream(Environment.getExternalStorageDirectory() + "/SSoftAudioFiles/"+year +"-"+ month +"-"+ date +"-"+ hour+"-" + min +"-"+ sec+"ME.wav");
size = fileSize.getChannel().size();
fileSize.close();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
final int RECORDER_BPP = 16;
long datasize=size+36;
long byteRate = (RECORDER_BPP * RECORDER_SAMPLERATE)/8;
long longSampleRate = RECORDER_SAMPLERATE;
byte[] header = new byte[44];
header[0] = 'R'; // RIFF/WAVE header
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
header[4] = (byte) (datasize & 0xff);
header[5] = (byte) ((datasize >> 8) & 0xff);
header[6] = (byte) ((datasize >> 16) & 0xff);
header[7] = (byte) ((datasize >> 24) & 0xff);
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
header[12] = 'f'; // 'fmt ' chunk
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 16; // 4 bytes: size of 'fmt ' chunk
header[17] = 0;
header[18] = 0;
header[19] = 0;
header[20] = 1; // format = 1
header[21] = 0;
header[22] = (byte) 1;
header[23] = 0;
header[24] = (byte) (longSampleRate & 0xff);
header[25] = (byte) ((longSampleRate >> 8) & 0xff);
header[26] = (byte) ((longSampleRate >> 16) & 0xff);
header[27] = (byte) ((longSampleRate >> 24) & 0xff);
header[28] = (byte) (byteRate & 0xff);
header[29] = (byte) ((byteRate >> 8) & 0xff);
header[30] = (byte) ((byteRate >> 16) & 0xff);
header[31] = (byte) ((byteRate >> 24) & 0xff);
header[32] = (byte) ((RECORDER_BPP) / 8); // block align
header[33] = 0;
header[34] = RECORDER_BPP; // bits per sample
header[35] = 0;
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
header[40] = (byte) (size & 0xff);
header[41] = (byte) ((size >> 8) & 0xff);
header[42] = (byte) ((size >> 16) & 0xff);
header[43] = (byte) ((size >> 24) & 0xff);
// out.write(header, 0, 44);
try {
RandomAccessFile rFile = new RandomAccessFile(Environment.getExternalStorageDirectory() + "/SSoftAudioFiles/" +year +"-"+ month +"-"+ date +"-"+ hour+"-" + min +"-"+ sec+ "ME.wav", "rw");
rFile.seek(0);
rFile.write(header);
rFile.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
It will concate your audio file and save a combined file in /sdcard0/SSoftAudioFiles/...ME.wav.
The below code will surely help you to concatinating two audio files.
try {
FileInputStream fis1 = new FileInputStream("/sdcard/MJdangerous.wav");
FileInputStream fis2 = new FileInputStream("/sdcard/MJBad.wav");
SequenceInputStream sis = new SequenceInputStream(fis1,fis2);
FileOutputStream fos = new FileOutputStream(new File("/sdcard/MJdangerousMJBad.wav"));
int temp;
try {
while ((temp = sis.read())!= -1){
fos.write(temp);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Audio recording in android with particular time interval

I have two method in my activity one is setOnClickListener() and other is setOnLongClickListener()
For the same button which used to start audio recording.
Now i don't know how to use condition, if i use setOnClickListener() then recording should start for 1 minute and stop automatically, and if i use setOnLongClickListener() then recording start for 2 minute and then stop automatically.
buttonStart.setOnLongClickListener(new OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
Toast.makeText(Record_Audio.this,
"Start Recording With LongClick", Toast.LENGTH_SHORT)
.show();
enableButtons(true);
startRecording();
return true;
}
});
private View.OnClickListener btnClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStart: {
Toast.makeText(Record_Audio.this, "Start Recording",
Toast.LENGTH_SHORT).show();
enableButtons(true);
startRecording();
break;
}
}
});
private void startRecording() {
displayAlertDialog();
}
private void displayAlertDialog() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
Record_Audio.this);
alertDialog.setTitle("Would you Like to save your Recording");
alertDialog.setMessage("Enter Audio Name");
alertDialog.setIcon(R.drawable.save_icon);
final EditText editTextAudioName = new EditText(Record_Audio.this);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
editTextAudioName.setLayoutParams(lp);
alertDialog.setView(editTextAudioName);
alertDialog.setPositiveButton("Save",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Code.audioName = editTextAudioName.getText().toString()
.trim();
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(output_formats[currentFormat]);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(getFilename());
recorder.setOnErrorListener(errorListener);
recorder.setOnInfoListener(infoListener);
try {
recorder.prepare();
recorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
myChronometer.setBase(SystemClock.elapsedRealtime());
myChronometer.start();
}
});
alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Write your code here to execute after dialog
dialog.cancel();
}
});
alertDialog.show();
}
I know i have to use setMaxDuration for particular time interval, but i don't know how to use with this two method.
Thanks in advance.
Anyhow the MediaRecorder Api is not good way to use record audio.Use the AudioRecorder API.
Let me explain
1.This is class for recording audio
public class Taukyrecorder {
private static final int RECORDER_BPP = 16;
private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".mp3";
private static final String AUDIO_RECORDER_FOLDER = "/'/'";
private static final String AUDIO_RECORDER_TEMP_FILE = "record_temp.raw";
private static final int RECORDER_SAMPLERATE = 44100;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private AudioRecord recorder = null;
private int bufferSize = 0;
private Thread recordingThread = null;
public static boolean isRecording = false;
int numCrossing, p;
public int frequency;
int blockSize = 3500;
private Context mcontext;
public static String final_sound_path = null;
Handler handler;
RecorderListener mylistener;
public Taukyrecorder(Context cntxt) {
// TODO Auto-generated constructor stub
mcontext = cntxt;
// Log.i("Recorder", "helllllo");
InitRecord();
}
public void RegisterListener(RecorderListener listener) {
this.mylistener = listener;
}
public void InitRecord()
{
handler = new Handler();
bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,
RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING);
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE, RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING, bufferSize);
recorder.setRecordPositionUpdateListener(
new OnRecordPositionUpdateListener() {
#Override
public void onPeriodicNotification(AudioRecord recorder) {
// TODO Auto-generated method stub
}
#Override
public void onMarkerReached(AudioRecord recorder) {
// TODO Auto-generated method stub
}
}, handler);
}
// Get the file for saving sound into the folder
public File GetFileTOwriteSound() {
File tempPicFile = null;
String ext_storage_state = Environment.getExternalStorageState();
File mediaStorage = new File(Environment.getExternalStorageDirectory()
+ "/TAUKY/SOUNDS");
if (ext_storage_state.equalsIgnoreCase(Environment.MEDIA_MOUNTED)) {
if (!mediaStorage.exists()) {
mediaStorage.mkdirs();
} else {
// do nothing
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
tempPicFile = new File(mediaStorage.getPath() + File.separator
+ "SOUND_" + timeStamp + ".mp3");
} else {
Toast.makeText(mcontext, "NO SDCARD MOUNTED", 1).show();
}
return tempPicFile;
}
private String getTempFilename() {
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath, AUDIO_RECORDER_FOLDER);
if (!file.exists()) {
file.mkdirs();
}
File tempFile = new File(filepath, AUDIO_RECORDER_TEMP_FILE);
if (tempFile.exists())
tempFile.delete();
return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE);
}
public void startRecording() {
//InitRecord();
recorder.startRecording();
isRecording = true;
recordingThread = new Thread(new Runnable() {
#Override
public void run() {
writedataToFile();
}
}, "AudioRecorder Thread");
recordingThread.start();
}
private void writedataToFile() {
byte data[] = new byte[bufferSize];
String filename = getTempFilename();
FileOutputStream os = null;
try {
os = new FileOutputStream(filename);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int read = 0;
short[] buffer = new short[blockSize];
double[] toTransform = new double[blockSize];
if (null != os) {
while (isRecording) {
read = recorder.read(data, 0, bufferSize);
if (AudioRecord.ERROR_INVALID_OPERATION != read) {
try {
os.write(data);
} catch (IOException e) {
e.printStackTrace();
}
//int bufferReadResult = recorder.read(buffer, 0, blockSize);
//byte[] bData= {};
short[] sData= new short[data.length/2];
// to turn bytes to shorts as either big endian or little endian.
ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(sData);
for (int i = 0; i < blockSize && i < read; i++) {
toTransform[i] = sData[i] / 32768.0;
}
mylistener.Updatevalues(toTransform);
}
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void stopRecording() {
String getfilename = GetFileTOwriteSound().getAbsolutePath();
final_sound_path = getfilename;
if (null != recorder) {
isRecording = false;
recorder.stop();
recorder.release();
recorder = null;
recordingThread = null;
}
copyWaveFile(getTempFilename(), getfilename);
deleteTempFile();
}
private void deleteTempFile() {
File file = new File(getTempFilename());
file.delete();
}
private void copyWaveFile(String inFilename, String outFilename) {
FileInputStream in = null;
FileOutputStream out = null;
long totalAudioLen = 0;
long totalDataLen = totalAudioLen + 36;
long longSampleRate = RECORDER_SAMPLERATE;
int channels = 2;
long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels / 8;
byte[] data = new byte[bufferSize];
try {
in = new FileInputStream(inFilename);
out = new FileOutputStream(outFilename);
totalAudioLen = in.getChannel().size();
totalDataLen = totalAudioLen + 36;
// /AppLog.logString("File size: " + totalDataLen);
WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
longSampleRate, channels, byteRate);
while (in.read(data) != -1) {
out.write(data);
}
in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void WriteWaveFileHeader(FileOutputStream out, long totalAudioLen,
long totalDataLen, long longSampleRate, int channels, long byteRate)
throws IOException {
byte[] header = new byte[44];
header[0] = 'R'; // RIFF/WAVE header
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
header[4] = (byte) (totalDataLen & 0xff);
header[5] = (byte) ((totalDataLen >> 8) & 0xff);
header[6] = (byte) ((totalDataLen >> 16) & 0xff);
header[7] = (byte) ((totalDataLen >> 24) & 0xff);
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
header[12] = 'f'; // 'fmt ' chunk
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 16; // 4 bytes: size of 'fmt ' chunk
header[17] = 0;
header[18] = 0;
header[19] = 0;
header[20] = 1; // format = 1
header[21] = 0;
header[22] = (byte) channels;
header[23] = 0;
header[24] = (byte) (longSampleRate & 0xff);
header[25] = (byte) ((longSampleRate >> 8) & 0xff);
header[26] = (byte) ((longSampleRate >> 16) & 0xff);
header[27] = (byte) ((longSampleRate >> 24) & 0xff);
header[28] = (byte) (byteRate & 0xff);
header[29] = (byte) ((byteRate >> 8) & 0xff);
header[30] = (byte) ((byteRate >> 16) & 0xff);
header[31] = (byte) ((byteRate >> 24) & 0xff);
header[32] = (byte) (2 * 16 / 8); // block align
header[33] = 0;
header[34] = RECORDER_BPP; // bits per sample
header[35] = 0;
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
header[40] = (byte) (totalAudioLen & 0xff);
header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
out.write(header, 0, 44);
}
}
Start and stop the record
MainActivity
TaukkyRecordr taukyrecorder=new Taukyrecorder(mcontext);
taukyrecorder.startRecording();
//For stop
taukyrecorder.stopRecording();
If you want stop automatically after few second please create one thread.
public class StopRecord extends Thread {
int i = 0;
#Override
public void run() {
// TODO Auto-generated method stub
super.run();
handler.post(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
taukyrecorder.stopRecording();
}
});
}
}
Then call the thread using handler
Handker mhandler=new Handeler;
mhandler.postDelayed(mRunnable, 1000);//put your secodn here

android voice recording - voice with background noice issue

I am developing an voice recording android application. For this I am using the following code. When I record and play it, I am getting recording voice with background noice. How can I get only recording voice. Can anyone help me?
import java.io.File;
import java.io.FileInputStream;
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.view.View;
import android.widget.Button;
public class RecorderActivity extends Activity {
private static final int RECORDER_BPP = 16;
private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".wav";
private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
private static final String AUDIO_RECORDER_TEMP_FILE = "record_temp.raw";
private static final int RECORDER_SAMPLERATE = 44100;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private AudioRecord recorder = null;
private int bufferSize = 0;
private Thread recordingThread = null;
private boolean isRecording = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setButtonHandlers();
enableButtons(false);
bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING);
}
private void setButtonHandlers() {
((Button)findViewById(R.id.btnStart)).setOnClickListener(btnClick);
((Button)findViewById(R.id.btnStop)).setOnClickListener(btnClick);
}
private void enableButton(int id,boolean isEnable){
((Button)findViewById(id)).setEnabled(isEnable);
}
private void enableButtons(boolean isRecording) {
enableButton(R.id.btnStart,!isRecording);
enableButton(R.id.btnStop,isRecording);
}
private String getFilename(){
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath,AUDIO_RECORDER_FOLDER);
if(!file.exists()){
file.mkdirs();
}
return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + AUDIO_RECORDER_FILE_EXT_WAV);
}
private String getTempFilename(){
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath,AUDIO_RECORDER_FOLDER);
if(!file.exists()){
file.mkdirs();
}
File tempFile = new File(filepath,AUDIO_RECORDER_TEMP_FILE);
if(tempFile.exists())
tempFile.delete();
return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE);
}
private void startRecording(){
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE, RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING, bufferSize);
recorder.startRecording();
isRecording = true;
recordingThread = new Thread(new Runnable() {
#Override
public void run() {
writeAudioDataToFile();
}
},"AudioRecorder Thread");
recordingThread.start();
}
private void writeAudioDataToFile(){
byte data[] = new byte[bufferSize];
String filename = getTempFilename();
FileOutputStream os = null;
try {
os = new FileOutputStream(filename);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int read = 0;
if(null != os){
while(isRecording){
read = recorder.read(data, 0, bufferSize);
if(AudioRecord.ERROR_INVALID_OPERATION != read){
try {
os.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void stopRecording(){
if(null != recorder){
isRecording = false;
recorder.stop();
recorder.release();
recorder = null;
recordingThread = null;
}
copyWaveFile(getTempFilename(),getFilename());
deleteTempFile();
}
private void deleteTempFile() {
File file = new File(getTempFilename());
file.delete();
}
private void copyWaveFile(String inFilename,String outFilename){
FileInputStream in = null;
FileOutputStream out = null;
long totalAudioLen = 0;
long totalDataLen = totalAudioLen + 36;
long longSampleRate = RECORDER_SAMPLERATE;
int channels = 2;
long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels/8;
byte[] data = new byte[bufferSize];
try {
in = new FileInputStream(inFilename);
out = new FileOutputStream(outFilename);
totalAudioLen = in.getChannel().size();
totalDataLen = totalAudioLen + 36;
AppLog.logString("File size: " + totalDataLen);
WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
longSampleRate, channels, byteRate);
while(in.read(data) != -1){
out.write(data);
}
in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void WriteWaveFileHeader(
FileOutputStream out, long totalAudioLen,
long totalDataLen, long longSampleRate, int channels,
long byteRate) throws IOException {
byte[] header = new byte[44];
header[0] = 'R'; // RIFF/WAVE header
header[1] = 'I';
header[2] = 'F';
header[3] = 'F';
header[4] = (byte) (totalDataLen & 0xff);
header[5] = (byte) ((totalDataLen >> 8) & 0xff);
header[6] = (byte) ((totalDataLen >> 16) & 0xff);
header[7] = (byte) ((totalDataLen >> 24) & 0xff);
header[8] = 'W';
header[9] = 'A';
header[10] = 'V';
header[11] = 'E';
header[12] = 'f'; // 'fmt ' chunk
header[13] = 'm';
header[14] = 't';
header[15] = ' ';
header[16] = 16; // 4 bytes: size of 'fmt ' chunk
header[17] = 0;
header[18] = 0;
header[19] = 0;
header[20] = 1; // format = 1
header[21] = 0;
header[22] = (byte) channels;
header[23] = 0;
header[24] = (byte) (longSampleRate & 0xff);
header[25] = (byte) ((longSampleRate >> 8) & 0xff);
header[26] = (byte) ((longSampleRate >> 16) & 0xff);
header[27] = (byte) ((longSampleRate >> 24) & 0xff);
header[28] = (byte) (byteRate & 0xff);
header[29] = (byte) ((byteRate >> 8) & 0xff);
header[30] = (byte) ((byteRate >> 16) & 0xff);
header[31] = (byte) ((byteRate >> 24) & 0xff);
header[32] = (byte) (2 * 16 / 8); // block align
header[33] = 0;
header[34] = RECORDER_BPP; // bits per sample
header[35] = 0;
header[36] = 'd';
header[37] = 'a';
header[38] = 't';
header[39] = 'a';
header[40] = (byte) (totalAudioLen & 0xff);
header[41] = (byte) ((totalAudioLen >> 8) & 0xff);
header[42] = (byte) ((totalAudioLen >> 16) & 0xff);
header[43] = (byte) ((totalAudioLen >> 24) & 0xff);
out.write(header, 0, 44);
}
private View.OnClickListener btnClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btnStart:{
AppLog.logString("Start Recording");
enableButtons(true);
startRecording();
break;
}
case R.id.btnStop:{
AppLog.logString("Start Recording");
enableButtons(false);
stopRecording();
break;
}
}
}
};
}
Are you testing this with the emulator, or on an actual device (if so, which device)? The acoustic tuning (which includes gain control, noise reduction, etc) will be specific to a given platform and product, and is not something you can change.
Jellybean includes APIs to let applications apply certain acoustic filters on recordings, and a noise suppressor is one of those. However, by using that API you're limiting your app to only function correctly on devices running Jellybean or later (and not even all of those devices might actually implement this functionality).
Another possibility would be to include a noise suppressor in your app. I think e.g. Speex includes noise supressing functionality, but it's geared towards low-bitrate speech encoding.
If you want to NoiseSuppressor then you can use this:
// The following would take effect only on Jelly Bean and higher.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
Log.i("Trying to clean up audio because running on SDK " + Build.VERSION.SDK_INT);
if (noise && NoiseSuppressor.create(getAudioSessionId()) == null) {
Log.i("NoiseSuppressor not present :(");
} else {
Log.i("NoiseSuppressor enabled!");
}
if (gain && AutomaticGainControl.create(getAudioSessionId()) == null) {
Log.i("AutomaticGainControl not present :(");
} else {
Log.i("AutomaticGainControl enabled!");
}
if (echo && AcousticEchoCanceler.create(getAudioSessionId()) == null) {
Log.i("AcousticEchoCanceler not present :(");
} else {
Log.i("AcousticEchoCanceler enabled!");
}
}
This code can remove background noise , echo and gain.

Categories

Resources