0

I have a problem to generate smooth sinus wave.

I've done it few years ago on C++ and everything worked perfect. Now I am trying to do this using AudioTrack and I do not know what is wrong.

This is my test case:

I want to produce for five second a sinus wave which is smooth (no crack etc.). For one second I generate 44100 samples and divided it on couple of buffer with size 8192 (probably this is the reason of cracks, but how can I fix it, without giving bigger size of buffer). Unfortunatelly using my code the sound is not smooth and instead of 5 second it takes about 1 second. I would be gratefull for any help. Please let me now if this piece of code is not enough.

    class Constants:
    //<---
    public final static int SAMPLING = 44100;
    public final static int DEFAULT_GEN_DURATION = 1000;
    public final static int DEFAULT_NUM_SAMPLES = DEFAULT_GEN_DURATION * SAMPLING / 1000; //44100         per second
    public final static int DEFAULT_BUFFER_SIZE = 8192;
    //--->

    //preparing buffers to play;
    Buffer buffer = new Buffer();
    short[] buffer_values = new short[Constants.DEFAULT_BUFFER_SIZE];
    float[] samples = new float[Constants.DEFAULT_BUFFER_SIZE];
    float d = (float) (( Constants.FREQUENCIES[index] * 2 * Math.PI )  / Constants.SAMPLING);


    int numSamples = Constants.DEFAULT_NUM_SAMPLES;  //44100 per second - for test
    float x = 0;
    int index_in_buffer = 0;

    for(int i = 0; i < numSamples; i++){
        if(index_in_buffer >= Constants.DEFAULT_BUFFER_SIZE - 1){
            buffer.setBufferShort(buffer_values);
            buffer.setBufferSizeShort(index_in_buffer);
            queue_with_data_AL.add(buffer); //add buffer to queue
            buffer_values = new short[Constants.DEFAULT_BUFFER_SIZE];
            samples = new float[Constants.DEFAULT_BUFFER_SIZE];
            index_in_buffer = 0;
        }

    samples[index_in_buffer] = (float) Math.sin(x);

    buffer_values[index_in_buffer] = (short) (samples[index_in_buffer] * Short.MAX_VALUE);

    x += d;
    index_in_buffer++;
    }

    buffer.setBufferShort(buffer_values);
        buffer.setBufferSizeShort(index_in_buffer+1);
        queue_with_data_AL.add(buffer);

        index_in_buffer = 0;

    }


    //class AudioPlayer

    public AudioPlayer(int sampleRate) { //44100

    int minSize = AudioTrack.getMinBufferSize(sampleRate,
            AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);

    audiotrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
            AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT,
            minSize, AudioTrack.MODE_STREAM);
    }


    public void play(byte[] audioData, int sizeOfBuffer) {
            audiotrack.write(audioData, 0, sizeOfBuffer);
    }

    public void start() {
    if (state == Constants.STOP_STATE) {
    state = Constants.START_STATE;
    int startLength = 0;
    while (state == Constants.START_STATE) {
        Buffer buffer = getBufferFromQueueAL(); //getting buffer from prepared list
        if (buffer != null) {
        short[] data = buffer.getBufferShort();
        int size_of_data = buffer.getBufferSizeShort();
        if (data != null) {
            int len = audiotrack.write(data, 0, size_of_data);
            if (startLength == 0) {
                audiotrack.play();
            }

            startLength += len;
        } else {
            break;
        }

    } else {
        MessagesLog.e(TAG, "get null data");
        break;
    }
    }

    if (audiotrack != null) {
            audiotrack.pause();
            audiotrack.flush();
            audiotrack.stop();
    }
    }
    }
usr30911
  • 2,731
  • 7
  • 26
  • 56
user1683637
  • 75
  • 1
  • 5

2 Answers2

0

You are playing only 1 second because 44100 samples at a samplerate of 44100Hz result in exactly 1 second of sound.

You have to generate 5 times more samples if you want to play 5 seconds of sound (e.g. multiply DEFAULT_NUM_SAMPLES by 5) in your code.

Aladin Q
  • 550
  • 5
  • 12
  • 1
    Sorry, I wasn't clear enough. The generator of sinus wave was in the loop which repeat the procedure 5 times. Few minutes ago I added the answer what was wrong. Thank you anyway. – user1683637 Sep 07 '14 at 12:22
0

I've found the solution by myself. After adding Buffer to queue_with_data_AL I've forgotten create new instance of Buffer object. So in queue was couple of buffer with the same instance, hence sinus wave were not continuous.

Thanks if someone was trying to solve my problem. Unfortunatelly it was my programming mistake.

Best regards.

user1683637
  • 75
  • 1
  • 5