【问题标题】:How to Generate A Particular Sound Frequency?如何产生特定的声音频率?
【发布时间】:2012-01-02 08:00:14
【问题描述】:

我正在开发一个 Android 应用程序。我想生成频率范围在 1KHz 到 20KHz 之间的声音。有没有办法以特定的频率产生声音。

【问题讨论】:

  • 你描述的范围不是超声波的。 IE。它仍然可以听到。
  • 只是吹毛求疵:超声波开始在 20KHz。您想要的范围内的频率是声学的。
  • @alextsc,如果是 BlackBerry 或 Java-ME,也欢迎回答。
  • 谢谢,我会编辑我的问题。

标签: android


【解决方案1】:

我从另一个 SO 帖子中找到了此代码。据我所知,它还有点小问题,但应该可以解决问题。

public class PlaySound extends Activity {
    // originally from http://marblemice.blogspot.com/2010/04/generate-and-play-tone-in-android.html
    // and modified by Steve Pomeroy <steve@staticfree.info>
    private final int duration = 3; // seconds
    private final int sampleRate = 8000;
    private final int numSamples = duration * sampleRate;
    private final double sample[] = new double[numSamples];
    private final double freqOfTone = 440; // hz

    private final byte generatedSnd[] = new byte[2 * numSamples];

    Handler handler = new Handler();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    protected void onResume() {
        super.onResume();

        // Use a new tread as this can take a while
        final Thread thread = new Thread(new Runnable() {
            public void run() {
                genTone();
                handler.post(new Runnable() {

                    public void run() {
                        playSound();
                    }
                });
            }
        });
        thread.start();
    }

    void genTone(){
        // fill out the array
        for (int i = 0; i < numSamples; ++i) {
            sample[i] = Math.sin(2 * Math.PI * i / (sampleRate/freqOfTone));
        }

        // convert to 16 bit pcm sound array
        // assumes the sample buffer is normalised.
        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);

        }
    }

    void playSound(){
        final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO,
                AudioFormat.ENCODING_PCM_16BIT, numSamples,
                AudioTrack.MODE_STATIC);
        audioTrack.write(generatedSnd, 0, generatedSnd.length);
        audioTrack.play();
    }
}

【讨论】:

  • 嘿。我刚刚发现了同样的事情here。据说该链接上的代码已更新以修复错误。
  • 是的,但根据 cmets,它仍然有一些......无论哪种方式,它都是一个很好的基础。
  • 此代码存在问题,因为即使您设置 sampleRate = 44100,它也不会播放超过 17000Hz 的任何内容。例如,这些相同的算法适用于 Flash,而我使用的手机可以播放这些当它们来自文件时的频率。有谁知道如何解决这个问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-12
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 2019-08-29
  • 2021-05-13
  • 1970-01-01
相关资源
最近更新 更多