答案 0 :(得分:1)
以下是链接代码的演示文稿,适用于API级别23+,并添加了音频持续时间参数:
short generatedSnd[];
int sampleRate = 44100;
float freqOfTone = 1000; //Hz
float amplitude = 10000; //0..32767 (0x7FFF)
float lengthSeconds = 1.0f;
private void genTone(){
int numSamples = (int) (sampleRate * lengthSeconds);
generatedSnd = new short[numSamples];
// fill out the array
for (int i = 0; i < numSamples; ++i) {
generatedSnd[i] = (short) (Math.sin(2 * Math.PI * i / (sampleRate/freqOfTone)) * amplitude);
}
}
private void playSound(){
AudioTrack audioTrack = new AudioTrack.Builder()
.setAudioFormat(
new AudioFormat.Builder()
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.setSampleRate(sampleRate)
.setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
.build()
)
.setTransferMode(AudioTrack.MODE_STATIC)
.setBufferSizeInBytes(generatedSnd.length * 2) //2 bytes-per-sample
.build();
audioTrack.write(generatedSnd, 0, generatedSnd.length);
audioTrack.play();
}
此代码已在仿真器中经过长达50s的测试,但由于将大小传递给setBufferSize()
,因此在更高的播放时间可能会崩溃。请注意,它不包含其他高级功能来帮助您处理任意长的播放时间,例如1.)流式播放或2.)由于float
量化误差而导致的相位校正,其值远非0。
它应该可以在少于10秒的时间内正常工作。
AudioTrack清理代码(stop()
/ release()
)也被省略。