AudioRecord возвращает некоторые пустые данные после запуска

Я написал стандартный код для получения данных с микрофона с помощью AudioRecord. Вот мой код:

AudioReceiver() {
    int minHardwareBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE,
            CHANNEL_CONFIG, AUDIO_FORMAT);
    Log.d(TAG, "minHardwareBufferSize = " + minHardwareBufferSize);
    int bufferSizeBytes = (minHardwareBufferSize > MIN_BUFFER_SIZE_BYTES) ?
            minHardwareBufferSize : MIN_BUFFER_SIZE_BYTES;
    bufferSizeShorts = bufferSizeBytes / 2;

    //резервируем буфер с запасом в 2 раза
    audioRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
            SAMPLE_RATE, CHANNEL_CONFIG, AUDIO_FORMAT, bufferSizeBytes * 2);

    testStack = new short[bufferSizeShorts * 4];
    Arrays.fill(testStack, (short) 2000);
}


boolean startReceive() {
    audioRecorder.startRecording();
    isReceiving = true;
    int recordingState = audioRecorder.getRecordingState();
    Log.d(TAG, "recordingState = " + recordingState);
    new Thread(receivingRunnable).start();
    return (recordingState == AudioRecord.RECORDSTATE_RECORDING);
}


boolean stopReceive() {
    isReceiving = false;
    audioRecorder.stop();
    int recordingState = audioRecorder.getRecordingState();
    Log.d(TAG, "recordingState = " + recordingState);
    return (recordingState == AudioRecord.RECORDSTATE_STOPPED);
}


private Runnable receivingRunnable = new Runnable() {
    @Override
    public void run() {
        int readCount = 0;
        short[] dataBuffer = new short[bufferSizeShorts];
        while (isReceiving) {
            testBusy = true;
            for (int j = 0; j < 4; j++) {
                readCount = audioRecorder.read(dataBuffer, 0, dataBuffer.length);
                Log.d(TAG, "receive " + readCount + " bytes");
                System.arraycopy(dataBuffer, 0, testStack, bufferSizeShorts * j, readCount);
            }
            isReceiving = false;
            testBusy = false;
        }
    }
};

Но заметил, что после первого запуска функции startReceive в начале буфера testStack пустые данные (около 1000 выборок на Nexus 4, см. график данных).

График данных

Между инициализацией AudioReceiver и запуском startReceive проходит много времени. Что может быть причиной проблемы?


person SolderingIronMen    schedule 20.08.2017    source источник
comment
Вы нашли решение этой проблемы, @soldingironmen? Я сталкиваюсь с той же проблемой.   -  person vishwarajanand    schedule 17.11.2017
comment
@KhatamNaayak, нет. Пожалуйста, проголосуйте за мой вопрос, если вы столкнулись с той же проблемой.   -  person SolderingIronMen    schedule 04.12.2017
comment
У меня есть обходной путь, я добавлю ниже для справки.   -  person vishwarajanand    schedule 05.12.2017


Ответы (1)


Кажется, задержка вызвана тем, что ОС требуется время для повторной выборки данных, и сложно иметь одну частоту выборки для всех устройств. Также упоминается в других сообщениях. Итак, вместо этого я переместил свою логику аудиозаписи в действие onCreate. Когда мне не нужен звук или он поставлен на паузу, я просто выбрасываю данные.

Я не наблюдал сильного разряда батареи, всегда на аудиозаписи. Хотя это может быть не лучший способ решить эту проблему, но это определенно было приемлемым обходным путем для меня.

person vishwarajanand    schedule 05.12.2017
comment
Меня это решение не устраивает, так как моей изначальной целью была синхронизация запуска AudioRecord и AudioTrack. Но теперь я понимаю, что с Java это сделать невозможно. - person SolderingIronMen; 05.12.2017