I want to play audio file from SD card with AudioTrack. I've tried with this code:
int minBufferSize = AudioTrack.getMinBufferSize(8000,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
int bufferSize = 512;
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 8000,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize,
AudioTrack.MODE_STREAM);
int i = 0;
byte[] s = new byte[bufferSize];
FileInputStream fin = new FileInputStream(path);
DataInputStream dis = new DataInputStream(fin);
at.play();
while ((i = dis.read(s, 0, bufferSize)) > -1)
{
at.write(s, 0, i);
}
at.stop();
at.release();
dis.close();
fin.close();
But it doesn't play audio file properly. Instead of original audio it plays some kind noise sound.
From the following link i have found that AudioTrack only plays PCM audio,
http://developer.android.com/guide/topics/media/index.html
And Please have a look on this code.
http://mindtherobot.com/blog/624/android-audio-play-an-mp3-file-on-an-audiotrack/
this is provided the information about how to Play an MP3 file on an AudioTrack.
Hope this helps u .
The AudioTrack class only supports PCM audio data, that's why you're hearing noise.
Use MediaPlayer or SoundPool if you want to play compressed audio files like .mp3 and .ogg.
Alternatively you could decode the compressed audio in your app and write the resulting PCM data to an AudioTrack, but that's a much bigger task.
Related
I'm working on Audio recorder app using AudioRecord not MediaRecorder.
I'm writing this code to record:
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 dataOutputStream = new DataOutputStream(bufferedOutputStream);
int minBufferSize = AudioRecord.getMinBufferSize(8000,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
short[] audioData = new short[minBufferSize];
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
8000,
AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT,
minBufferSize);
audioRecord.startRecording();
while(recording){
int numberOfShort = audioRecord.read(audioData, 0, minBufferSize);
for(int i = 0; i < numberOfShort; i++){
dataOutputStream.writeShort(audioData[i]);
}
}
audioRecord.stop();
dataOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
It's working fine. but, i have a large file size. I recorded about 1 min and i had file with size about 1.2M.
I tried to use MediaRecorder using this code:
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setOutputFile(fileName);
mMediaRecorder.prepare();
mMediaRecorder.start();
It's great and recorded 5 minutes with file size about 500K or less. But, i have to use AudioRecord because i need to apply some task on audio byte by byte.
Can i have the same file size in MediaRecorder when i use AudioRecord?
Thank you very much.
Actually with AudioRecord class you get raw data from sound source without any compression to byte buffer you work with and MediaRecorder class provides only basic functionality for recording media from any available sources without direct access to data buffers.
I assume you should use AudioRecord for capturing audio, apply your byte to byte task for data in AudioRecord buffer and then write modified data from buffer using compression to a file. As I remember, there is no already implemented functionality in android API for audio compression, so you should use third-party library (for example lame) or write compression yourself. You can check this sources for audio recording in MP3 with lame: https://github.com/yhirano/Mp3VoiceRecorderSampleForAndroid
Iam trying to develop an application where i can set the speed of music file(mp3) to be set like 1x,1.5x,2x,2.5x like this.but MediaPlayer does not support this feauture unless it is 23 api.How can i use AudioTrack to play this mp3 file and also seek to position.the below code gives me "zzzzzzz" sound.
public void playAudio(){
int minBufferSize = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
int bufferSize = 512;
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
String filepath = Environment.getExternalStorageDirectory().getAbsolutePath();
int i = 0;
byte[] s = new byte[bufferSize];
try {
final String path= Environment.getExternalStorageDirectory().getAbsolutePath() + "/folioreader/audio"+".mp3";
FileInputStream fin = new FileInputStream(path);
DataInputStream dis = new DataInputStream(fin);
audioTrack.play();
while((i = dis.read(s, 0, bufferSize)) > -1){
audioTrack.write(s, 0, i);
}
audioTrack.stop();
audioTrack.release();
dis.close();
fin.close();
} catch (FileNotFoundException e) {
// TODO
e.printStackTrace();
} catch (IOException e) {
// TODO
e.printStackTrace();
}
}
AudioTrack can play uncompressed audio (WAV) not any compressed ones (mp3 or AAC etc.,) You need to call MediaCodec to decode and then use Audio Track to play audio. Refer these links, https://developer.android.com/reference/android/media/AudioTrack.html and https://developer.android.com/reference/android/media/MediaCodec.html.
For faster playback, give sample rate proportional to the speed that you require. For ex. to play 8kHz audio in 2X rate, give 16kHz in AudioTrack and so on. This is crude way.
int minSize =AudioTrack.getMinBufferSize( 45100, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT );
track = new AudioTrack( AudioManager.STREAM_MUSIC,45100 ,
AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT,
minSize, AudioTrack.MODE_STREAM);
track.setStereoVolume(1f,1f);
while(true)
{
Log.e(""," sizewe are using for track buffer is "+minSize);
int i = 0; // Read the file into the "music" array
music=new short[4188];
while (dis.available() > 0)
{
music[i] = dis.readShort();
i++;
if(i==4188)
break;
}
Log.e("","music lengh= "+music.length+" and dis.available="+dis.available());
track.play();
track.write(music,0, music.length);
track.flush();
track.stop();
}
could some one tell me how to decode sound when we playing a large mp3 file in audiotrack using bytebuffer ,i want to decode it in real time when playing the song .. here i am getting song from .aiff file which is a pcm format
first: i want to play a mp3 file by audiotrack class
second: .wav is also a pcm file but it is not playing.
thanks in advance
I am trying to play a mono sound through a single channel, the only thing I can think of is interweaving a second channel into the byte array, changing AudioFormat to stereo then calling
audioTrack.setStereoVolume(leftVolume, rightVolume); to set one channel's volume to zero. Is there a simpler way?
Playback:
AudioTrack audioTrack = null; // Get audio track
try {
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
sampleRate, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, (int)numSamples*2,
AudioTrack.MODE_STATIC);
audioTrack.write(generatedSnd, 0, generatedSnd.length); // Load the track
audioTrack.play(); // Play the track
}
catch (Exception e){ }
I am trying to play the bigger size audio wav file(which is >20 mb) using the following code(AudioTrack) on my Android 1.6 HTC device which basically has less memory. But i found device crash as soon as it executes reading, writing and play. But the same code works fine and plays the lesser size audio wav files(10kb, 20 kb files etc) very well.
P.S: I should play PCM(.wav) buffer sound, the reason behind why i use AudioTrack here.
Though my device has lesser memory, how would i read bigger audio files bytes by bytes and play the sound to avoid crashing due to memory constraints.
private void AudioTrackPlayPCM() throws IOException
{
String filePath = "/sdcard/myWav.wav"; // 8 kb file
byte[] byteData = null;
File file = null;
file = new File(filePath);
byteData = new byte[(int) file.length()];
FileInputStream in = null;
try {
in = new FileInputStream( file );
in.read( byteData );
in.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int intSize = android.media.AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_8BIT);
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_8BIT, intSize, AudioTrack.MODE_STREAM);
at.play();
at.write(byteData, 0, byteData.length);
at.stop();
at.release();
}
Could someone guide me please to play the AudioTrack code for bigger size wav files?
Your intSize will be the minimum buffer size needed to init the AudioTrack, try using a multiple of this to create a bigger buffer
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 8000,
AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_8BIT, intSize*10,
AudioTrack.MODE_STREAM);