igorski / MWEngine

Audio engine and DSP library for Android, written in C++ providing low latency performance within a musical context, while providing a Java/Kotlin API. Supports both OpenSL and AAudio.
MIT License
264 stars 45 forks source link

Use setRecordFromDeviceInputState to record microphone sound is abnormal #147

Closed krislyy closed 2 years ago

krislyy commented 2 years ago
private class RecordOutputHandler implements View.OnClickListener {
        @Override
        public void onClick( View v ) {
            _isRecording = !_isRecording;
            _engine.setRecordFromDeviceInputState(
                _isRecording, getApplicationContext().getExternalFilesDir("").getAbsolutePath() + "/mwengine_output.wav"
            , 15000);
            (( Button ) v ).setText( _isRecording ? R.string.rec_btn_off : R.string.rec_btn_on );
        }
    }

use setRecordFromDeviceInputState to record microphone sound is abnormal. Glitch~~~ but setRecordingState is Ok, Is there something wrong with my use?

Add more, My phone is huawei P20, AAudio is not ok, but OpenSL is normal. I tried other phones, both is ok. By the way, when recording from input device without headset, AEC supports??

igorski commented 2 years ago

Hi there,

in what way is the sound abnormal ? Could you provide expectation and result, or maybe even the recorded output ?

Going by the little informative I have and the code provided I'm tempted to think maybe you are suffering from a feedback loop (as described in the Wiki). This means that the device is hearing its recorded signal meaning it will record the recorded signal again which quickly escalates to extreme noise (MWEngine does not provide AEC filtering).

For this purpose it is recommended to either record with headphones plugged in (as the microphone cannot pick up the sound coming from the headphones), or to mute the input channel while recording, for instance:

private class RecordOutputHandler implements View.OnClickListener {
        @Override
        public void onClick( View v ) {
            _isRecording = !_isRecording;
            _engine.setRecordFromDeviceInputState(
                _isRecording, getApplicationContext().getExternalFilesDir("").getAbsolutePath() + "/mwengine_output.wav"
            , 15000);
            _engine.getInputChannel().setMuted( _isRecording );
            (( Button ) v ).setText( _isRecording ? R.string.rec_btn_off : R.string.rec_btn_on );
        }
    }

For your remaining question on the audio driver, please limit to one question per GitHub Issue as it will be easier to track and maintain their progress.

krislyy commented 2 years ago

Thank you very much for your reply, this does solve the problem. In addition, if setMute takes effect, I need to add the following code:

diff --git a/mwengine/src/main/cpp/audioengine.cpp b/mwengine/src/main/cpp/audioengine.cpp
index 0983ae8..779651c 100755
--- a/mwengine/src/main/cpp/audioengine.cpp
+++ b/mwengine/src/main/cpp/audioengine.cpp
@@ -350,7 +350,7 @@ namespace MWEngine {

             // merge recording into current input buffer for instant monitoring

-            if ( inputChannel->getVolume() > 0.F ) {
+            if ( inputChannel->getVolume() > 0.F && !inputChannel->muted) {
                 inputChannel->mixBuffer( inBuffer, inputChannel->getVolume() );
             }
         }

However, the abnormal problem of AAudio when recording Android microphone input still exists, maybe this is a problem on a specific model, but it is very strange, it is normal to use OpenSL. I'll upload the two wav files I recorded with setMute(true) for reference. And resource wav files here

igorski commented 2 years ago

Thanks for pointing out the bug with the muted channel, this has been addressed in 87c68009a119c79d3f8ff8376c5aae5bca696f60

As for the AAudio recording issued this will be addressed in conjunction with https://github.com/igorski/MWEngine/issues/153

igorski commented 2 years ago

I have narrowed it down to an issue with dynamic buffer size scaling. AAudio is able to fire callbacks at different sample frames whenever the system considers it to be efficient. This would imply that the amount of recorded input samples would also be non-fixed.

I have pushed some changes in ecf2f8bce0dc09e4a6646d032d35c2bc001b9b09 can you verify whether this addresses your issue ?