I am trying to play a PCM file which was created while recording audio from the microphone.
I am using AudioRecord because I want to analyse the frequency of the sound which is recorded by the microphone.
The snippet of code which plays the PCM file is as below. But when I tried to play the file, there is a heavy noise which is being played.
FileInputStream fis=null;
File l=null;
l=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Notate/f1.pcm");
byte[] buffer=new byte[(int)l.length()];
try {
fis = new FileInputStream(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Notate/f1.pcm");
fis.read(buffer);
}
catch(Exception e)
{
}
int intSize = android.media.AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, intSize, AudioTrack.MODE_STREAM);
if (at!=null) {
at.play();
at.write(buffer, 0, buffer.length);
at.stop();
at.release();
}
The code which is used to store the PCM file is below.
private class RecordAudio extends AsyncTask<Void, Double, Void> {
FileOutputStream os = null;
BufferedOutputStream bos =null;
DataOutputStream dos = null;
#Override
protected Void doInBackground(Void... params) {
int bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioEncoding); // Gets the minimum buffer needed
AudioRecord audioRecord = new AudioRecord(audioSource, sampleRate, channelConfig, audioEncoding, bufferSize); // The RAW PCM sample recording
File f=new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/Notate/");
if(!f.isDirectory()) {
File newDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Notate/");
newDirectory.mkdirs();
}
String filepath=Environment.getExternalStorageDirectory().getAbsolutePath()+"/Notate/f1.pcm";
short[] buffer = new short[blockSize]; // Save the raw PCM samples as short bytes
try{
os=new FileOutputStream(filepath);
}
catch(FileNotFoundException e)
{
}
bos = new BufferedOutputStream(os);
dos = new DataOutputStream(bos);
try {
audioRecord.startRecording(); //Start
} catch (Throwable t) {
}
while (started) {
int length=audioRecord.read(buffer, 0, blockSize);
Yin alpha = new Yin(44100, 1024, 0.2);
float[] floaters = new float[buffer.length];
for (int i = 0; i < buffer.length; i++) {
floaters[i] = buffer[i];
}
for(int k=0;k<length;k++) {
try {
dos.writeShort(buffer[k]);
} catch (IOException e) {
}
}
float result = alpha.getPitch(floaters);
publishProgress((double) result);
}
try{
dos.close();
}
catch(IOException e){
e.printStackTrace();
}
return null;
}
writeShort writes the values in a big-endian layout, i.e. the most significant byte first, while AudioTrack probably expects the samples to be little-endian (least significant byte first).
You'd make things simpler for yourself if you used a byte[] instead of a short[] when recording. Then you can simply write to your DataOutputStream with dos.write(buffer, 0, length);. Your conversion to floating-point values would have to be modified a bit in that case:
for (int i = 0; i < length; i += 2) {
floaters[i] = (short)(buffer[i] | (buffer[i+1] << 8));
}
Related
In one of my app i need to change sound frequency like it should be in thick voice for that i have use
THIS LINK
The above link code works fine for me...
While playing audio it change voice
My problem is HOW TO STORE THIS CHANGED VOICE?
this is method which play voice with changing in voice
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();
}
}
How can i store this clip in SDCARD? this is what i need is
In short i need all this thing to share that changed voice clip.. how i can i do this?
Can anybody help me to solve this problem?
I had the same problem and searched a lot and could not find a solution, But I came to a solution is to record the file with natural sound and save it in the phone and then used and called with the change Hz again ..
This Is Code StartRecord And Save it in Storage Device..
private void startRecord() {
AudioSavePathInDevice = Environment.getExternalStorageDirectory().getAbsolutePath() + "/SarahaVoice";
NameAudio = CreateRandomAudioFileName(5) + "Recording.mp3";
Toast.makeText(getActivity(), NameAudio, Toast.LENGTH_SHORT).show();
File file = new File(AudioSavePathInDevice, NameAudio);
try {
//file.createNewFile();
//Upcasting
OutputStream outputStream = new FileOutputStream(file);
//Buffering (Get Temporary Space To Write File.. When Finished Writing File Removed Temporary Space)
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
//Uses To Write Data Types Of Primitive Data In File
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);
int minBufferSize = AudioRecord.getMinBufferSize(11025, 2, 2);
short[] audioData = new short[minBufferSize];
AudioRecord audioRecord = new AudioRecord(1, 11025, 2, 2,minBufferSize);
audioRecord.startRecording();
while(recording){
int numberOfShort = audioRecord.read(audioData, 0, minBufferSize);
for(int i = 0; i < numberOfShort; i++){
dataOutputStream.writeShort(audioData[i]);
}
}
if (!recording.booleanValue())
{
audioRecord.stop();
audioRecord.release();
dataOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
And Also Code To PlayRecord audio From Storage Device With Change Hz..
void playRecord() {
audioTrack = null;
String str = (String) spFrequency.getSelectedItem();
File file = new File(AudioSavePathInDevice, NameAudio);
int shortSizeInBytes = Short.SIZE/Byte.SIZE;
final int bufferSizeInBytes = (int)(file.length()/shortSizeInBytes);
final short[] audioData = new short[bufferSizeInBytes];
try {
InputStream inputStream = new FileInputStream(file);
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
DataInputStream dataInputStream = new DataInputStream(bufferedInputStream);
int j = 0;
while(dataInputStream.available() > 0){
audioData[j] = dataInputStream.readShort();
j++;
}
dataInputStream.close();
if (str.equals(getString(R.string.normal)))
{
i = 11025;
}
if (str.equals(getString(R.string.monster)))
{
i = 8000;
}
if (str.equals(getString(R.string.chipmunk)))
{
i = 16000;
}
if (str.equals(getString(R.string.funny)))
{
i = 9000;
}
if (str.equals(getString(R.string.bee)))
{
i = 13000;
}
audioTrack = new AudioTrack(3,i,2,2,bufferSizeInBytes,1);
audioTrack.play();
audioTrack.write(audioData, 0, bufferSizeInBytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Ask yourself what they are Function CreateRandomAudioFileName() ^_^ This Function Create Random text Its code is down..
public String CreateRandomAudioFileName(int string){
StringBuilder stringBuilder = new StringBuilder( string );
int i = 0 ;
while(i < string ) {
stringBuilder.append(RandomAudioFileName.charAt(random.nextInt(RandomAudioFileName.length())));
i++ ;
}
return stringBuilder.toString();
}
God be with you :)
basically i need to change record voice then add effect to voice then share it with effect
in short share voice with adding effect
void playRecord() {
File file = new File(Environment.getExternalStorageDirectory(),
"testaudio.pcm");
// File file = new File(Environment.getExternalStorageDirectory(),
// "testaudio.3gp");
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();
int sampleFreq = 11025;
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
sampleFreq, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes,
AudioTrack.MODE_STREAM);
audioTrack.play();
// audioTrack.reloadStaticData()
audioTrack.write(audioData, 0, bufferSizeInBytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
In this i need to save this audioTrack to my sd card as audio format like mp3 or waw
I have recorded user's voice successfully using mediaplayer and the file is stored in sd card.
now i want to play that voice using audio track. But when I do it is making noise.
Y so.?
Here is the code to play sound..
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(); }
Noise could be due to a small buffer.
Try:
int intSize = android.media.AudioTrack.getMinBufferSize(44100,
AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
init *= 2;
If you work with exactly the minimum buffer size, it might result in noisy sound. Having twice the minimum size is a good practice (in my experience).
I have just resolve this by adding buffer size and check this code this will resolve your problem.
void playRecord(int position) {
if (position==0){
m=8000;
String folder_main = "MyVoiceChanger";
File filee = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + folder_main + "/Recording.mp3");
int shortSizeInBytes = Short.SIZE / Byte.SIZE;
int bufferSizeInBytes = (int) (filee.length() / shortSizeInBytes);
short[] audioData = new short[bufferSizeInBytes];
try {
InputStream inputStream = new FileInputStream(filee);
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
DataInputStream dataInputStream = new DataInputStream(bufferedInputStream);
int i = 0;
while (dataInputStream.available() > 0) {
try {
audioData[i] = dataInputStream.readShort();
i++;
}catch (EOFException e){
e.printStackTrace();
}
}
dataInputStream.close();
try {
bufferSizeInBytes = AudioTrack.getMinBufferSize(
m,
RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING
);
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes, AudioTrack.MODE_STREAM);
Log.i("Buffer", "playRecord: "+bufferSizeInBytes);
final int finalBufferSizeInBytes = bufferSizeInBytes;
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
audioTrack = new AudioTrack(3, m, 2, 2, finalBufferSizeInBytes, 1);
try {
audioTrack.play();
Log.i("Usman", "Audio "+audioTrack);
}catch (Exception e){
e.printStackTrace();
}
}
});
}catch (Exception e){
e.printStackTrace();
}
mediaPlayer.prepareAsync();
audioTrack.write(audioData, 0, bufferSizeInBytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
To produce sound on Android, I am using AudioTrack.
I have been able to produce sine waves, sawtooth waves, square waves but it would be nice to have a more realistic sound.
I found that .wav files were the easiest to play on AudioTrack because they are basically just a sequence of bytes with a header.
So I have got my wav file in the res/raw folder and I tried playing it with this code :
public void writeWav(){
byte[] byteData = null;
InputStream is = getResources().openRawResource(R.raw.high);
byteData = new byte[mBufferSize];
try {
is.read(byteData);
is.close();
}
catch (FileNotFoundException e) {}
catch (IOException e) {}
mAudioTrack.write(byteData, 0, byteData.length);
}
But all I get is noise. I realize there are lots of questions about AudioTrack and wav files, but I couldn't find an answer to my noise problem.
Use this method to play sound using audioTrack. It works for me
public void playAudioTrack() {
int sampleFreq = 16000;
File file = new File("--filePath--");
int shortSizeInBytes = Short.SIZE / Byte.SIZE;
int minBufferSize = AudioTrack.getMinBufferSize(sampleFreq, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
int bufferSizeInBytes = (int)(file.length() / shortSizeInBytes);
final AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, sampleFreq,
AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize,
AudioTrack.MODE_STREAM);
int i = 0;
byte[] s = new byte[bufferSizeInBytes];
try {
final FileInputStream fin = new FileInputStream("--filePath--");
final DataInputStream dis = new DataInputStream(fin);
at.setNotificationMarkerPosition((int)(file.length() / 2));
at.play();
while ((i = dis.read(s, 0, bufferSizeInBytes)) > -1) {
at.write(s, 0, i);
}
} catch (FileNotFoundException e) {
} catch (IOException e) {
} catch (Exception e) {
}
}
When I play a file with the following code:
private void PlayAudioFileViaAudioTrack(int ResId) throws IOException {
int intSize = android.media.AudioTrack.getMinBufferSize(11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, intSize,
AudioTrack.MODE_STREAM);
int count = 256 * 1024; // 256 kb
byte[] byteData = null;
byteData = new byte[(int) count];
InputStream in = null;
AssetFileDescriptor fd = null;
fd = mResources.openRawResourceFd(ResId);
in = mResources.openRawResource(ResId);
int bytesRead = 0, amount = 0;
int size = (int) fd.getLength();
at.play();
while (bytesRead < size) {
amount = in.read(byteData, 0, count);
if (amount != -1) {
at.write(byteData, 0, amount);
}
}
in.close();
at.stop();
at.release();
}
The only thing I hear is static, white noise. I've checked that my .wav file has the same properties (samplerate,bitrate). I don't have to much knowledge about raw audio data(PCM), so I was wondering if anyone could see what's wrong with my code.
from your code i can see that you just read data from the wav file and just import them to the AudioTrack. Wav files have a small header as you can see here https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ So you have to skip the header and point your file descriptor at the right place where the actual audio data are.
Also when you playing an audio file and you are dealing with byte operations you should take care of the Endianess. Take a look here Using AudioTrack in Android to play a WAV file
Below my code (some checks and the WAV header skip are missing) that works in both Nexus One and Galaxy S with a wav file with frequency 8000Hz and 16 bit encoding.
public void playWav(){
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);
String filepath = Environment.getExternalStorageDirectory().getAbsolutePath();
int i = 0;
byte[] s = new byte[bufferSize];
try {
FileInputStream fin = new FileInputStream(filepath + "/REFERENCE.wav");
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();
} catch (FileNotFoundException e) {
// TODO
e.printStackTrace();
} catch (IOException e) {
// TODO
e.printStackTrace();
}
}
That looks WAY more complicated than what I did. I played sounds using this. I think .wav files would work just as well.
MediaPlayer mpPlayProgram = new MediaPlayer();
mpPlayProgram.setDataSource("/sdcard/file.mp3");
mpPlayProgram.prepare();
mpPlayProgram.start();
mpPlayProgram.release();
For static resources, it's even easier:
MediaPlayer mpStart = MediaPlayer.create(this, resID);
mpStart.start();
mpStart.release();
If you have saved file in wav format and want to play it using AudioTrack then follow this code:
File file=new File(Environment.getExternalStorageDirectory()+"/AudioRecorder/fahim.wav");
InputStream is;
DataInputStream dis = null ;
BufferedInputStream bis;
try
{
is = new FileInputStream(file);
bis = new BufferedInputStream(is, 8000);
dis = new DataInputStream(bis); // Create a DataInputStream to read the audio data from the saved file
}
catch (FileNotFoundException e1)
{
ShowToast("fILE NOT FOUND:"+e1.getMessage());
}
int i = 0; // Read the file into the "music" array
music=new byte[(int) file.length()];
try
{
while (dis.available() > 0)
{
music[i] = dis.readByte(); // This assignment does not reverse the order
i++;
}
}
catch (IOException e)
{
ShowToast("I/O Exception:"+e.getMessage());
}
try {dis.close();} catch (IOException e) {e.printStackTrace();}
int minBufferSize = AudioTrack.getMinBufferSize(11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC, 11025, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
at.play();
ShowToast("size:"+music.length);
//*/
at.write(music, 0, music.length);