如何使用AudioTrack循环播放音频?

时间:2019-07-02 00:45:06

标签: java android audiotrack

我有一个记录pcm文件并保存的程序。该文件的路径存储在名为import pygame pygame.init() pygame.mixer.init() sound = pygame.mixer.music.load('sound.wav') def playSound(): sound.pause() sound.play() while True: pass 的变量中。我想更改此代码,以使其在无缝循环中播放PCM文件,直到线程停止(通过将pcmFile更改为false)。

我有一个isPlaying课,像这样:

AudioManager

这里的重要部分是public class AudioManager { static final String TAG = "AudioRecorder"; boolean isPlaying = false; static final int frequency = 16000; private static final String AUDIO_RECORDER_FOLDER = "4TRACK"; static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO; static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; int playBufSize; AudioTrack audioTrack; String filename; File pcmFile; public AudioManager() { playBufSize=AudioTrack.getMinBufferSize(frequency, channelConfiguration, audioEncoding); audioTrack = new AudioTrack(android.media.AudioManager.STREAM_MUSIC, frequency, channelConfiguration, audioEncoding, playBufSize, AudioTrack.MODE_STREAM); audioTrack.setStereoVolume(0.7f, 0.7f); } public void startPlaying() { isPlaying = true; new PlayThread().start(); } public void stopPlaying() { isPlaying = false; } private String getFilename(){ String filepath = Environment.getExternalStorageDirectory().getPath(); File file = new File(filepath,AUDIO_RECORDER_FOLDER); return (file.getAbsolutePath() + "/" + filename + ".pcm"); } class PlayThread extends Thread { public void run() { try { System.out.println("~~Playing audio"); byte[] buffer = new byte[playBufSize]; BufferedInputStream bis = new BufferedInputStream(new FileInputStream(pcmFile), playBufSize); audioTrack.play(); int readSize = -1; while (isPlaying && (readSize = bis.read(buffer)) != -1) { audioTrack.write(buffer, 0, readSize); } audioTrack.stop(); MainActivity main = (MainActivity) ctx; main.audioStopped(); System.out.println("~~No longer playing"); bis.close(); } catch (Throwable t) { t.printStackTrace(); } } } } 类。现在,它可以完美播放pcm文件。如何调整此代码,使其循环播放PCM文件?

1 个答案:

答案 0 :(得分:0)

我可以看到您正在从main.audioStopped调用MainActivity函数,该函数通知媒体我想停止播放了。您可以通过audioStopped的{​​{1}}函数轻松地处理重复。

我对MainActivity类进行了如下修改。其中包含AudioManagercontext的音频,这些音频需要在构造函数中播放。这有助于您从fileName创建AudioManager的实例,因此,当音频播放完毕后,您可以重新开始音频。

MainActivity

然后从public class AudioManager { static final String TAG = "AudioRecorder"; Context ctx; public static boolean isPlaying = false; static final int frequency = 16000; private static final String AUDIO_RECORDER_FOLDER = "4TRACK"; static final int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO; static final int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; int playBufSize; AudioTrack audioTrack; String filename; File pcmFile; public AudioManager(Context ctx, String fileName) { this.ctx = ctx; this.filename = fileName; playBufSize = AudioTrack.getMinBufferSize(frequency, channelConfiguration, audioEncoding); audioTrack = new AudioTrack(android.media.AudioManager.STREAM_MUSIC, frequency, channelConfiguration, audioEncoding, playBufSize, AudioTrack.MODE_STREAM); audioTrack.setStereoVolume(0.7f, 0.7f); startPlaying(); } public void startPlaying() { isPlaying = true; new PlayThread().start(); } private String getFilename() { String filepath = Environment.getExternalStorageDirectory().getPath(); File file = new File(filepath, AUDIO_RECORDER_FOLDER); return file.getAbsolutePath() + "/" + filename + ".pcm"; } class PlayThread extends Thread { public void run() { try { System.out.println("~~Playing audio"); byte[] buffer = new byte[playBufSize]; BufferedInputStream bis = new BufferedInputStream(new FileInputStream(getFilename()), playBufSize); audioTrack.play(); int readSize = -1; while (isPlaying && (readSize = bis.read(buffer)) != -1) { audioTrack.write(buffer, 0, readSize); } audioTrack.stop(); MainActivity main = (MainActivity) ctx; main.audioStopped(); System.out.println("~~No longer playing"); bis.close(); } catch (Throwable t) { t.printStackTrace(); } } } } 开始检查MainActivity的值,并在找到isPlaying时重复启动线程。

true

希望有帮助!