Playing an arbitrary tone with Android

后端 未结 10 2273
伪装坚强ぢ
伪装坚强ぢ 2020-11-22 10:38

Is there any way to make Android emit a sound of arbitrary frequency (meaning, I don\'t want to have pre-recorded sound files)?

I\'ve looked around and ToneGenerator

10条回答
  •  生来不讨喜
    2020-11-22 10:45

    Modified Code Based on Singhaks' answer

    public class MainActivity extends Activity {
        private final int duration = 30; // 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();
        private AudioTrack audioTrack;
        private boolean play = false;
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                    8000, AudioFormat.CHANNEL_OUT_MONO,
                    AudioFormat.ENCODING_PCM_16BIT, numSamples,
                    AudioTrack.MODE_STREAM);
        }
    
        @Override
        protected void onResume() {
            super.onResume();
    
            // Use a new tread as this can take a while
            Thread thread = new Thread(new Runnable() {
                public void run() {
    
                    handler.post(new Runnable() {
    
                        public void run() {
                            playSound();
                            genTone();
                        }
                    });
                }   
            });
            thread.start();
        }
    
        void genTone(){
            // fill out the array
            while(play){
                    for (int i = 0; i < numSamples; ++i) {
                    //  float angular_frequency = 
                        sample[i] = Math.sin(2 * Math.PI * i / (sampleRate/freqOfTone));
                    }
                    int idx = 0;
    
                    // convert to 16 bit pcm sound array
                    // assumes the sample buffer is normalised.
                    for (double dVal : sample) {
                        short val = (short) (dVal * 32767);
                        generatedSnd[idx++] = (byte) (val & 0x00ff);
                        generatedSnd[idx++] = (byte) ((val & 0xff00) >>> 8);
                    }
                    audioTrack.write(generatedSnd, 0, numSamples);
                }
            }
    
    
        void playSound(){
            play = true;
            audioTrack.play();
        }
    }
    

提交回复
热议问题