使用 SoundPool 生成 10 到 20000Hz 之间的正弦波
Posted
技术标签:
【中文标题】使用 SoundPool 生成 10 到 20000Hz 之间的正弦波【英文标题】:Generate Sine Wave between 10 and 20000Hz using SoundPool 【发布时间】:2010-11-17 16:18:23 【问题描述】:我最初尝试使用 AudioTrack 生成正弦波。结果并不令人满意。然后我转到了 Soundpool 课程。我使用 Audacity 创建 1 秒的音频文件,然后修改播放速度 (.5 - 2.0) 以获得所需的频率。 (阵列,因为也有锯和三角波文件)
sig10000[0]=soundPool01.load(context,R.raw.sine10000,1);
sig2500[0]=soundPool01.load(context,R.raw.sine2500,1);
sig625[0]=soundPool01.load(context,R.raw.sine625,1);
sig157[0]=soundPool01.load(context,R.raw.sine156,1);
sig40[0]=soundPool01.load(context,R.raw.sine40,1);
然后,根据选择的频率播放音频:
public void play()
Signal s=null;
float factor;
for(int i=0;i<this.size();i++)
s=this.get(i);
if(s.getFreq()>4999)
factor = s.getFreq()/10000f;
s.setStreamID(soundPool01.play(sig10000[s.getWaveType()],.99f,.99f,0,-1,factor));
else if(s.getFreq()>1249)
factor = s.getFreq()/2500f;
s.setStreamID(soundPool01.play(sig2500[s.getWaveType()],.99f,.99f,0,-1,factor));
else if(s.getFreq()>312)
factor = s.getFreq()/625f;
s.setStreamID(soundPool01.play(sig625[s.getWaveType()],.99f,.99f,0,-1,factor));
else if(s.getFreq()>77)
factor = s.getFreq()/156f;
s.setStreamID(soundPool01.play(sig157[s.getWaveType()],.99f,.99f,0,-1,factor));
else
factor = s.getFreq()/40f;
s.setStreamID(soundPool01.play(sig40[s.getWaveType()],.99f,.99f,0,-1,factor));
现在我看到了,除了 5000-20000 Hz 范围外,该方法工作正常。我对此感到头疼,不知道为什么它不起作用,而且我找不到任何问题的模式。
这种方法有一些基本问题吗?
提前谢谢你
编辑:“不工作的解释” 当我播放 5000-20000 Hz 范围内的正弦波时,很明显频率不准确。这意味着音高很差。例如。 19000 Hz 太低,很容易被耳朵察觉。我能说的是 10000 Hz(我的错误是 5000Hz),所以正常的播放速率是正确的。 在 14kHz 左右,信号音高不再正确。
想法/可能的原因(?): (A) 播放速度(SoundPool)有多少步?文档说 0.5-2.0 这是否意味着有 15 种不同的播放速度? (B) 我使用 Audacity 来生成 .ogg 文件。当我放大 10000Hz 正弦波时,我可以看到它不太平滑(采样率 44100),并且波不能精确地从 0 开始和结束。这会叠加不需要的信号吗?
【问题讨论】:
当您说“不确定为什么它不起作用”时,您能否更具体一些。似乎是什么问题?您是否在 LogCat 中收到任何可能与症状相关的消息? 【参考方案1】:我的第一个猜测是物理,而不是编程。
您的测试设备几乎不可能有一个实际能够产生干净的 19 Khz 输出的扬声器,因为那几乎是毫无意义的。因此,如果您尝试使用以 44 Khz 采样的 19 Khz 信号来驱动它,它将产生其他意想不到的频率。
【讨论】:
抱歉,我一开始还以为它在 5000Hz 下也不能正常工作,但它确实可以。所以我认为你可能是对的。它在 14Khz 左右开始变得不准确。然而,市场上有一些应用程序似乎能够在这些频率下发出信号,所以这在技术上不应该是可行的吗?在这些条件下,我能得到的最佳结果是什么? 我真的会质疑这些假设。您为什么要尝试使用专为可听频率设计的廉价扬声器来产生听不见的信号?是的,对于单个设备,我可以测量频率响应,将其反转,并确定对给定扬声器产生最佳近似的驱动信号。但是更好的扬声器通常会便宜很多。 但某些开发人员已经完成了独立于硬件生成更高范围的信号。这让我相信它以某种方式是可能的。 (我已经向他们发送了电子邮件 - 没有回复) 至于原因:我正在制作一个应用程序,其灵魂目的是在给定频率产生信号。以上是关于使用 SoundPool 生成 10 到 20000Hz 之间的正弦波的主要内容,如果未能解决你的问题,请参考以下文章
Android SoundPool:AudioFlinger 错误