How to record audio with different frequency? - android

I am trying to record audio with different frequency. Though I have been trying to implement it by the following code but its not working (app unexpectedly stopped).
//importing packages
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.KeyEvent;
import android.view.View;
import android.widget.Button;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends Activity {
private static final int RECORDER_SAMPLERATE = 44100;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private AudioRecord recorder = null;
private Thread recordingThread = null;
private boolean isRecording = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setButtonHandlers();//handling buttons
enableButtons(false);
int bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE,
RECORDER_CHANNELS, RECORDER_AUDIO_ENCODING);
}
private void setButtonHandlers() {
((Button) findViewById(R.id.Start)).setOnClickListener(btnClick);
((Button) findViewById(R.id.Stop)).setOnClickListener(btnClick);
}
private void enableButton(int id, boolean isEnable) {
((Button) findViewById(id)).setEnabled(isEnable);
}
private void enableButtons(boolean isRecording) {
enableButton(R.id.Start, !isRecording);
enableButton(R.id.Stop, isRecording);
}
int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we use only 1024
int BytesPerElement = 2; // 2 bytes in 16bit format
public void Record()
{
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE, RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING, BufferElements2Rec * BytesPerElement);
recorder.startRecording();
isRecording = true;
recordingThread = new Thread(new Runnable() {
public void run() {
writeAudioDataToFile();
}
}, "AudioRecorder Thread");
recordingThread.start();
}
private byte[] short2byte(short[] sData) {
int shortArrsize = sData.length;
byte[] bytes = new byte[shortArrsize * 2];
for (int i = 0; i < shortArrsize; i++) {
bytes[i * 2] = (byte) (sData[i] & 0x00FF);
bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
sData[i] = 0;
}
return bytes;
}
private void writeAudioDataToFile() {
// Write the output audio in byte
String filePath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/myrec.pcm";
short sData[] = new short[BufferElements2Rec];
FileOutputStream os = null;
try {
os = new FileOutputStream(filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (isRecording) {
// gets the voice output from microphone to byte format
recorder.read(sData, 0, BufferElements2Rec);
System.out.println("Short wirting to file" + sData.toString());
try {
// // writes the data to file from buffer
// // stores the voice buffer
byte bData[] = short2byte(sData);
os.write(bData, 0, BufferElements2Rec * BytesPerElement);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void Record_Stop()
{
if (null != recorder) {
isRecording = false;
recorder.stop();
recorder.release();
recorder = null;
recordingThread = null;
}
}
private View.OnClickListener btnClick = new View.OnClickListener() {
public void onClick(View v) {
switch (v.getId()) {
case R.id.Start: {
enableButtons(true);
Record();
break;
}
case R.id.Stop: {
enableButtons(false);
Record_Stop();
break;
}
}
}
};
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
finish();
}
return super.onKeyDown(keyCode, event);
}
}
As soon as I press the start button the app gets unexpectedly stopped.
com.example.kaushal.learningfft E/AndroidRuntime: FATAL EXCEPTION:
main Process: com.example.kaushal.learningfft, PID: 4705
java.lang.IllegalStateException: startRecording() called on an
uninitialized AudioRecord. at
android.media.AudioRecord.startRecording(AudioRecord.java:97‌​6) at
com.example.kaushal.learningfft.MainActivity.Record(MainActi‌​vity.java:57)
at
com.example.kaushal.learningfft.MainActivity$2.onClick(MainA‌​ctivity.java:126)
at android.view.View.performClick(View.java:5610) at
android.view.View$PerformClick.run(View.java:22265) at
android.os.Handler.handleCallback(Handler.java:751) at
android.os.Handler.dispatchMessage(Handler.java:95) at
android.os.Looper.loop(Looper.java:154)
android.app.ActivityThread.main(ActivityThread.java:6077) at
java.lang.reflect.Method.invoke(Native Method) at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(Z‌​ygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)

Related

how to save changed pitch audio file to sd card android

In my android application I want to change the pitch of an audio file and save it to sd card.
I am using sonic ndk link for changing pitch of my audio file but I am unable to save the changed audio file.
Is there any way to save this changed pitch audio file? Thanks in advance
Below is the code that I am using for my audio modification and save.
public class SonicTest extends Activity implements View.OnClickListener {
private Button saveBtn;
private int bufferSize=0;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
saveBtn = findViewById(R.id.button1);
saveBtn.setOnClickListener(this);
}
public void play(View view)
{
new Thread(new Runnable()
{
public void run()
{
final EditText speedEdit = findViewById(R.id.speed);
final EditText pitchEdit = findViewById(R.id.pitch);
final EditText rateEdit = findViewById(R.id.rate);
float speed = Float.parseFloat(speedEdit.getText().toString());
float pitch = Float.parseFloat(pitchEdit.getText().toString());
float rate = Float.parseFloat(rateEdit.getText().toString());
AndroidAudioDevice device = new AndroidAudioDevice(22050, 1);
Sonic sonic = new Sonic(22050, 1);
byte samples[] = new byte[4096];
byte modifiedSamples[] = new byte[2048];
InputStream soundFile = getResources().openRawResource(R.raw.talking);
// InputStream soundFile = getResources().openRawResource(R.raw.sample);
int bytesRead;
if(soundFile != null) {
sonic.setSpeed(speed);
sonic.setPitch(pitch);
sonic.setRate(rate);
do {
try {
bytesRead = soundFile.read(samples, 0, samples.length);
} catch (IOException e) {
e.printStackTrace();
return;
}
if(bytesRead > 0) {
sonic.putBytes(samples, bytesRead);
} else {
sonic.flush();
}
int available = sonic.availableBytes();
if(available > 0) {
if(modifiedSamples.length < available) {
modifiedSamples = new byte[available*2];
}
sonic.receiveBytes(modifiedSamples, available);
device.writeSamples(modifiedSamples, available);
}
} while(bytesRead > 0);
device.flush();
}
}
} ).start();
}
#Override
public void onClick(View v) {
LinkedList<byte[]>linkedList = AndroidAudioDevice.list;
for (int i=0; i<linkedList.size(); i++){
bufferSize = bufferSize+linkedList.get(i).length;
}
byte[]buffer = new byte[bufferSize];
int k=0;
for (int i=0 ; i< linkedList.size(); i++){
for(int j=0; j<linkedList.get(i).length; j++){
buffer[k]=linkedList.get(i)[j];
k++;
}
Log.v("Buffer array length",""+k);
}
File file = new File(Environment.getExternalStorageDirectory(),"demo.mp3");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
fos.write(buffer);
fos.flush();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
package org.vinuxproject.sonic;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Environment;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.LinkedList;
public class AndroidAudioDevice
{
AudioTrack track;
static int bufferLength;
public static LinkedList<byte[]>list= new LinkedList<>();
private int findFormatFromChannels(int numChannels)
{
switch(numChannels) {
case 1: return AudioFormat.CHANNEL_OUT_MONO;
case 2: return AudioFormat.CHANNEL_OUT_STEREO;
default: return -1; // Error
}
}
public AndroidAudioDevice(int sampleRate, int numChannels)
{
int format = findFormatFromChannels(numChannels);
int minSize = AudioTrack.getMinBufferSize(sampleRate, format, AudioFormat.ENCODING_PCM_16BIT);
track = new AudioTrack( AudioManager.STREAM_MUSIC, sampleRate,
format, AudioFormat.ENCODING_PCM_16BIT,
minSize*4, AudioTrack.MODE_STREAM);
track.play();
}
public void flush()
{
track.flush();
}
public void writeSamples(byte[] samples, int length)
{
bufferLength = bufferLength+length;
track.write( samples, 0, length);
list.add(samples);
}
}

Android - How to convert raw data of audio to wav?

I have implemented a feature of recording audio in my android app. My app is working fine on linux. but when i run same app in mac osx and do recording audio, it crashes my app.
private AudioRecordingThread recordingThread;
recordingThread = new AudioRecordingThread(fileName,
new AudioRecordingHandler() {
#Override
public void onFftDataCapture(final byte[] bytes) {
runOnUiThread(new Runnable() {
public void run() {
if (visualizerView != null) {
visualizerView.updateVisualizerFFT(bytes);
}
}
});
}
#Override
public void onRecordSuccess() {
}
#Override
public void onRecordingError() {
runOnUiThread(new Runnable() {
public void run() {
recordStop();
NotificationUtils.showInfoDialog(
ActivityCropImage.this,
"Error in saving");
}
});
}
#Override
public void onRecordSaveError() {
runOnUiThread(new Runnable() {
public void run() {
recordStop();
NotificationUtils.showInfoDialog(
ActivityCropImage.this,
"Error in recording");
}
});
}
});
PcmAudioHelper.convertRawToWav(WavAudioFormat.mono16Bit(SAMPLING_RATE), file_raw, file_wav);
This is the line of code where my app crashed. I have used https://github.com/steelkiwi/AndroidRecording library in my project.
package com.record.util;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Environment;
import android.text.format.Time;
import android.util.Log;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class RecordWavMaster {
private static final int samplingRates[] = {16000, 11025, 11000, 8000, 6000};
public static int SAMPLE_RATE = 16000;
private AudioRecord mRecorder;
private File mRecording;
private short[] mBuffer;
private String audioFilePath;
private boolean mIsRecording = false;
private String RECORD_WAV_PATH = Environment.getExternalStorageDirectory() + File.separator + "AudioRecord";
/* Initializing AudioRecording MIC */
public RecordWavMaster() {
initRecorder();
}
/* Get Supported Sample Rate */
public static int getValidSampleRates() {
for (int rate : samplingRates) {
int bufferSize = AudioRecord.getMinBufferSize(rate, AudioFormat.CHANNEL_CONFIGURATION_DEFAULT, AudioFormat.ENCODING_PCM_16BIT);
if (bufferSize > 0) {
return rate;
}
}
return SAMPLE_RATE;
}
/* Start AudioRecording */
public void recordWavStart() {
mIsRecording = true;
mRecorder.startRecording();
mRecording = getFile("raw");
startBufferedWrite(mRecording);
}
/* Stop AudioRecording */
public String recordWavStop() {
try {
mIsRecording = false;
mRecorder.stop();
File waveFile = getFile("wav");
rawToWave(mRecording, waveFile);
Log.e("path_audioFilePath",audioFilePath);
return audioFilePath;
} catch (Exception e) {
Log.e("Error saving file : ", e.getMessage());
}
return null;
}
/* Release device MIC */
public void releaseRecord() {
mRecorder.release();
}
/* Initializing AudioRecording MIC */
private void initRecorder() {
SAMPLE_RATE = getValidSampleRates();
int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
mBuffer = new short[bufferSize];
mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufferSize);
new File(RECORD_WAV_PATH).mkdir();
}
/* Writing RAW file */
private void startBufferedWrite(final File file) {
new Thread(new Runnable() {
#Override
public void run() {
DataOutputStream output = null;
try {
output = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
while (mIsRecording) {
double sum = 0;
int readSize = mRecorder.read(mBuffer, 0, mBuffer.length);
for (int i = 0; i < readSize; i++) {
output.writeShort(mBuffer[i]);
sum += mBuffer[i] * mBuffer[i];
}
if (readSize > 0) {
final double amplitude = sum / readSize;
}
}
} catch (IOException e) {
Log.e("Error writing file : ", e.getMessage());
} finally {
if (output != null) {
try {
output.flush();
} catch (IOException e) {
Log.e("Error writing file : ", e.getMessage());
} finally {
try {
output.close();
} catch (IOException e) {
Log.e("Error writing file : ", e.getMessage());
}
}
}
}
}
}).start();
}
/* Converting RAW format To WAV Format*/
private void rawToWave(final File rawFile, final File waveFile) throws IOException {
byte[] rawData = new byte[(int) rawFile.length()];
DataInputStream input = null;
try {
input = new DataInputStream(new FileInputStream(rawFile));
input.read(rawData);
} finally {
if (input != null) {
input.close();
}
}
DataOutputStream output = null;
try {
output = new DataOutputStream(new FileOutputStream(waveFile));
// WAVE header
writeString(output, "RIFF"); // chunk id
writeInt(output, 36 + rawData.length); // chunk size
writeString(output, "WAVE"); // format
writeString(output, "fmt "); // subchunk 1 id
writeInt(output, 16); // subchunk 1 size
writeShort(output, (short) 1); // audio format (1 = PCM)
writeShort(output, (short) 1); // number of channels
writeInt(output, SAMPLE_RATE); // sample rate
writeInt(output, SAMPLE_RATE * 2); // byte rate
writeShort(output, (short) 2); // block align
writeShort(output, (short) 16); // bits per sample
writeString(output, "data"); // subchunk 2 id
writeInt(output, rawData.length); // subchunk 2 size
// Audio data (conversion big endian -> little endian)
short[] shorts = new short[rawData.length / 2];
ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts);
ByteBuffer bytes = ByteBuffer.allocate(shorts.length * 2);
for (short s : shorts) {
bytes.putShort(s);
}
output.write(bytes.array());
} finally {
if (output != null) {
output.close();
rawFile.delete();
}
}
}
/* Get file name */
private File getFile(final String suffix) {
Time time = new Time();
time.setToNow();
audioFilePath = time.format("%Y%m%d%H%M%S");
return new File(RECORD_WAV_PATH, time.format("%Y%m%d%H%M%S") + "." + suffix);
}
private void writeInt(final DataOutputStream output, final int value) throws IOException {
output.write(value >> 0);
output.write(value >> 8);
output.write(value >> 16);
output.write(value >> 24);
}
private void writeShort(final DataOutputStream output, final short value) throws IOException {
output.write(value >> 0);
output.write(value >> 8);
}
private void writeString(final DataOutputStream output, final String value) throws IOException {
for (int i = 0; i < value.length(); i++) {
output.write(value.charAt(i));
}
}
public String getFileName (final String time_suffix) {
return (RECORD_WAV_PATH+time_suffix+ "." + "wav");
}
public Boolean getRecordingState () {
if( mRecorder.getRecordingState() == AudioRecord.RECORDSTATE_STOPPED) {
return false;
}
return true;
}
}
Use the following permissions in manifest
<!--Permission record-->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

How to record audio using AudioRecorder in Android

I want to capture audio from an Android device. My code below seems to successfully make a wav file on the SD card but it cannot be played. I tried to play it using different media players but none work. There is an issue in my code that is causing this problem.
code
public class MainActivity extends ActionBarActivity {
private static final String LOG_TAG = "AudioRecordTest";
static final int AUDIO_PORT = 2048;
static final int SAMPLE_RATE = 8000;
static final int SAMPLE_INTERVAL = 20; // milliseconds
static final int SAMPLE_SIZE = 2; // bytes per sample
static final int BUF_SIZE = SAMPLE_INTERVAL * SAMPLE_INTERVAL * SAMPLE_SIZE * 2;
private static int[] mSampleRates = new int[]{44100, 44056, 47250, 48000, 22050, 16000, 11025, 8000};
private Thread recordingThread = null;
private boolean isRecording = false;
int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we
// use only 1024
int BytesPerElement = 2; // 2 bytes in 16bit format
private int bufferSize;
private AudioRecord recorder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startRecording();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private void startRecording() {
recorder = findAudioRecord();
recorder.startRecording();
isRecording = true;
recordingThread = new Thread(new Runnable() {
public void run() {
writeAudioDataToFile();
}
}, "AudioRecorder Thread");
recordingThread.start();
}
// convert short to byte
private byte[] short2byte(short[] sData) {
int shortArrsize = sData.length;
byte[] bytes = new byte[shortArrsize * 2];
for (int i = 0; i < shortArrsize; i++) {
bytes[i * 2] = (byte) (sData[i] & 0x00FF);
bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
sData[i] = 0;
}
return bytes;
}
public AudioRecord findAudioRecord() {
for (int rate : mSampleRates) {
for (short audioFormat : new short[]{AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT}) {
for (short channelConfig : new short[]{AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO}) {
try {
Log.d(LOG_TAG, "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: "
+ channelConfig);
bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);
if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {
// check if we can instantiate and have a success
recorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize);
if (recorder.getState() == AudioRecord.STATE_INITIALIZED)
return recorder;
}
} catch (Exception e) {
Log.e(LOG_TAG, rate + "Exception, keep trying.", e);
}
}
}
}
return null;
}
private void writeAudioDataToFile() {
/*// Write the output audio in byte
short sData[] = new short[BufferElements2Rec];
while (isRecording) {
// gets the voice output from microphone to byte format
recorder.read(sData, 0, BufferElements2Rec);
System.out.println("Short wirting to file" + sData.toString());
// // stores the voice buffer
byte bData[] = short2byte(sData);
sendLiveAudio(bData);
}*/
String filePath = "/sdcard/test.wav";
short sData[] = new short[bufferSize / 2];
FileOutputStream os = null;
try {
os = new FileOutputStream(filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (isRecording) {
// gets the voice output from microphone to byte format
recorder.read(sData, 0, bufferSize / 2);
Log.d("eray", "Short wirting to file" + sData.toString());
try {
// // writes the data to file from buffer
// // stores the voice buffer
byte bData[] = short2byte(sData);
os.write(bData, 0, bufferSize);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void stopRecording() {
// stops the recording activity
if (null != recorder) {
isRecording = false;
recorder.stop();
recorder.release();
recorder = null;
recordingThread = null;
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
super.onBackPressed();
stopRecording();
}
}
Try This.....
public class Audio_Record extends Activity {
private static final int RECORDER_SAMPLERATE = 8000;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private AudioRecord recorder = null;
private Thread recordingThread = null;
private boolean isRecording = false;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setButtonHandlers();
enableButtons(false);
int 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);
}
int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we use only 1024
int BytesPerElement = 2; // 2 bytes in 16bit format
private void startRecording() {
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE, RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING, BufferElements2Rec * BytesPerElement);
recorder.startRecording();
isRecording = true;
recordingThread = new Thread(new Runnable() {
public void run() {
writeAudioDataToFile();
}
}, "AudioRecorder Thread");
recordingThread.start();
}
//convert short to byte
private byte[] short2byte(short[] sData) {
int shortArrsize = sData.length;
byte[] bytes = new byte[shortArrsize * 2];
for (int i = 0; i < shortArrsize; i++) {
bytes[i * 2] = (byte) (sData[i] & 0x00FF);
bytes[(i * 2) + 1] = (byte) (sData[i] >> 8);
sData[i] = 0;
}
return bytes;
}
private void writeAudioDataToFile() {
// Write the output audio in byte
String filePath = "/sdcard/voice8K16bitmono.pcm";
short sData[] = new short[BufferElements2Rec];
FileOutputStream os = null;
try {
os = new FileOutputStream(filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (isRecording) {
// gets the voice output from microphone to byte format
recorder.read(sData, 0, BufferElements2Rec);
System.out.println("Short wirting to file" + sData.toString());
try {
// // writes the data to file from buffer
// // stores the voice buffer
byte bData[] = short2byte(sData);
os.write(bData, 0, BufferElements2Rec * BytesPerElement);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void stopRecording() {
// stops the recording activity
if (null != recorder) {
isRecording = false;
recorder.stop();
recorder.release();
recorder = null;
recordingThread = null;
}
}
private View.OnClickListener btnClick = new View.OnClickListener() {
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStart: {
enableButtons(true);
startRecording();
break;
}
case R.id.btnStop: {
enableButtons(false);
stopRecording();
break;
}
}
}
};
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
finish();
}
return super.onKeyDown(keyCode, event);
}
}

Button.onTouch() not being called

I have a button btnSpeak which i find by ID, i then try to set the MotionEventListener
package com.ctc.android.widget;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Button;
import com.ctc.android.widget.ImageMap.Area;
public class ImageMapTestActivity extends Activity{
/********** Dan's Variables *********/
private static final String LOG_TAG = "AudioRecordTest";
private static String mFileName = null;
private MediaRecorder mRecorder = null;
private MediaPlayer mPlayer = null;
boolean isRecording = false;
boolean isStreaming = false;
private String hostIP = "192.168.0.14";
private static final int IDLE_EMPTY_BUFFER = 0;
private static final int IDLE_BUFFER_READY = 1;
private static final int RECORDING_STATE = 2;
private static final int PREVIEW_STATE = 3;
private static final int PLAYOUT_STATE = 4;
private int currentState = IDLE_EMPTY_BUFFER;
private static InetAddress multicastaddress = null;
private List<String> IPs = new ArrayList<String>();
private ArrayList<InetAddress> SelectedIPs = new ArrayList<InetAddress>();
private boolean listUpdated = false;
/********** ****** *********/
ImageMap mImageMap;
String strCoordinates;
int intSelectedAreaID;
Button btnPlaySiren;
// Button btnSpeak;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// find the image map in the view
mImageMap = (ImageMap)findViewById(R.id.map);
btnPlaySiren = (Button)findViewById(R.id.btnPlaySiren);
Button btnSpeak = (Button)findViewById(R.id.btnSpeak);
btnSpeak.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View v, MotionEvent event){
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
startStreamingRun();
break;
case MotionEvent.ACTION_UP:
stopStreamingRun();
break;
}
return true;
}
});
// add a click handler to react when areas are tapped
mImageMap.addOnImageMapClickedHandler(new ImageMap.OnImageMapClickedHandler() {
#Override
public void onImageMapClicked(int id) {
// when the area is tapped, show the name in a
// text bubble
intSelectedAreaID = id;
mImageMap.showBubble(id);
// TODO: Change colour of selected Area.
// TODO: Change state of selected Area.
}
#Override
public void onBubbleClicked(int id) {
// react to info bubble for area being tapped
}
});
// TODO: Set bitmap as Area decoration for each area added.
// TODO: Add an onClickListener for each area here.
ArrayList<Area> mAreas = mImageMap.GetAllAreas();
for(Area objArea : mAreas){
Bitmap objBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.remvox_green);
objArea.setBitmap(objBitmap);
Log.v("Area ID: :", Integer.toString(objArea._id)); // 07-30 14:40:05.409: V/Area ID: :(28449): 2131230738
} // End of for(Area...)
} // End of onCreate(Bundle ...)
public void btnPlaySirenClicked(View v){
if(v.getId() == R.id.btnPlaySiren){
Log.v("Siren Button Clicked", "Playing siren");
Thread thread = new Thread(new Runnable() {
public void run() {
playOverSocket(); // To resolve "Network on main thread" error!
}
});
thread.start();
}
}
private void playOverSocket() {
Log.e("AudioRecord", "Top of network play");
/*****
// Get the file we want to playback.
File file = new File("android.resource://com.ctc.android.widget.ImageMapTestActivity/res/raw/british"); // Do not add extension (file type)
File objSirenFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/reverseme.pcm");
// Get the length of the audio stored in the file (16 bit so 2 bytes per
// short)
// and create a short array to store the recorded audio.
int musicLength = (int) (file.length() / 2);
// short[] music = new short[musicLength];
* *****/
try {
// Create a DataInputStream to read the audio data back from the
// saved file.
InputStream is = getResources().openRawResource(R.raw.british);
//InputStream objSiren = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(is);
DataInputStream dis = new DataInputStream(bis);
Socket s = null;
try {
s = new Socket("192.168.1.101", 6666); // hostIP - Hard coded until implemented.
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedOutputStream buff = new BufferedOutputStream(
s.getOutputStream()); // out1 is the socket's outputStream
DataOutputStream dataOutputStreamInstance = new DataOutputStream(
buff);
// Read the file into the music array.
short lastByte = dis.readShort();
while(lastByte != -1)
{
dataOutputStreamInstance.writeChar(lastByte);
lastByte = dis.readShort();
}
dataOutputStreamInstance.flush();
dataOutputStreamInstance.close();
buff.flush();
buff.close();
s.close();
// Close the input streams.
dis.close();
} catch (Throwable t) {
Log.e("AudioTrack", "Playback Failed" + t.getMessage());
}
}
public void btnRecordClicked(View v){
//Button btnStopRecordToggle = (Button) findViewById(R.id.btnRecord);
if(v.getId() == R.id.btnRecord){
Log.v("Record Button Clicked", "Recording");
Thread thread = new Thread(new Runnable() {
public void run() {
record();
}
});
isRecording = true;
thread.start();
}
}
private void record() {
Log.v("AudioRecord", "Top of Record");
int frequency = 11025;
int channelConfiguration = AudioFormat.CHANNEL_IN_MONO;
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
File file = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/reverseme.pcm");
// Delete any previous recording.
if (file.exists())
file.delete();
// Create the new file.
try {
file.createNewFile();
} catch (IOException e) {
throw new IllegalStateException("Failed to create "
+ file.toString());
}
try {
// Create a DataOuputStream to write the audio data into the saved
// file.
OutputStream os = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(os);
DataOutputStream dos = new DataOutputStream(bos);
// Create a new AudioRecord object to record the audio.
int bufferSize = 8 * 1024;// AudioRecord.getMinBufferSize(frequency,
// channelConfiguration, audioEncoding);
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC, frequency,
channelConfiguration, audioEncoding, bufferSize);
short[] buffer = new short[2048];
audioRecord.startRecording();
while (isRecording) {
int bufferReadResult = audioRecord.read(buffer, 0, 2048);
for (int i = 0; i < bufferReadResult; i++)
dos.writeShort(buffer[i]);
}
audioRecord.stop();
dos.close();
Log.e("AudioRecord", "Recording Finished");
} catch (Throwable t) {
Log.e("AudioRecord", "Recording Failed");
Log.e("AudioRecord Error", t.getLocalizedMessage());
}
}
private void playRecordedOverSocket(InetAddress objAddress) {
Log.e("AudioRecord", "Top of network play recorded");
// Get the file we want to playback.
File file = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/reverseme.pcm");
// Get the length of the audio stored in the file (16 bit so 2 bytes per
// short)
// and create a short array to store the recorded audio.
int musicLength = (int) (file.length() / 2);
// short[] music = new short[musicLength];
try {
// Create a DataInputStream to read the audio data back from the
// saved file.
InputStream is = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(is);
DataInputStream dis = new DataInputStream(bis);
Socket s = new Socket(objAddress, 6666);
BufferedOutputStream buff = new BufferedOutputStream(
s.getOutputStream()); // out1 is the socket's outputStream
DataOutputStream dataOutputStreamInstance = new DataOutputStream(
buff);
// Read the file into the music array.
for (int i = 0; i < musicLength; i++) {
// music[i] =
dataOutputStreamInstance.writeChar(dis.readShort());
}
dataOutputStreamInstance.flush();
dataOutputStreamInstance.close();
buff.flush();
buff.close();
s.close();
// Close the input streams.
dis.close();
} catch (Throwable t) {
Log.e("AudioTrack", "Playback Failed" + t.getMessage());
}
}
public void btnRecordedMessageClicked(View v)
{
for(final InetAddress oneSpeaker : mImageMap.arrSelectedAddresses)
{
Thread thread = new Thread(new Runnable() {
public void run() {
playRecordedOverSocket(oneSpeaker);
}
});
thread.start();
}
}
public void btnStopClicked(View v)
{
isRecording = false;
}
public void btnSelectAllClicked(View v)
{
for(Area objOneArea : mImageMap.mAreaList)
{
objOneArea.blnIsSelected = false;
objOneArea.touched(SelectedIPs);
}
mImageMap.mBubbleMap.clear();
mImageMap.invalidate();
}
public void btnCallClicked(View v)
{
}
/*
*
* Multi-Cast Streaming implementation
*
*/
private void startStreamingRun() {
Thread thread = new Thread(new Runnable() {
public void run() {
doTestStream();
//doMCastStream();
}
});
// isStreaming = true;
thread.start();
}
private void stopStreamingRun() {
isStreaming = false;
}
private void doTestStream() {
int frequency = 11025;
int channelConfiguration = AudioFormat.CHANNEL_IN_MONO;
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
try {
// Create a DataOuputStream to write the audio data into the saved
// file.
Socket s = new Socket(hostIP, 6666);
BufferedOutputStream bos = new BufferedOutputStream(
s.getOutputStream()); // out1 is the socket's outputStream
DataOutputStream dos = new DataOutputStream(bos);
// Create a new AudioRecord object to record the audio.
int bufferSize = 8 * 1024;// AudioRecord.getMinBufferSize(frequency,
// channelConfiguration, audioEncoding);
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC, frequency,
channelConfiguration, audioEncoding, bufferSize);
//short[] buffer = new short[bufferSize];
byte[] buffer = new byte[bufferSize];
audioRecord.startRecording();
byte[] MiniBuff = new byte[2];
while (isStreaming) {
int bufferReadResult = audioRecord.read(buffer, 0, bufferSize);
for (int i = 0; i < bufferReadResult; i++) {
MiniBuff[1] = buffer[i];
i++;
MiniBuff[0] = buffer[i];
dos.write(MiniBuff);
}
/*
for (int i = 0; i < bufferReadResult; i++) {
short val=(short)( ((buffer[i+1]&0xFF)<<8) | (buffer[i]&0xFF) );
i++;
dos.writeShort(val);
}
*/
//dos.write(buffer[i]);
dos.flush();
}
dos.flush();
dos.close();
s.close();
// Close the input streams.
audioRecord.stop();
Log.e("AudioRecord", "Streaming Finished");
} catch (Throwable t) {
Log.e("AudioRecord", "Streaming Failed");
Log.e("AudioRecord Error", t.getLocalizedMessage());
}
}
} // End of class
This is done in the onCreate method of the activity, but when the activity runs and the button is touched, the event is never triggered and I can't see where I am going wrong. Not sure if its a case of not being able to see the wood for the trees.
I have copied your class, commenting the part of code i don't have relation (owner classes, own files...).
I made a test main.xml and everything works. Have you tried a "Project/Clean", maybe the ID from your btnSpeak is not updated
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button android:id="#+id/btnPlaySiren" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Siren" />
<Button android:id="#+id/btnSpeak" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Speak" />
<Button android:id="#+id/btnRecord" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Record" />
</LinearLayout>

Reading data from a microphone in android to process it online

I have a problem reading audiodata from microphone in android. My app must change lightness of a logo picture depending on volume of a sound, which I read from microphone. I use AudioRecord class to get audiodata. Depending on sample rate and buffer size, every 2nd/4th/8th read operation goes with latency of 100-200 ms. So my app can't react on volume changes properly. I tried to reduce buffer size, and to execute data processing in other thread (using AudioRecord.setPositionNotificationPeriod() and callback) but those not make much sense - latency just becomes a little shorter. Here is my code:
package com.mikesoft.Clown;
import android.app.Activity;
import android.media.AudioFormat;
import android.media.AudioRecord.OnRecordPositionUpdateListener;
import android.media.AudioRecord;
import android.media.MediaRecorder.AudioSource;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import java.lang.Math;
public class TestActivity extends Activity implements OnClickListener, OnRecordPositionUpdateListener {
private static final String LOG_TAG = TestActivity.class.getSimpleName();
//arrays for selecting usable audioformat
private static int[] mSampleRates = new int[] {8000, 11025, 22050, 44100};
private static short[] audioFormat = new short[] {AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT};
private static short[] channelConfig = new short[] {AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.CHANNEL_CONFIGURATION_STEREO};
private short[][] buffers;
private int ix;
private AudioRecord recorder = null;
private int bufferSize = 0;
private AudioThread recordingThread = null;
private boolean isRecording = false;
/** The OpenGL View */
private LogoView glSurface;
//markers
private short[] buffer;
private long read_time;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_test);
findViewById(R.id.btnStart).setOnClickListener(this);
findViewById(R.id.btnStop).setOnClickListener(this);
mVolumeText = (TextView)findViewById(R.id.volume);
setRecordMode();
glSurface = (LogoView)findViewById(R.id.glSurface);
}
private void setRecordMode() {
((Button) findViewById(R.id.btnStop)).setClickable(isRecording);
((Button) findViewById(R.id.btnStart)).setClickable(!isRecording);
}
public void startRecording() {
if (null == recorder) {
recorder = findAudioRecord();
recorder.setRecordPositionUpdateListener(this);
recorder.startRecording();
isRecording = true;
recordingThread = new AudioThread();
}
Log.d(LOG_TAG, "Audio recording started");
}
//thread for executing audio recorder
private class AudioThread extends Thread {
private AudioThread() {
start();
}
#Override
public void run() {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
recordAudio();
}
}
private void recordAudio() {
ix = 0;
int read = 0;
recorder.setPositionNotificationPeriod(bufferSize);
while (isRecording) {
//long t1 = System.currentTimeMillis();
buffer = buffers[ix++ % buffers.length];
read = recorder.read(buffer, 0, buffer.length);
//time after reading
//read_time = System.currentTimeMillis();
//Log.d(LOG_TAG, "read bytes: " + read);
//Log.d(LOG_TAG, "read_time=" + (read_time - t1));
//int vol = 0;
//for (int i=0;i<buffer.length;i++)
// vol = Math.max(vol, Math.abs(buffer[i]));
//float norm = (float)vol/(float)Short.MAX_VALUE;
//glSurface.setLightness(norm);
}
}
//initialize AudioRecord with suitable format
public AudioRecord findAudioRecord() {
//for (int rate : mSampleRates) {
int rate = 22050;
for (short format : audioFormat) {
for (short channel : channelConfig) {
try {
Log.d(LOG_TAG, "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: "
+ channelConfig);
bufferSize = AudioRecord.getMinBufferSize(rate, channel, format);
if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {
// check if we can instantiate and have a success
AudioRecord recorder = new AudioRecord(AudioSource.MIC, rate, channel, format, bufferSize);
//bufferSize/=8;
if (recorder.getState() == AudioRecord.STATE_INITIALIZED) {
buffers = new short[256][bufferSize];
return recorder;
}
}
} catch (Exception e) {
Log.e(LOG_TAG, rate + "Exception, keep trying.",e);
}
}
}
//}
return null;
}
public void stopRecording() {
if (null != recorder) {
isRecording = false;
recorder.stop();
recorder.release();
recorder = null;
recordingThread = null;
}
Log.d(LOG_TAG, "Audio recording stopped");
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStart:
startRecording();
setRecordMode();
break;
case R.id.btnStop:
stopRecording();
setRecordMode();
break;
default:
break;
}
}
#Override
public void onMarkerReached(AudioRecord arg0) {
// TODO Auto-generated method stub
}
#Override
public void onPeriodicNotification(AudioRecord arg0) {
float norm;
short[] buf = buffers[ix % buffers.length];
int vol = 0;
for (int i = 0; i < buf.length; i++)
vol = Math.max(vol, Math.abs(buf[i]));
norm = (float) vol / (float) Short.MAX_VALUE;
glSurface.setLightness(norm);
}
}
I tried devices&emulators with Android 1.6-3.2 but it's the same thing everywhere. Is there a solution for my problem in Java? Or I should use NDK approaches?
Will appreciate any help.

Categories

Resources