RootEncoder icon indicating copy to clipboard operation
RootEncoder copied to clipboard

hissing sound on mix audio

Open itsmeinteger opened this issue 5 months ago • 20 comments

I'm getting a hissing sound from my device's audio when using mic+audio mix. The issue only occurs when the mic is on—there's no hissing when the mic is off. Whenever I interact with something, like clicking in a game's UI or opening settings, the hissing sound comes along with the audio. Please help me fix this.

itsmeinteger avatar Jul 30 '25 09:07 itsmeinteger

here is the example of the issue https://youtube.com/shorts/w3rpOXtRWRE?si=cTTNT1wVm2lsfdnk

itsmeinteger avatar Jul 30 '25 09:07 itsmeinteger

Hello,

I only can hear noise but it is from the microphone because you still have that noise using microphone source. Can you be more specific with the seconds that you can detect that problem or even record a video with the problem but more evident?

pedroSG94 avatar Jul 30 '25 17:07 pedroSG94

https://youtube.com/shorts/gdGxNgkmLoI?si=tfbir9su-sYFVXfI maybe now its more clear

itsmeinteger avatar Jul 30 '25 17:07 itsmeinteger

a buzzing like sound

itsmeinteger avatar Jul 30 '25 17:07 itsmeinteger

Do you means the "residual noise sound" after click a button in the game or the noise present all time after change to mix audio? In both cases it seem related with the microphone. For the first case try reduce the device sound close to 0, maybe the sound is detected by the microphone and produce that noise. The second case maybe can be reduced using noiseSuppressor and echoCanceler in prepareAudio method, if you are using it, try remove it because in some device instead of help, it could produce noise. Also, you can try change the microphone audio source. when you change the audio source to MixAudioSource try this:

MixAudioSource(
            it,
            microphoneAudioSource = MediaRecorder.AudioSource.VOICE_COMMUNICATION
          )

Try too with MediaRecorder.AudioSource.MIC

pedroSG94 avatar Jul 31 '25 09:07 pedroSG94

As you suggested, I tried all the recommended methods:

First, I disabled both NoiseSuppressor and EchoCanceler. Then I tested with both MediaRecorder.AudioSource.VOICE_COMMUNICATION and MediaRecorder.AudioSource.MIC. I also reduced the device volume, connected external headphones, and tested without headphones as well. Unfortunately, none of these made a difference—the noise issue is still present. The only noticeable change was that using MediaRecorder.AudioSource.MIC slightly improved the mic quality and loudness, but the noise remains.

I'm currently testing on a Samsung Galaxy F22 and have also tried on an iQOO Z5, and the issue is the same on both. So it doesn’t seem to be device-specific.

itsmeinteger avatar Jul 31 '25 10:07 itsmeinteger

any solution brother?

itsmeinteger avatar Aug 04 '25 11:08 itsmeinteger

Hello,

Sorry for late response I was on holidays. I'm still not sure about which noise you refer, please specify the video and second when you detect the noise. Also, you can try using TimeStampMode.BUFFER and check if the problem is solved (ScreenService class in the example):

    genericStream = GenericStream(baseContext, this, NoVideoSource(), MicrophoneSource()).apply {
      //This is important to keep a constant fps because media projection only produce fps if the screen change
      getGlInterface().setForceRender(true, 15)
      setTimestampMode(TimestampMode.CLOCK, TimestampMode.BUFFER)
    }

pedroSG94 avatar Aug 05 '25 19:08 pedroSG94

tested with the (TimestampMode.CLOCK, TimestampMode.BUFFER ), (TimestampMode.CLOCK, TimestampMode.CLOCK) and (TimestampMode.BUFFER, TimestampMode.BUFFER) but the issue is still there

itsmeinteger avatar Aug 07 '25 14:08 itsmeinteger

https://youtube.com/shorts/Pcf0y71hQJA?si=5L15nKonDUDBGXoA

could you try connecting a headphone and listening closely? Right after the UI sound ends, there’s a faint hissing noise in the mixed audio. might be some leftover noise from the mic or something similar

itsmeinteger avatar Aug 07 '25 15:08 itsmeinteger

Hello,

Ok, I understand. Maybe the problem is related with the mix audio method. Do you have this problem is you select audio only from the microphone and increase the device audio to max? This way we can confirm if the problem is related with the audio mix or the microphone.

pedroSG94 avatar Aug 11 '25 20:08 pedroSG94

I tested the way you suggested, using microphone only mode with the device volume at maximum, and I noticed it captures low device volume. I’m adding the video use headphones to listen carefully. I’m not sure what’s causing the issue, I used external headphones while recording this video. https://www.youtube.com/shorts/D--1f-L8zJc

itsmeinteger avatar Aug 12 '25 11:08 itsmeinteger

I finally fixed the buzzing and distortion in AudioUtils.kt. The main problem was that audio samples were being read as unsigned numbers when they should’ve been signed. This threw off the volume calculations and mixing. The old code was also mixing sound one byte at a time instead of using full 16-bit samples, which made the audio messy. On top of that, there was no limit on how loud the combined samples could get, so they could overflow and wrap around, creating harsh buzzing. Even the volume control had the same signed/unsigned problem.

Here’s an example of the old and new code:

// OLD (BROKEN) - mixed raw bytes, caused distortion
dst[i] = (adjustedSample.toByte() + adjustedSample2.toByte()).toByte()

// NEW (FIXED)
 // 1. Convert to signed 16-bit
val signedSample1 = if (sample1 > 32767) sample1 - 65536 else sample1
val signedSample2 = if (sample2 > 32767) sample2 - 65536 else sample2

// 2. Apply volume and mix properly
val adjustedSample1 = (signedSample1 * volume).toInt()
val adjustedSample2 = (signedSample2 * volume2).toInt()
var mixedSample = adjustedSample1 + adjustedSample2

// 3. Clamp to prevent overflow
mixedSample = mixedSample.coerceIn(-32768, 32767)

// 4. Convert back to unsigned bytes
val unsignedSample = if (mixedSample < 0) mixedSample + 65536 else mixedSample
dst[i] = (unsignedSample and 0xFF).toByte()
dst[i + 1] = ((unsignedSample shr 8) and 0xFF).toByte()

itsmeinteger avatar Aug 13 '25 14:08 itsmeinteger

Hello,

Thank you for the report and the fix. I did a PR based on your fix here: https://github.com/pedroSG94/RootEncoder/pull/1895/files

Let me know if it is fixed as you recommended. I did a test and the quality seem good

pedroSG94 avatar Aug 13 '25 20:08 pedroSG94

You can create a PR if you prefer do the PR yourself if you want.

pedroSG94 avatar Aug 13 '25 20:08 pedroSG94

Yes, I tested the fix you applied and it’s correct it resolves the issue. Everything works as expected now, cheers! The issue is resolved.

itsmeinteger avatar Aug 13 '25 23:08 itsmeinteger

Can you update to version 2.6.4? I'm encountering the same issue. Thank you

wubangjunjava avatar Aug 14 '25 13:08 wubangjunjava

Hello,

I did an optimization in the method. Please, test it and confirm me that all is working fine. In my case all seem fine.

About the version, I will do it soon after confirm that all is fine

pedroSG94 avatar Aug 14 '25 21:08 pedroSG94

Hey, the rest of your code is fine! Just found a bug in calculateAmplitude(). Currently it only measures positive sound waves and ignores negative ones.
So loud negative peaks (like bass) are read as quiet. change

val sample = ((buffer[i + 1].toInt() shl 8) or (buffer[i].toInt() and 0xFF))
if (sample > amplitude) amplitude = sample

to

val sample = ((buffer[i + 1].toInt() shl 8) or (buffer[i].toInt() and 0xFF)).toShort().toInt()
val sampleAmplitude = kotlin.math.abs(sample)
if (sampleAmplitude > amplitude) amplitude = sampleAmplitude

itsmeinteger avatar Aug 14 '25 23:08 itsmeinteger

Hello,

Thank you. I did a commit to fix it in the same PR: https://github.com/pedroSG94/RootEncoder/pull/1895/commits/27962be901115d0707e2d7cad2a9c69d59f241a7

pedroSG94 avatar Aug 15 '25 13:08 pedroSG94