I want to record Audio in mp3 format using MIC in android.
I try to record below code,
but when i check sdcard ( path: sdcard/recording.mp3), the file does not work.
(the file size is 0kb).
How can i record Mic audio in android in mp3 or wav format.
please, help.
private final int FREQUENCY = 11025;
private final int CUSTOM_FREQ_SOAP = 1;
private final int OUT_FREQUENCY = FREQUENCY * CUSTOM_FREQ_SOAP;
private final int CHANNEL_CONTIGURATION = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private final int AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
======
try {
mRecordingFile = File.createTempFile("recording", ".mp3", new File("/sdcard/"));
} catch (IOException e) {
throw new RuntimeException("Couldn't create file on SD card", e);
}
======
private class RecordAudio extends AsyncTask<Void, Integer, Void> {
#Override
protected Void doInBackground(Void... params) {
isRecording = true;
try {
DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(
mRecordingFile, true)));
int bufferSize = AudioRecord.getMinBufferSize(FREQUENCY,
CHANNEL_CONTIGURATION, AUDIO_ENCODING);
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC, FREQUENCY,
CHANNEL_CONTIGURATION, AUDIO_ENCODING, bufferSize);
short[] buffer = new short[bufferSize];
audioRecord.startRecording();
while (isRecording) {
int bufferReadResult = audioRecord.read(buffer, 0,
bufferSize);
int amplitude = 0;
for (int i = 0; i < bufferReadResult; i++) {
dos.writeShort(buffer[i]);
amplitude += Math.abs((int) buffer[i]);
}
final int amp = amplitude;
}
audioRecord.stop();
//dos.close();
} catch (Throwable t) {
}
return null;
}
public void recordAudio(String fileName) {
final MediaRecorder recorder = new MediaRecorder();
ContentValues values = new ContentValues(3);
values.put(MediaStore.MediaColumns.TITLE, fileName);
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setOutputFile("/sdcard/sound/" + fileName);
try {
recorder.prepare();
} catch (Exception e){
e.printStackTrace();
}
final ProgressDialog mProgressDialog = new ProgressDialog(MyActivity.this);
mProgressDialog.setTitle(R.string.lbl_recording);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressDialog.setButton("Stop recording", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
mProgressDialog.dismiss();
recorder.stop();
recorder.release();
}
});
mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener(){
public void onCancel(DialogInterface p1) {
recorder.stop();
recorder.release();
}
});
recorder.start();
mProgressDialog.show();
}
Related
I am getting PCM streams through ethernet port. So far, I am able to capture the packets and takeout the pcm_payload data from them.
How to play this raw PCM data in android? The PCM data is 16-bit 2 channel, 44.1kHZ rate stream.
I am both new to android application programming and audio programming. Sorry if this is a trivial question.
You can use AudioTrack to play PCM data!
Maybe like this:
int bufsize = AudioTrack.getMinBufferSize(44100,
AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
AudioTrack audio = new AudioTrack(AudioManager.STREAM_MUSIC,
44100, //sample rate
AudioFormat.CHANNEL_OUT_STEREO, //2 channel
AudioFormat.ENCODING_PCM_16BIT, // 16-bit
bufsize,
AudioTrack.MODE_STREAM );
audio.play()
then invoke audio.write() to write your PCM data.
it's my sollution. write stream to file and play it
public class AudioTrackPlayer {
private String pathAudio;
private AudioTrack audioPlayer;
private Thread mThread;
private int bytesread = 0, ret = 0;
private int size;
private FileInputStream in = null;
private byte[] byteData = null;
private int count = 512 * 1024; // 512 kb
private boolean isPlay = true;
private boolean isLooping = false;
private static Handler mHandler;
public AudioTrackPlayer() {
}
public void prepare(String pathAudio){
this.pathAudio = pathAudio;
mHandler = new Handler();
}
public void play(){
stop();
isPlay = true;
bytesread = 0;
ret = 0;
if (pathAudio == null)
return;
audioPlayer = createAudioPlayer();
if (audioPlayer == null) return;
audioPlayer.play();
mThread = new Thread(new PlayerProcess());
mThread.start();
}
private final Runnable mLopingRunnable = new Runnable() {
#Override
public void run() {
play();
}
};
private AudioTrack createAudioPlayer(){
int intSize = android.media.AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO,
AudioFormat.ENCODING_PCM_16BIT, intSize, AudioTrack.MODE_STREAM);
if (audioTrack == null) {
Log.d("TCAudio", "audio track is not initialised ");
return null;
}
File file = null;
file = new File(pathAudio);
byteData = new byte[(int) count];
try {
in = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
size = (int) file.length();
return audioTrack;
}
private class PlayerProcess implements Runnable{
#Override
public void run() {
while (bytesread < size && isPlay) {
if (Thread.currentThread().isInterrupted()) {
break;
}
try {
ret = in.read(byteData, 0, count);
} catch (IOException e) {
e.printStackTrace();
}
if (ret != -1) { // Write the byte array to the track
audioPlayer.write(byteData,0, ret);
bytesread += ret;
} else break;
}
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
if (audioPlayer!=null){
if (audioPlayer.getState()!=AudioTrack.PLAYSTATE_STOPPED){
audioPlayer.stop();
audioPlayer.release();
mThread = null;
}
}
if (isLooping && isPlay ) mHandler.postDelayed(mLopingRunnable,100);
}
}
public void setLooping(){
isLooping = !isLooping;
}
public void pause(){
}
public void stop(){
isPlay = false;
if (mThread != null) {
mThread.interrupt();
mThread = null;
}
if (audioPlayer != null) {
audioPlayer.stop();
audioPlayer.release();
audioPlayer = null;
}
}
public void reset(){
}
}
I am developing an Android app. In my app I need to record audio using AudionRecord and need to play it. But throwing error when play the recorded pcm file. The main problem is I cannot log know the error as well because I have to test on real device and cannot run on emulator. Because when I run on emulator and record, my application crash.
This is my activity
public class MainActivity extends AppCompatActivity {
Boolean recording;
private Thread recordingThread = null;
DataOutputStream dataOutputStream;
short[] audioData;
private Button btnPlay,btnStop,btnRecord;
private String outputFile = null;
//outputFile = Environment.getExternalStorageDirectory().getAbsolutePath()+"/recording.3gp";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initialize();
initViews();
setUpViews();
}
private void initialize()
{
}
private void initViews()
{
btnPlay = (Button)findViewById(R.id.btn_play);
btnRecord = (Button)findViewById(R.id.btn_record);
btnStop = (Button)findViewById(R.id.btn_stop);
}
private void setUpViews()
{
btnRecord.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startRecord();
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
recording = false;
Toast.makeText(getBaseContext(),"Stopped",Toast.LENGTH_SHORT).show();
}
});
btnPlay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playRecord();
}
});
}
private void startRecord(){
File file = new File(Environment.getExternalStorageDirectory(), "test.pcm");
try {
file.createNewFile();
OutputStream outputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
dataOutputStream = new DataOutputStream(bufferedOutputStream);
final int minBufferSize = AudioRecord.getMinBufferSize(11025,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
audioData = new short[minBufferSize];
final AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
11025,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
minBufferSize);
audioRecord.startRecording();
Toast.makeText(getBaseContext(),"Recording",Toast.LENGTH_SHORT).show();
recordingThread = new Thread(new Runnable() {
public void run() {
while(recording){
int numberOfShort = audioRecord.read(audioData, 0, minBufferSize);
for(int i = 0; i < numberOfShort; i++){
try{
dataOutputStream.writeShort(audioData[i]);
}
catch (IOException e)
{
Toast.makeText(getBaseContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
}
}
}
}, "AudioRecorder Thread");
audioRecord.stop();
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void playRecord(){
File file = new File(Environment.getExternalStorageDirectory(), "test.pcm");
int shortSizeInBytes = Short.SIZE/Byte.SIZE;
int bufferSizeInBytes = (int)(file.length()/shortSizeInBytes);
short[] audioData = new short[bufferSizeInBytes];
try {
InputStream inputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
DataInputStream dataInputStream = new DataInputStream(bufferedInputStream);
int i = 0;
while(dataInputStream.available() > 0){
audioData[i] = dataInputStream.readShort();
i++;
}
dataInputStream.close();
AudioTrack audioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC,
11025,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSizeInBytes,
AudioTrack.MODE_STREAM);
audioTrack.play();
audioTrack.write(audioData, 0, bufferSizeInBytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The problem is with playing the recorded pcm. When I click play button, application throws fatal error and stopped. I cannot log the error as well. The pcm file really exists at the defined path as well. What is wrong with my code? Why can it not play?
As you can see below, pcm file created successfully after recording
Without seeing the Logcat, it is hard to figure the issue in your code. Take a look at this working code on 'How to play pcm files using AudioTrack':
private void PlayAudioFileViaAudioTrack(String filePath) throws IOException
{
// We keep temporarily filePath globally as we have only two sample sounds now..
if (filePath==null)
return;
int intSize = android.media.AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT, intSize, AudioTrack.MODE_STREAM);
if (at==null){
Log.d("TCAudio", "audio track is not initialised ");
return;
}
int count = 512 * 1024; // 512 kb
//Reading the file..
byte[] byteData = null;
File file = null;
file = new File(filePath);
byteData = new byte[(int)count];
FileInputStream in = null;
try {
in = new FileInputStream( file );
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int bytesread = 0, ret = 0;
int size = (int) file.length();
at.play();
while (bytesread < size) {
ret = in.read( byteData,0, count);
if (ret != -1) { // Write the byte array to the track
at.write(byteData,0, ret);
bytesread += ret;
}
else break;
}
in.close();
at.stop();
at.release();
}
code from http://jongladwin.blogspot.co.uk/2010/03/android-play-pcmwav-audio-buffer-using.html
Am developing an android app that has the feature to record the user speech. For this I have used the AndroidRecord Audio API.
Currently the pcm file(recorded audio file - recordedAudio.pcm) getting generated successfully in the sd card. But am not able to play that file. I tried in PC also with windows media palyer and some other players. But nothing helps.
Following are my code snippet.
private int minBufSize;
private AudioRecord recorder;
private int sampleRate = 44100;
private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
private boolean status;
minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig,
audioFormat);
status = true;
startStreaming();
public void startStreaming() {
Thread streamThread = new Thread(new Runnable() {
#Override
public void run() {
try {
String filePath = Environment.getExternalStorageDirectory()
.getPath() + "/audioRecord.pcm";
FileOutputStream fileOutputStreamObj = null;
try {
fileOutputStreamObj = new FileOutputStream(filePath);
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.e(TAG, "Exception" + e.getMessage());
}
// short[] sData = new short[minBufSize];
byte[] buffer = new byte[minBufSize];
// recorder = findAudioRecord();
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
sampleRate, channelConfig, audioFormat, minBufSize);
Log.d(TAG, "Recorder initialized");
recorder.startRecording();
while (status) {
// reading data from MIC into buffer
minBufSize = recorder.read(buffer, 0, buffer.length);
try {
// writes the data to file from buffer
// stores the voice buffer
// byte bData[] = short2byte(sData);
fileOutputStreamObj.write(buffer, 0, buffer.length);
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, "Exception" + e.getMessage());
}
// mConnection.sendBinaryMessage(buffer);
System.out.println("MinBufferSize: " + minBufSize);
}
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Exception" + e.getMessage());
}
}
});
streamThread.start();
}
Please help me on this. Thanks in advance.
You don't have to convert it into WAV and Play.
AudioTrack can directly play the recorded Audio.
Following is a Code snippet to Record audio into a file using AudioRecord and playback the same using AudioTrack API.
The operation is controlled from User using Buttons.
Code
private int BufferSize;
byte[] buffer = new byte[BufferSize];
/* AudioRecord and AudioTrack Object */
private AudioRecord record = null;
private AudioTrack track = null;
/* Audio Configuration */
private int sampleRate = 44100;
private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
private boolean isRecording = true;
private Thread recordingThread = null;
The Audio Configuration can change as per device.
Refer to this question.
GUI has three buttons, Record, Stop and Play
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setButtonHandlers();
/* Set Button Visibility */
enableButton(R.id.btnStartRec,true);
enableButton(R.id.btnStopRec,false);
enableButton(R.id.btnStartPlay,false);
BufferSize = AudioRecord.getMinBufferSize(sampleRate,
channelConfig, audioFormat);
}
/* Function to Enable/Disable Buttons */
private void enableButton(int id,boolean isEnable){
((Button)findViewById(id)).setEnabled(isEnable);
}
/* Assign OnClickListener to Buttons */
private void setButtonHandlers() {
((Button)findViewById(R.id.btnStartRec)).setOnClickListener(btnClick);
((Button)findViewById(R.id.btnStopRec)).setOnClickListener(btnClick);
((Button)findViewById(R.id.btnStartPlay)).setOnClickListener(btnClick);
}
Handling Button click:
private View.OnClickListener btnClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btnStartRec:{
Log.d(TAG, "Start Recording");
enableButton(R.id.btnStartRec,false);
enableButton(R.id.btnStopRec,true);
startRecording();
break;
}
case R.id.btnStopRec:{
Log.d(TAG, "Stop Recording");
enableButton(R.id.btnStartRec,true);
enableButton(R.id.btnStopRec,false);
stopRecording();
enableButton(R.id.btnStartPlay,true);
break;
}
case R.id.btnStartPlay:{
Log.d(TAG, "Play Recording");
enableButton(R.id.btnStartRec,false);
enableButton(R.id.btnStopRec,false);
StartPlaying();
break;
}
}
}
};
Code for Start Recording
private void startRecording()
{
record = new AudioRecord(AudioSource.DEFAULT, sampleRate,
channelConfig, audioFormat, BufferSize);
if (AudioRecord.STATE_INITIALIZED == record.getState())
record.startRecording();
isRecording = true;
/* Run a thread for Recording */
recordingThread = new Thread(new Runnable() {
#Override
public void run() {
writeAudioDataToFile();
}
},"AudioRecorder Thread");
recordingThread.start();
}
private void writeAudioDataToFile()
{
byte data[] = new byte[BufferSize];
/* Record audio to following file */
String filename = "/sdcard/audiofile.pcm";
FileOutputStream os = null;
try {
os = new FileOutputStream(filename);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
int read_bytes = 0;
if(null != os){
while(isRecording)
{
read_bytes = record.read(data, 0, BufferSize);
if(AudioRecord.ERROR_INVALID_OPERATION != read_bytes){
try {
os.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Code for Stop Recording
private void stopRecording()
{
if(null != record)
{
isRecording = false;
if (AudioRecord.STATE_INITIALIZED == record.getState())
{
record.stop();
record.release();
Log.d(TAG, "===== Recording Audio Completed ===== ");
}
record = null;
recordingThread = null;
}
}
Code for Playing the Audio file:
public void startPlaying()
{
enableButton(R.id.btnStartPlay,false);
int minBufferSize = AudioTrack.getMinBufferSize(sampleRate,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
track = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize,
AudioTrack.MODE_STREAM);
int i = 0;
byte[] temp = new byte[minBufferSize];
try {
FileInputStream fin = new FileInputStream("/sdcard/audiofile.pcm");
Log.d(TAG, "===== Opening File for Playing : /sdcard/audiofile.pcm ===== ");
DataInputStream dis = new DataInputStream(fin);
track.play();
while((i = dis.read(temp, 0, minBufferSize)) > -1)
{
track.write(temp, 0, i);
}
Log.d(TAG, "===== Playing Audio Completed ===== ");
track.stop();
track.release();
dis.close();
fin.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
enableButton(R.id.btnStartRec,true);
}
Please include the following in AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" > </uses-permission>
<uses-permission android:name="android.permission.RECORD_AUDIO" > </uses-permission>
The activity_main.xml looks like this.
The string.xml looks like this.
The above code is working and tested.
You can also do the same, without a file and using a intermediate buffer.
See: Audio Recording and Streaming in Android
Yes finally I found the answer with the clue of Michael's Comment above.
Am posting here the working code.
The Client Side Code as Follow's,
From the client side am streaming the audio data to the web socket server.
private int minBufSize;
private AudioRecord recorder;
private int sampleRate = 44100;
private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
minBufSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig,
audioFormat);
startStreaming();
public void startStreaming() {
Thread streamThread = new Thread(new Runnable() {
#Override
public void run() {
try {
byte[] buffer = new byte[minBufSize];
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
sampleRate, channelConfig, audioFormat, minBufSize);
Log.d(TAG, "Recorder initialized");
recorder.startRecording();
while (status) {
// reading data from MIC into buffer
minBufSize = recorder.read(buffer, 0, buffer.length);
mConnection.sendBinaryMessage(buffer);
System.out.println("MinBufferSize: " + minBufSize);
}
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "Exception" + e.getMessage());
}
}
});
streamThread.start();
}
The Server Side Code added implementation as follows,
First the server will create the .pcm from the streamed data. Then from that pcm file it will create the wave file by adding header.
#OnMessage
public void onMessage(byte[] data, boolean arg1)
{
if ((!this.currentCommand.equals("stop")) &&
(this.currentCommand.equals("start")))
try {
System.out.println("Starting new recording.");
FileOutputStream fOut = new FileOutputStream(this.f2, true);
fOut.write(data);
fOut.close();
properWAV(this.f2, 111133.0F);
}
catch (Exception e) {
e.printStackTrace();
}
}
private void properWAV(File fileToConvert, float newRecordingID)
{
try {
long mySubChunk1Size = 16L;
int myBitsPerSample = 16;
int myFormat = 1;
long myChannels = 1L;
long mySampleRate = 44100L;
long myByteRate = mySampleRate * myChannels * myBitsPerSample / 8L;
int myBlockAlign = (int)(myChannels * myBitsPerSample / 8L);
byte[] clipData = getBytesFromFile(fileToConvert);
long myDataSize = clipData.length;
long myChunk2Size = myDataSize * myChannels * myBitsPerSample / 8L;
long myChunkSize = 36L + myChunk2Size;
OutputStream os = new FileOutputStream(new File("D:/audio/" + newRecordingID + ".wav"));
BufferedOutputStream bos = new BufferedOutputStream(os);
DataOutputStream outFile = new DataOutputStream(bos);
outFile.writeBytes("RIFF");
outFile.write(intToByteArray((int)myChunkSize), 0, 4);
outFile.writeBytes("WAVE");
outFile.writeBytes("fmt ");
outFile.write(intToByteArray((int)mySubChunk1Size), 0, 4);
outFile.write(shortToByteArray((short)myFormat), 0, 2);
outFile.write(shortToByteArray((short)(int)myChannels), 0, 2);
outFile.write(intToByteArray((int)mySampleRate), 0, 4);
outFile.write(intToByteArray((int)myByteRate), 0, 4);
outFile.write(shortToByteArray((short)myBlockAlign), 0, 2);
outFile.write(shortToByteArray((short)myBitsPerSample), 0, 2);
outFile.writeBytes("data");
outFile.write(intToByteArray((int)myDataSize), 0, 4);
outFile.write(clipData);
outFile.flush();
outFile.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
private static byte[] intToByteArray(int i)
{
byte[] b = new byte[4];
b[0] = (byte)(i & 0xFF);
b[1] = (byte)(i >> 8 & 0xFF);
b[2] = (byte)(i >> 16 & 0xFF);
b[3] = (byte)(i >> 24 & 0xFF);
return b;
}
public static byte[] shortToByteArray(short data)
{
return new byte[] { (byte)(data & 0xFF), (byte)(data >>> 8 & 0xFF) };
}
public byte[] getBytesFromFile(File file)
throws IOException
{
byte[] buffer = new byte[(int)file.length()];
InputStream ios = null;
try {
ios = new FileInputStream(file);
if (ios.read(buffer) == -1)
throw new IOException("EOF reached while trying to read the whole file");
}
finally {
try {
if (ios != null)
ios.close();
}
catch (IOException localIOException)
{
}
}
try
{
if (ios != null)
ios.close();
}
catch (IOException localIOException1)
{
}
return buffer;
}
Hope this one saves many of the developer's time.
I am developing an android application that records through MIC and changes its frequency. Similar to Helium booth app for iphone. For the time being i have written code to record a file and save it in sdcard. I am getting an error which says:
Could not get audio input for record source 1
Error creating AudioRecord instance: initialization check failed.
[ android.media.AudioRecord ] Error code -20 when initializing native
FATAL EXCEPTION: Thread-10
java.lang.IllegalStateException: startRecording() called on an uninitialized
Following is my code:
public class MainActivity extends Activity {
Integer[] freqset = {8000};
private ArrayAdapter<Integer> adapter;
Spinner spFrequency;
Button startRec, stopRec, playBack;
Boolean recording;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startRec = (Button)findViewById(R.id.startrec);
stopRec = (Button)findViewById(R.id.stoprec);
playBack = (Button)findViewById(R.id.playback);
startRec.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Thread recordThread = new Thread(new Runnable(){
#Override
public void run() {
recording = true;
startRecord();
}
});
recordThread.start();
}
});
stopRec.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
recording = false;
}
});
playBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
playRecord();
}
});
spFrequency = (Spinner)findViewById(R.id.frequency);
adapter = new ArrayAdapter<Integer>(this, android.R.layout.simple_spinner_item, freqset);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spFrequency.setAdapter(adapter);
}
private void startRecord(){
File file = new File(Environment.getExternalStorageDirectory(), "test.pcm");
int BytesPerElement = 2;
int sampleFreq = (Integer)spFrequency.getSelectedItem();
Log.e("Test","Start Recording"+sampleFreq);
try {
file.createNewFile();
OutputStream outputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);
int minBufferSize = AudioRecord.getMinBufferSize(sampleFreq,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
Log.i("Test","Buffer Size is"+minBufferSize);
short[] audioData = new short[minBufferSize];
Log.i("Test","audioData initialized"+audioData);
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
sampleFreq,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
minBufferSize*BytesPerElement);
Log.i("Test","audioRecord initialized"+audioRecord);
audioRecord.startRecording();
while(recording){
int numberOfShort = audioRecord.read(audioData, 0, minBufferSize);
for(int i = 0; i < numberOfShort; i++){
dataOutputStream.writeShort(audioData[i]);
Log.i("Test","Recording buzzz");
}
}
audioRecord.stop();
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
Log.e("Testing", "Esception Found");
}
}
void playRecord(){
File file = new File(Environment.getExternalStorageDirectory(), "test.pcm");
int shortSizeInBytes = Short.SIZE/Byte.SIZE;
int bufferSizeInBytes = (int)(file.length()/shortSizeInBytes);
short[] audioData = new short[bufferSizeInBytes];
try {
InputStream inputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
DataInputStream dataInputStream = new DataInputStream(bufferedInputStream);
int i = 0;
while(dataInputStream.available() > 0){
audioData[i] = dataInputStream.readShort();
i++;
}
dataInputStream.close();
int sampleFreq = (Integer)spFrequency.getSelectedItem();
AudioTrack audioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC,
sampleFreq,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSizeInBytes,
AudioTrack.MODE_STREAM);
audioTrack.play();
audioTrack.write(audioData, 0, bufferSizeInBytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}}
P.S I asked similar question earlier but i used MediaRecorder. Here i am using AudioRecord class now.
I am developing a sound recording app for android. The problem I am facing is that I want to know when the sound file that is being played finishes and I do not know how to check. There is setOnCompleteListener for MediaRecorder class but I am using AudioRecorder class because I need to do some editing while recording too, like change in frequency and pitch of the speaker.
Following is my code:
public class MainActivity extends Activity {
Integer[] freqset = {8000};
private ArrayAdapter<Integer> adapter;
Spinner spFrequency;
Button startRec, stopRec, playBack;
Boolean recording;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startRec = (Button)findViewById(R.id.startrec);
stopRec = (Button)findViewById(R.id.stoprec);
playBack = (Button)findViewById(R.id.playback);
startRec.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Thread recordThread = new Thread(new Runnable(){
#Override
public void run() {
recording = true;
startRecord();
}
});
recordThread.start();
}
});
stopRec.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
recording = false;
}
});
playBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("Test","Play Record called");playRecord();
}
});
spFrequency = (Spinner)findViewById(R.id.frequency);
adapter = new ArrayAdapter<Integer>(this, android.R.layout.simple_spinner_item, freqset);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spFrequency.setAdapter(adapter);
}
private void startRecord(){
File file = new File(Environment.getExternalStorageDirectory(), "test.pcm");
int BytesPerElement = 2;
int sampleFreq = (Integer)spFrequency.getSelectedItem();
Log.e("Test","Start Recording"+sampleFreq);
try {
file.createNewFile();
OutputStream outputStream = new FileOutputStream(file);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);
int minBufferSize = AudioRecord.getMinBufferSize(sampleFreq,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT);
Log.i("Test","Buffer Size is"+minBufferSize);
short[] audioData = new short[minBufferSize];
Log.i("Test","audioData initialized"+audioData);
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
sampleFreq,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
minBufferSize*BytesPerElement);
Log.i("Test","audioRecord initialized"+audioRecord);
audioRecord.startRecording();
while(recording){
int numberOfShort = audioRecord.read(audioData, 0, minBufferSize);
for(int i = 0; i < numberOfShort; i++){
dataOutputStream.writeShort(audioData[i]);
Log.i("Test","Recording buzzz"+recording);
}
}
Log.i("Test","Recording Value after stop"+recording);
audioRecord.stop();
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
Log.e("Testing", "Esception Found");
}
}
void playRecord(){
File file = new File(Environment.getExternalStorageDirectory(), "test.pcm");
int shortSizeInBytes = Short.SIZE/Byte.SIZE;
int bufferSizeInBytes = (int)(file.length()/shortSizeInBytes);
short[] audioData = new short[bufferSizeInBytes];
try {
InputStream inputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
DataInputStream dataInputStream = new DataInputStream(bufferedInputStream);
int i = 0;
while(dataInputStream.available() > 0){
audioData[i] = dataInputStream.readShort();
i++;
}
dataInputStream.close();
int sampleFreq = (Integer)spFrequency.getSelectedItem();
Log.i("Test","Sab set hai");
AudioTrack audioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC,
sampleFreq,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSizeInBytes,
AudioTrack.MODE_STREAM);
Log.i("Test","will start play");
audioTrack.play();
audioTrack.write(audioData, 0, bufferSizeInBytes);
Log.i("Test","does this print");
} catch (FileNotFoundException e) {
Log.i("Test","Ye wali exception");
e.printStackTrace();
} catch (IOException e) {
Log.i("Test"," Ni Ye wali exception");
e.printStackTrace();
}
}}
you can use AudioTrack.OnPlaybackPositionUpdateListener and AudioTrack.setNotificationMarkerPosition to known Audio playing is finished or not as :
AudioTrack audioTrack = new AudioTrack(
AudioManager.STREAM_MUSIC,
sampleFreq,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSizeInBytes,
AudioTrack.MODE_STREAM);
// set setNotificationMarkerPosition accouding audio length
audioTrack.setNotificationMarkerPosition(bufferSizeInBytes);
// now add OnPlaybackPositionUpdateListener to audioTrack
audioTrack.setPlaybackPositionUpdateListener(
new AudioTrack.OnPlaybackPositionUpdateListener() {
#Override
public void onMarkerReached(AudioTrack track) {
// do your work here....
}
});