Android AudioTrack воспроизводит WAV-файл, получая только белый шум
Когда я играю файл со следующим кодом:
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();
}
Единственное, что я слышу, - это статический белый шум. Я проверил, что мой файл.wav имеет те же свойства (частота дискретизации, битрейт). Мне не нужно много знаний о необработанных аудиоданных (PCM), поэтому мне было интересно, сможет ли кто-нибудь увидеть, что не так с моим кодом.
3 ответа
Из вашего кода я вижу, что вы просто читаете данные из файла wav и просто импортируете их в AudioTrack. Wav-файлы имеют небольшой заголовок, как вы можете видеть здесь https://ccrma.stanford.edu/courses/422/projects/WaveFormat/ Таким образом, вы должны пропустить заголовок и указать дескриптор файла в нужном месте, где находятся фактические аудиоданные являются.
Также, когда вы проигрываете аудиофайл и имеете дело с байтовыми операциями, вы должны позаботиться о Endianess. Посмотрите здесь Использование AudioTrack в Android для воспроизведения файла WAV
Ниже мой код (некоторые проверки и пропуск заголовка WAV отсутствуют), который работает как в Nexus One, так и в Galaxy S с файлом WAV с частотой 8000 Гц и 16-битной кодировкой.
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();
}
}
Если вы сохранили файл в формате wav и хотите воспроизвести его с помощью AudioTrack, выполните следующие действия:
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);
Это выглядит намного сложнее, чем я. Я играл звуки, используя это. Я думаю, что файлы.wav будут работать так же хорошо.
MediaPlayer mpPlayProgram = new MediaPlayer();
mpPlayProgram.setDataSource("/sdcard/file.mp3");
mpPlayProgram.prepare();
mpPlayProgram.start();
mpPlayProgram.release();
Для статических ресурсов это даже проще:
MediaPlayer mpStart = MediaPlayer.create(this, resID);
mpStart.start();
mpStart.release();