问题 如何生成特定的声音频率?


我正在开发一个Android应用程序。我想生成1KHz到20KHz之间的频率范围声音。无论如何都要以特定的频率产生声音。


4836
2018-01-02 08:00


起源

您描述的范围不是超声波。即它仍然可以听到。 - Sjoerd
挑剔:超声波 启动 在20KHz。您想要的范围内的频率是声音。 - Ted Hopp
@alextsc,如果是在BlackBerry或Java-ME中,那么也欢迎回答。 - Lucifer
看一眼 android.media.ToneGenerator - Ted Hopp
谢谢,我会编辑我的问题。 - Lucifer


答案:


我从另一个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();
    }
}

16
2018-01-02 08:08



嘿。我刚刚发现了同样的事情 这里。据说代码在该链接更新以修复错误。 - Ted Hopp
是的,但根据评论,它仍然有一些...无论哪种方式,它是一个很好的基础。 - Reid
此代码存在问题,即使您设置sampleRate = 44100也无法播放超过17000Hz的任何内容。例如,这些相同的算法在Flash中工作,而我使用的手机在来自文件时可以播放这些频率。有谁知道如何解决这一问题? - PSIXO