2

I'm trying to generate and play a square wave with AudioTrack(Android). I've read lots of tutorials but still have some confusions.

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);

In the codes, what makes me confused is How to write the short array "audioData" ...

Anyone can help me? Thanks in advance !

randino
  • 23
  • 5

2 Answers2

1

You should use Pulse-code modulation. The linked article has an example of encoding a sine wave, a square wave is even simpler. Remember that the maximum amplitude is encoded by the maximum value of short (32767) , and that the "effective" frequency depends on your sampling rate.

mikołak
  • 9,605
  • 1
  • 48
  • 70
  • Thank you ! that article help me further understand how the data is transmitted between the android device and mcu, but I still dont't have any idea to do with it. Do you have some relative codes ? Thank! – randino Jul 25 '13 at 02:17
  • Unfortunately I cannot provide you any code, but I'd be more than happy to help you if you show [what have you tried](http://mattgemmell.com/2008/12/08/what-have-you-tried/). Just edit your question to include the code you've attempted after reading that article :). But here's a hint if you're stuck at the start: see that diagram in the [Modulation section](https://en.wikipedia.org/wiki/Pulse-code_modulation#Modulation)? Each "step" is one `short` value/index in your array. – mikołak Jul 25 '13 at 06:31
  • Thank you for your help and I have solved it according to this article [Playing an arbitrary tone with Android](http://stackoverflow.com/questions/2413426/playing-an-arbitrary-tone-with-android) :) – randino Jul 25 '13 at 08:48
  • @randino: No problem. It is a good thing if you either accept your existing answer or create a new one and accept it. That way the question won't be left unanswered and "dangling". – mikołak Jul 25 '13 at 10:09
0

This method generates Square, Sin and Saw Tooth wave forms

         // 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();
        }
    }

Credit goes to billthefarmer.

Complete Source code:

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

Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154