Android声波 - 不顺畅和持续时间问题

时间:2014-09-06 16:37:01

标签: android wave audiotrack

我有一个产生平滑窦波的问题。

几年前我在C ++上完成了它,一切都很完美。现在我正在尝试使用AudioTrack这样做,我不知道出了什么问题。

这是我的测试用例:

我想生产五秒钟的正弦波(没有裂缝等)。一秒钟我生成了44100个样本并将其分成两个大小为8192的缓冲区(可能这是裂缝的原因,但我如何修复它,而不给出更大的缓冲区大小)。 不幸地使用我的代码声音不顺畅,而不是5秒,它需要大约1秒钟。我会感激任何帮助。 如果这段代码不够,请现在就告诉我。

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

2 个答案:

答案 0 :(得分:0)

你只播放1秒,因为44100个样本的44100个样本只能产生1秒的声音。

如果您想在代码中播放5秒钟的声音(例如,将DEFAULT_NUM_SAMPLES乘以5),则必须生成5倍以上的样本。

答案 1 :(得分:0)

我自己找到了解决方案。将Buffer添加到queue_with_data_AL后,我忘了创建Buffer对象的新实例。因此在队列中有一对具有相同实例的缓冲区,因此正弦波不是连续的。

如果有人试图解决我的问题,谢谢。不幸的是,这是我的编程错误。

最好的问候。