如何使用AudioTrack生成和播放20Hz方波?

时间:2013-07-24 08:09:53

标签: android wave audiotrack

我正在尝试使用AudioTrack(Android)生成和播放方波。我已经阅读了很多教程,但仍然有一些混淆。

int sampleRate = 44100;
int channelConfig = AudioFormat.CHANNEL_IN_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;

AudioTrack audioTrack;
int buffer = AudioTrack.getMinBufferSize(sampleRate, channelConfig,
        audioFormat);

audioTrack.write(short[] audioData, int offsetInShorts, int sizeInShorts);

在代码中,让我困惑的是如何编写短数组“audioData”......

任何人都可以帮助我吗?提前谢谢!

2 个答案:

答案 0 :(得分:1)

您应该使用Pulse-code modulation。链接的文章有一个编码正弦波的例子,方波甚至更简单。请记住,最大振幅由最大值short(32767)编码,“有效”频率取决于您的采样率。

答案 1 :(得分:0)

此方法生成Square,Sin和Saw Tooth波形

         // Process audio
        protected void processAudio()
        {
            short buffer[];

            int rate =
                AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
            int minSize =
                AudioTrack.getMinBufferSize(rate, AudioFormat.CHANNEL_OUT_MONO,
                                            AudioFormat.ENCODING_PCM_16BIT);

            // Find a suitable buffer size
            int sizes[] = {1024, 2048, 4096, 8192, 16384, 32768};
            int size = 0;

            for (int s : sizes)
            {
                if (s > minSize)
                {
                    size = s;
                    break;
                }
            }

            final double K = 2.0 * Math.PI / rate;

            // Create the audio track
            audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, rate,
                                        AudioFormat.CHANNEL_OUT_MONO,
                                        AudioFormat.ENCODING_PCM_16BIT,
                                        size, AudioTrack.MODE_STREAM);
            // Check audiotrack
            if (audioTrack == null)
                return;

            // Check state
            int state = audioTrack.getState();

            if (state != AudioTrack.STATE_INITIALIZED)
            {
                audioTrack.release();
                return;
            }

            audioTrack.play();

            // Create the buffer
            buffer = new short[size];

            // Initialise the generator variables
            double f = frequency;
            double l = 0.0;
            double q = 0.0;

            while (thread != null)
            {
                // Fill the current buffer
                for (int i = 0; i < buffer.length; i++)
                {
                    f += (frequency - f) / 4096.0;
                    l += ((mute ? 0.0 : level) * 16384.0 - l) / 4096.0;
                    q += (q < Math.PI) ? f * K : (f * K) - (2.0 * Math.PI);

                    switch (waveform)
                    {
                    case SINE:
                        buffer[i] = (short) Math.round(Math.sin(q) * l);
                        break;

                    case SQUARE:
                        buffer[i] = (short) ((q > 0.0) ? l : -l);
                        break;

                    case SAWTOOTH:
                        buffer[i] = (short) Math.round((q / Math.PI) * l);
                        break;
                    }
                }

                audioTrack.write(buffer, 0, buffer.length);
            }

            audioTrack.stop();
            audioTrack.release();
        }
    }

信用转到billthefarmer

完整源代码:

https://github.com/billthefarmer/sig-gen