我正在尝试生成并播放方波。我正在生成信号,然后使用
track = new AudioTrack(AudioManager.STREAM_MUSIC,
sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, minSize,
AudioTrack.MODE_STREAM);
track.write(signal, 0, signal.length);
然后调用track.play()。问题是它只播放一次。看起来有一种设置循环点的方法,但我不知道要为帧添加什么。
我也尝试在while循环中调用track.write()然后调用track.play(),但是有一个短暂的延迟,我认为这不是正确的方法。
无缝循环的正确方法是什么?
答案 0 :(得分:6)
有一个非常相似的问题:https://stackoverflow.com/questions/4241724/androidaudiotrack-setlooppoint-issue
如果我正确阅读了Android文档,那么您使用的是16位样本,因此signal.length / 2是样本数。我试试:
track.setLoopPoints(0, signal.length/2, -1);
答案 1 :(得分:1)
要在MODE_STREAM中循环,请等到写循环结束。然后设置循环点,然后再次调用play。我没有做任何循环,甚至非循环的AudioTrack,已经治愈了点击开始。
答案 2 :(得分:0)
要无限次循环音频文件,请将循环设置为-1。要在循环播放音频文件时消除延迟,请使用SoundPool
类而不是MediaPlayer
。
答案 3 :(得分:0)
我现在面临同样的问题,看起来循环对我来说效果不好,循环之间总有一点“休息”,然后我尝试继续生成声音并提供录音带,它对我有用:
class ToneGenerator {
int sampleRate = 8000;
double sample[] = null;
byte generatedSnd[] = null;
int m_ifreq = 400;
Thread m_PlayThread = null;
boolean m_bStop = false;
AudioTrack m_audioTrack = null;
int m_play_length = 1000;//in seconds
static public void PlayTone(int freq, int play_length) {
ToneGenerator player = new ToneGenerator();
player.m_ifreq = freq;
player.m_play_length = play_length;
player.play();
}
synchronized void stop() {
m_bStop = true;
if (m_PlayThread != null) {
try {
m_PlayThread.interrupt();
m_PlayThread.join();
m_PlayThread = null;
} catch (Exception e) {
}
}
if (m_audioTrack != null) {
m_audioTrack.stop();
m_audioTrack.release();
m_audioTrack = null;
}
}
synchronized void play() {
m_bStop = false;
m_PlayThread = new Thread() {
public void run() {
try {
int iToneStep = 0;
m_audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
sampleRate, AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, 2 * sampleRate,
AudioTrack.MODE_STREAM);
while (!m_bStop && m_play_length-- > 0) {
genTone(iToneStep++);
m_audioTrack.write(generatedSnd, 0, generatedSnd.length);
if (iToneStep == 1) {
m_audioTrack.play();
}
}
} catch (Exception e) {
Log.e("Tone", e.toString());
} catch (OutOfMemoryError e) {
Log.e("Tone", e.toString());
}
}
};
m_PlayThread.start();
}
//Generate tone data for 1 seconds
synchronized void genTone(int iStep) {
sample = new double[sampleRate];
for (int i = 0; i < sampleRate; ++i) {
sample[i] = Math.sin(2 * Math.PI * (i + iStep * sampleRate) / (sampleRate / m_ifreq));
}
// convert to 16 bit pcm sound array
// assumes the sample buffer is normalised.
generatedSnd = new byte[2 * sampleRate];
int idx = 0;
for (final double dVal : sample) {
// scale to maximum amplitude
final short val = (short) ((dVal * 32767));
// in 16 bit wav PCM, first byte is the low order byte
generatedSnd[idx++] = (byte) (val & 0x00ff);
generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
}
}
}