gpt4 book ai didi

android - 播放短促的声音

转载 作者:行者123 更新时间:2023-11-30 00:31:02 26 4
gpt4 key购买 nike

我想播放一个短于 1 秒的生成声音。但是,AudioTrack 的 minBufferSize 似乎总是 1 秒或更长。在某些设备上,我可以将 bufferSize 设置为小于使用 AudioTrack.getMinBufferSize 评估的值,但这并非在所有设备上都可行。我想知道是否可以为 AudioTrack 生成更短的声音。我目前正在使用这段代码(它包含一些平滑,因为我不断获得新的频率):

int buffSize = AudioTrack.getMinBufferSize(sampleRate,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT);
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT, buffSize,
AudioTrack.MODE_STREAM);
short samples[] = new short[buffSize];
int amp = 10000;
double twopi = 8. * Math.atan(1.);
double phase = 0.0;
audioTrack.play();
double currentFrequency = getFrequency();
double smoothing = 300;
double deltaTime = buffSize / 500;
while (playing && PreferenceManager.getDefaultSharedPreferences(
MainActivity.this).getBoolean("effect_switch", true))
{
double newFrequency = getFrequency();
for (int i = 0; i < buffSize; i++)
{
currentFrequency += deltaTime * (newFrequency - currentFrequency) / smoothing;
samples[i] = (short) (amp * Math.sin(phase));
phase += twopi * currentFrequency / sampleRate;
}
audioTrack.write(samples, 0, buffSize);
}
audioTrack.stop();
audioTrack.release();

事实上,我希望声音更频繁地更新,这就是我需要较短样本的原因。

最佳答案

我想我有一个解决方案。由于我的最小缓冲区似乎比 1 秒小得多,我通过加载一个包含 5 秒数据的缓冲区来模拟你的问题,但只播放其中的 0.5 秒,然后立即播放另一个频率。这个音调我还创建了 5 秒的数据但只播放了 0.5 秒并重复了几个音调。这一切都适合我。

另外,由于我将它塞进了我正在处理的当前项目中,所以我很难仅仅剪切和粘贴我的代码。虽然我已经测试了我的解决方案,但我在此处发布的内容并未完全按照所写内容进行测试。其中一些是剪切和粘贴,一些是伪代码。

关键功能是使用 OnPlaybackPositionUpdateListener。

private AudioTrack.OnPlaybackPositionUpdateListener audioTrackListener = new AudioTrack.OnPlaybackPositionUpdateListener() {
@Override
public void onMarkerReached(AudioTrack audioTrack) {
int marker = audioTrack.getNotificationMarkerPosition();
// I just used 8 tones of 0.5 sec each to determine when to stop but you could make
// the condition based on a button click or whatever is best for you
if(marker < MAX_FRAME_POSITION) {
audioTrack.pause();
newSamples();
audioTrack.play();
} else {
audioTrack.stop();
}
audioTrack.setNotificationMarkerPosition(marker + FRAME_MARKER);
Log.d(TAG, "MarkerReached");
}

@Override
public void onPeriodicNotification(AudioTrack audioTrack) {
int position = audioTrack.getPlaybackHeadPosition();
if(position < MAX_FRAME_POSITION) {
audioTrack.pause();
newSamples();
audioTrack.play();
} else {
audioTrack.stop();
}
Log.d(TAG, "PeriodNotification");
}
};

然后

    audioTrack.setPlaybackPositionUpdateListener(AudioTrackListener);

我在测试中使用了标记(必须反复重新初始化)...

    audioTrack.setNotificationMarkerPosition(MARKER_FRAMES);    

但您也应该能够使用定期通知。

    audioTrack.setPositionNotificationPeriod(PERIODIC_FRAMES);

以及从监听器调用的 newSamples() 方法

public void newSamples() {
/*
* generate buffer, I'm doing similar to you, without the smoothing
*/

// AudioTrack write is a blocking operation so I've moved it off to it's own Thread.
// Could also be done with an AsyncTask.
Thread thread = new Thread(writeSamples);
thread.start();
}

private Runnable writeSamples = new Runnable() {
@Override
public void run() {
audioTrack.write(samples, 0, buffSize);
}
};

关于android - 播放短促的声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44354985/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com