Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recordings Overlapping #39

Closed
CodElixer opened this issue May 27, 2022 · 53 comments · Fixed by #59 or #72
Closed

Recordings Overlapping #39

CodElixer opened this issue May 27, 2022 · 53 comments · Fixed by #59 or #72
Assignees

Comments

@CodElixer
Copy link

CodElixer commented May 27, 2022

Hi @chenxiaolong

I tried latest v1.4 too but the audio recording overlapping is still there!

Say If I record for a 20 seconds long call then sometimes it's the recorded duration only getting 7 seconds, sometimes it's 11 seconds and sometimes whole 20 seconds!

When the duration reducing say for 7 seconds long recording then the remaining recording of 13 seconds seems getting overlapped between 6th to 7th second of the recorded audio!

I've also allowed BCR to run in the background, So there's no issue with getting it killed in background.

@CodElixer CodElixer changed the title Recording Overlapping Recordings Overlapping May 27, 2022
@chenxiaolong
Copy link
Owner

Hmm, that's a really weird issue. To make sure I'm understanding, you're saying that the files are always 20 seconds, but sometimes it's:

  • 7 seconds of good audio + 13 seconds overlapped
  • 11 seconds of good audio + 9 seconds overlapped
  • 20 seconds of good audio

Is that correct?

After work today, I'll make a debug build for you to try out that will not do any encoding/compression and just output a raw .wav file. Those output files will be the exact audio that the Android system provides to BCR. Hopefully there will be no issue there, but if the overlapping still happens, then it might not be fixable because Android itself is producing bad audio.

@CodElixer
Copy link
Author

Hmm, that's a really weird issue. To make sure I'm understanding, you're saying that the files are always 20 seconds, but sometimes it's:

  • 7 seconds of good audio + 13 seconds overlapped
  • 11 seconds of good audio + 9 seconds overlapped
  • 20 seconds of good audio

Is that correct?

After work today, I'll make a debug build for you to try out that will not do any encoding/compression and just output a raw .wav file. Those output files will be the exact audio that the Android system provides to BCR. Hopefully there will be no issue there, but if the overlapping still happens, then it might not be fixable because Android itself is producing bad audio.

Yes, I'm always recording for 20 seconds, so originally file should be of 20 seconds long.
But sometimes the output files are:

  • For 7 seconds long output file, Remaining 13 seconds of audio overlapping in between 6th to 7th second of the output file.

  • For 11 seconds long output file, Remaining 9 seconds of audio overlapping in between 10th to 11th second of the output file.

So, This is the issue.

@chenxiaolong
Copy link
Owner

Could you give these 2 debug builds a try?

Hopefully the overlapping doesn't occur in the wav files. If it still happens, there's nothing BCR can do to fix it--the raw audio from Android is already broken.

@CodElixer
Copy link
Author

CodElixer commented May 28, 2022

Could you give these 2 debug builds a try?

Both the r2 and r3 files are working fine!

@CodElixer
Copy link
Author

CodElixer commented May 28, 2022

  • Dump file from latest BCR v1.5 with default MPA format, 64 kbps Bitrate.
    https://easyupload.io/qahsaw

  • Here you can see the audio distortion at last 20th second!

@chenxiaolong
Copy link
Owner

That's good news! So it seems like call recording words, but encoding/compression is broken on your device.

Can you try running this apk? CodecDump.zip (It's a regular apk that can be directly installed--not a magisk module.)

It should print out something like this: Screenshot_20220528-161832

Can you copy and paste (or upload) that full text here?

On my device, there are:

  • c2.android.aac.encoder
  • c2.android.opus.encoder
  • c2.android.flac.encoder

I wonder if the ROM you're running has additional/different encoders that might be broken.

@CodElixer
Copy link
Author

CodElixer commented May 28, 2022

Yeah sure, here you go CodecDump.txt

@chenxiaolong
Copy link
Owner

Hmm, so it uses the same encoders as on my Google Pixel. I wonder why it might be broken.

@CodElixer
Copy link
Author

CodElixer commented May 29, 2022

Hmm, so it uses the same encoders as on my Google Pixel. I wonder why it might be broken.

Does it(The CodecDump file) changes according to the ROM you're using?
Because My device is Xiaomi's Poco F1 and Running Pixel Experience custom ROM based on Pixel 6 Pro device!

@CodElixer
Copy link
Author

CodElixer commented May 29, 2022

@chenxiaolong
Copy link
Owner

Does it(The CodecDump file) changes according to the ROM you're using?

I haven't tried anything besides the stock ROM and pure AOSP. Same codecs in those two.

Just incase you needed, Here's the dump file from Poco F1's Stock Android 10 ROM.

Do you know if the overlapping issue happens in that stock ROM also?

So far, I'm not having any luck troubleshooting what the problem might be. I can't reproduce it on my Pixel and don't have any other devices to test on. I'm adding WAV as a supported output type in version 1.6 so at least you can have something working while we try to fix this.

@chenxiaolong chenxiaolong self-assigned this May 29, 2022
@CodElixer
Copy link
Author

CodElixer commented May 30, 2022

Do you know if the overlapping issue happens in that stock ROM also?

  • I'll let you know later about how the BCR is working on stock ROM.

On stock ROM, There was Xiaomi's Default call recorder which was using mp3 codec and saving the files in format like "contact name/number(number)_YYYYMMDDTTMMSS.mp3", example: Complaint Helpline(198)_20220409180752.mp3
There the recording was working flawlessly because it was by default supported by the ROM itself.

So far, I'm not having any luck troubleshooting what the problem might be. I can't reproduce it on my Pixel and don't have any other devices to test on. I'm adding WAV as a supported output type in version 1.6 so at least you can have something working while we try to fix this.

Yeah, No issues!👍🏻
Just wanted to let you know that the .wav ui is missing from the format selection buttons. It's still working but not showing there, There might be the issue with the width, sharing you the screenshot of the issue. And also if you could add that 16kHz option too in upcoming version for wav file that'll take some less space.

@praveenpkallambalam
Copy link

Hmm, that's a really weird issue. To make sure I'm understanding, you're saying that the files are always 20 seconds, but sometimes it's:

  • 7 seconds of good audio + 13 seconds overlapped
  • 11 seconds of good audio + 9 seconds overlapped
  • 20 seconds of good audio

Is that correct?

After work today, I'll make a debug build for you to try out that will not do any encoding/compression and just output a raw .wav file. Those output files will be the exact audio that the Android system provides to BCR. Hopefully there will be no issue there, but if the overlapping still happens, then it might not be fixable because Android itself is producing bad audio.

Have this issue. M4A/AAC glitches at like 5-10 seconds in to recording after few seconds it becomes clear and continue to record. When glitches the seek bar on player moves backwards. OGG/Opus has the same issue.
Device:Poco f1
ROM: Pixel Experience+ a12

@chenxiaolong
Copy link
Owner

Just wanted to let you know that the .wav ui is missing from the format selection buttons. It's still working but not showing there, There might be the issue with the width, sharing you the screenshot of the issue.

Oops! I'll find a way to fix that (probably allow the buttons to be on multiple rows).

I'll let you know later about how the BCR is working on stock ROM.

👍

On stock ROM, There was Xiaomi's Default call recorder which was using mp3 codec and saving the files in format like "contact name/number(number)_YYYYMMDDTTMMSS.mp3", example: Complaint Helpline(198)_20220409180752.mp3
There the recording was working flawlessly because it was by default supported by the ROM itself.

Oh, that's interesting. Can you link to a download of the stock ROM? Maybe I can figure out what the stock recorder does differently.

@CodElixer
Copy link
Author

CodElixer commented May 30, 2022

Oh, that's interesting. Can you link to a download of the stock ROM? Maybe I can figure out what the stock recorder does differently.

Here is the link for Official Stock ROM.
There you'll find two types:

  1. Fastbooot ROM
  2. Recovery ROM

Hope this helps :)

@chenxiaolong
Copy link
Owner

It looks like that MIUI ROM has different recording methods depending on the output format:

  • WAV
    • Records using Android's AudioRecord API
    • Writes .wav header manually
    • (Very similar to what BCR does--that explains why this is working for you)
  • MP3:
    • Records using Android's AudioRecord API
    • Encodes using the LAME library
  • AAC and AMR-WB/NB:
    • Records and encodes using Android's MediaRecorder API
    • (I actually implemented BCR this way before version 1.0, but it unfortunately crashes and does not work at all on my Google Pixel)

So, it seems like MIUI doesn't use the MediaCodec API at all (which is what BCR uses for encoding). That must be where the overlapping issue is happening.

By the way, a random thought I had: does MIUI have a battery power save mode? If it has a power save mode, does it make any difference for when the overlapping occurs?

@CodElixer
Copy link
Author

CodElixer commented Jun 1, 2022

So, it seems like MIUI doesn't use the MediaCodec API at all (which is what BCR uses for encoding). That must be where the overlapping issue is happening.

Oh! Then it seems might be using Android's AudioRecord API and Encoding using the LAME library.

  • And this might be patent encumbered in some countries.

By the way, a random thought I had: does MIUI have a battery power save mode? If it has a power save mode, does it make any difference for when the overlapping occurs?

Yes, I agree MIUI Power Save mode is aggressive. But when I was on MIUI Stock ROM then atleast call recording was working irrespective of Battery Power Save On/Off. There I wasn't using any external call recorder as it was internally supported.

But now I'm permanently moved to Pixel ROM (Android:12L) and here Google Dialer's default call recording is also working without any issues which is also recording in wav form!
IMG_20220601_085342.jpg

Just incase, This is the link of the Pixel ROM that I'm using.

chenxiaolong added a commit that referenced this issue Jun 1, 2022
This was previously disabled due to incorrect troubleshooting of an
issue where the `c2.android.flac.encoder` component would crash during
recording. It turns out the crash was caused by incorrect math:

    inputTimestamp += frames * 1000000 / audioRecord.sampleRate

`frames` and `1000000` are both 32-bit integers, so the multiplication
result overflowed and caused `inputTimestamp` (a 64-bit integer) to
accumulate negative values, which would crash the encoder. This bug was
inadvertently fixed during refactorying in commit
3d3eb82.

This commit reenables the submission of timestamps to MediaCodec. To
avoid accumulated error due to integer division when the microseconds
per sample count is not perfectly divisible, the recording loop will
keep track of the total frame count and only calculate the timestamp
during buffer submission.

This should fix issues where the encoded output files had overlapping
audio or other weird audible artifacts. These were caused by
MediaCodec's multithreaded encoding, where the lack of timestamps would
cause encoded samples to be produced out of order.

Fixes: #39 #54
Signed-off-by: Andrew Gunnerson <[email protected]>
chenxiaolong added a commit that referenced this issue Jun 1, 2022
This was previously disabled due to incorrect troubleshooting of an
issue where the `c2.android.flac.encoder` component would crash during
recording. It turns out the crash was caused by incorrect math:

    inputTimestamp += frames * 1000000 / audioRecord.sampleRate

`frames` and `1000000` are both 32-bit integers, so the multiplication
result overflowed and caused `inputTimestamp` (a 64-bit integer) to
accumulate negative values, which would crash the encoder. This bug was
inadvertently fixed during refactoring in commit
3d3eb82.

This commit reenables the submission of timestamps to MediaCodec. To
avoid accumulated error due to integer division when the microseconds
per sample count is not perfectly divisible, the recording loop will
keep track of the total frame count and only calculate the timestamp
during buffer submission.

This should fix issues where the encoded output files had overlapping
audio or other weird audible artifacts. These were caused by
MediaCodec's multithreaded encoding, where the lack of timestamps would
cause encoded samples to be produced out of order.

Fixes: #39 #54
Signed-off-by: Andrew Gunnerson <[email protected]>
@chenxiaolong
Copy link
Owner

Can you give the test build in #59 a try? I think I may have found the issue 🙂

@CodElixer
Copy link
Author

Can you give the test build in #59 a try? I think I may have found the issue 🙂

Whoa mate!! It's working perfectly.

Debugged All formats with native sample bitrate and flac with 8 level of compression and as of now it's seems working without any issues!!🎉

@chenxiaolong
Copy link
Owner

Awesome, thanks for testing and being patient with me while troubleshooting this issue!

It turns out it was a BCR bug and pretty easy to fix :D I'll release version 1.8 with this fix in a little bit.

chenxiaolong added a commit that referenced this issue Jun 1, 2022
This was previously disabled due to incorrect troubleshooting of an
issue where the `c2.android.flac.encoder` component would crash during
recording. It turns out the crash was caused by incorrect math:

    inputTimestamp += frames * 1000000 / audioRecord.sampleRate

`frames` and `1000000` are both 32-bit integers, so the multiplication
result overflowed and caused `inputTimestamp` (a 64-bit integer) to
accumulate negative values, which would crash the encoder. This bug was
inadvertently fixed during refactoring in commit
3d3eb82.

This commit reenables the submission of timestamps to MediaCodec. To
avoid accumulated error due to integer division when the microseconds
per sample count is not perfectly divisible, the recording loop will
keep track of the total frame count and only calculate the timestamp
during buffer submission.

This should fix issues where the encoded output files had overlapping
audio or other weird audible artifacts. These were caused by
MediaCodec's multithreaded encoding, where the lack of timestamps would
cause encoded samples to be produced out of order.

Fixes: #39 #54
Signed-off-by: Andrew Gunnerson <[email protected]>
@chenxiaolong
Copy link
Owner

Version 1.8 has been released!

@CodElixer
Copy link
Author

Awesome, thanks for testing and being patient with me while troubleshooting this issue!

No issues, Any time :)

It turns out it was a BCR bug and pretty easy to fix :D I'll release version 1.8 with this fix in a little bit.

Cheers!🎉

@chenxiaolong
Copy link
Owner

chenxiaolong commented Jun 1, 2022

I split out BCR's encoding step into a separate test app to make it a bit easier to test. Can you give this apk a try? MediaCodecAudioEncodeTest.zip

It should look something like this: Screenshot_20220601-131928

Can you try selecting a good .wav file and use this test app to convert to .flac? Does it still have overlapping audio?


EDIT: Please also try this BCR debug build with flac + native sample rate. Nothing was changed with the encoding code, I just added a bunch of things for debugging. BCR-1.8.r2.g6eda631-debug.zip

It should hopefully produce 3 files in the output directory:

  • <filename>.flac - Encoded recording (with overlapping)
  • <filename>.raw.wav - WAV recording (without overlapping)
  • <filename>.txt - Log file with debug information (the phone number, caller name, etc. should be automatically removed, but please verify 🙂)

Can you upload those?

@CodElixer
Copy link
Author

CodElixer commented Jun 2, 2022

Can you upload those?

Hi!
I'm sharing you all the output files in a single zip. You'll get 3 zip files inside the main zip, each will be having ReadMe.txt please read those txt files for description of the issues.

  • Following output files are attached:
    BCR-1.8.r2.g6eda631-debug
    BCR-1.8.r2.g03193a2-debug
    MediaCodec(Attached the original wav files too with it's encoded flac files).

https://easyupload.io/awwfv1

Hope this helps:)

@robertio
Copy link

robertio commented Jun 2, 2022

Hi Andrew,

Problem seems resolved in BCR-1.8.r2.g6eda631!

I also install BCR-1.8.r2.g6eda631-debug.zip on my Poco F2 Pro (K30 Pro) and debug files are here:
https://easyupload.io/m/l3whhz

But the main message, i have no error in OGG file (default settings)!
it is only 2 minutes 11 sec but no error! ill do longer tests now.

what did you change since official 1.8 ?

Best Regards,
Robert

@robertio
Copy link

robertio commented Jun 2, 2022

37 minutes long call with OGG 48kbps, 8000Hz has no error at all!
So i think you solved the issue with conversion.
:)
Thank you very much.

@chenxiaolong
Copy link
Owner

Thank you both for testing!

So from previous tests, we know that recording part was not the problem because the .wav (no encoding/compression) works fine. This is done via Android's AudioRecord API.

Then, what I suspected was Android's MediaCodec API, which handles the Opus/AAC/FLAC encoding, but that turned out not to be the case either. I made a test app to only perform the .wav to .flac conversion. From @YASHKRAJ's upload, I compared the wav and flac:

image

The top is the .wav, the middle is the .flac, and the bottom is the .flac subtracted from the .wav. Since it's empty, the audio in the two files are identical.

So, by itself, there's no problem in the recording and no problem in the encoding. BCR's recording process is essentially:

  • Loop until phone call ends:
    • Read audio from phone call into a buffer
    • Send raw audio to encoder
    • Write encoded audio to file

From @YASHKRAJ's log file, we have:

06-02 15:02:52.002 11167  3424 D RecorderThread: [691] Encoded 1755648 frames at 48000; submitting buffer with index: 2, size: 4608, timestamp: 36576000, buffer: [0..4608] -> [4608..4608]
06-02 15:02:52.794 11167  3424 D RecorderThread: [691] Encoded 1757952 frames at 48000; submitting buffer with index: 3, size: 4608, timestamp: 36624000, buffer: [0..4608] -> [4608..4608]

Looking at the log, the buffer is size: 4608. (4608 bytes) / (2 bytes per sample) / (48000 samples per second) = 0.048 seconds = 48ms. This means the call audio is recorded in 48ms chunks. The time it takes to encode each chunk must not take more than 48ms or else the audio will be broken. So this is really a CPU usage issue.

In the logs above, the chunk at timestamp: 36576000 (~36.6 seconds) was recorded at 15:02:52.002, but the next chunk wasn't recorded until 15:02:52.794. So that chunk took 792ms to encode... way more than the 48ms needed for a smooth recording. This matches what @YASHKRAJ said:

2nd test had issue at 36 second.

#61 improved the situation by using Android's API to determine what the best buffer/chunk size is. With a smaller buffer size, there's less data to encode each loop, so there's less of a chance of this issue happening.

The real fix is to move the encoding process to a different thread. That way, even if encoding is slow, it will not block the recording and won't cause dropped samples.


Right now, I'm planning:

  • Release version 1.9 with Rework buffering mechanism for recording #61. It doesn't fix the problem, but makes it better.
  • For version 1.10, add code to detect when audio samples are dropped. (Maybe send a notification if too many samples are dropped?) Also add a hidden option to produce a log file so I don't need to create debug builds for this.
  • For version 1.11, split recording and encoding into two separate threads. This should hopefully fix the problem for good.

The dropped frames from @YASHKRAJ's logs:

1. 20220602_145822.791+0530_out_198.txt - 0 drops (click to expand):
[20:15:04] cxl-desktop-1 …/All Debugs/BCR-1.8.r2.g6eda631-debug Outputs
❯ python ../../../process_log.py '1. 20220602_145822.791+0530_out_198.txt'
2. 20220602_150212.922+0530_out_198.txt - 2 drops (click to expand):
[20:15:31] cxl-desktop-1 …/All Debugs/BCR-1.8.r2.g6eda631-debug Outputs
❯ python ../../../process_log.py '2. 20220602_150212.922+0530_out_198.txt'
At 14.93s in the audio file, encoding took 177.0ms, max is 48.0ms
At 36.58s in the audio file, encoding took 792.0ms, max is 48.0ms 
3. 20220602_150802.947+0530_out_198.txt - 3 drops (click to expand):
[20:19:14] cxl-desktop-1 …/All Debugs/BCR-1.8.r2.g6eda631-debug Outputs
❯ python ../../../process_log.py '3. 20220602_150802.947+0530_out_198.txt'
At 17.28s in the audio file, encoding took 218.0ms, max is 48.0ms
At 26.54s in the audio file, encoding took 205.0ms, max is 48.0ms
At 48.82s in the audio file, encoding took 231.0ms, max is 48.0ms

The dropped frames from @robertio's logs:

20220602_174829.874+0200_out_1270.txt - 151 drops (click to expand):
[20:20:40] cxl-desktop-1 …/l3whhz/l3whhz_folder
❯ python ../../../process_log.py '20220602_174829.874+0200_out_1270.txt'
At 0.68s in the audio file, encoding took 105.0ms, max is 40.0ms
At 5.60s in the audio file, encoding took 71.0ms, max is 40.0ms
At 22.40s in the audio file, encoding took 74.0ms, max is 40.0ms
At 22.60s in the audio file, encoding took 72.0ms, max is 40.0ms
At 22.80s in the audio file, encoding took 72.0ms, max is 40.0ms
At 23.40s in the audio file, encoding took 72.0ms, max is 40.0ms
At 23.60s in the audio file, encoding took 72.0ms, max is 40.0ms
At 24.00s in the audio file, encoding took 71.0ms, max is 40.0ms
At 24.20s in the audio file, encoding took 71.0ms, max is 40.0ms
At 28.20s in the audio file, encoding took 72.0ms, max is 40.0ms
At 28.40s in the audio file, encoding took 71.0ms, max is 40.0ms
At 28.60s in the audio file, encoding took 78.0ms, max is 40.0ms
At 28.80s in the audio file, encoding took 74.0ms, max is 40.0ms
At 29.20s in the audio file, encoding took 74.0ms, max is 40.0ms
At 29.60s in the audio file, encoding took 75.0ms, max is 40.0ms
At 29.80s in the audio file, encoding took 72.0ms, max is 40.0ms
At 30.20s in the audio file, encoding took 73.0ms, max is 40.0ms
At 30.40s in the audio file, encoding took 71.0ms, max is 40.0ms
At 30.60s in the audio file, encoding took 72.0ms, max is 40.0ms
At 30.80s in the audio file, encoding took 71.0ms, max is 40.0ms
At 31.00s in the audio file, encoding took 72.0ms, max is 40.0ms
At 31.60s in the audio file, encoding took 74.0ms, max is 40.0ms
At 31.80s in the audio file, encoding took 74.0ms, max is 40.0ms
At 32.20s in the audio file, encoding took 71.0ms, max is 40.0ms
At 32.40s in the audio file, encoding took 72.0ms, max is 40.0ms
At 32.60s in the audio file, encoding took 72.0ms, max is 40.0ms
At 32.80s in the audio file, encoding took 72.0ms, max is 40.0ms
At 33.00s in the audio file, encoding took 71.0ms, max is 40.0ms
At 33.20s in the audio file, encoding took 74.0ms, max is 40.0ms
At 33.40s in the audio file, encoding took 78.0ms, max is 40.0ms
At 33.60s in the audio file, encoding took 73.0ms, max is 40.0ms
At 33.80s in the audio file, encoding took 73.0ms, max is 40.0ms
At 34.00s in the audio file, encoding took 73.0ms, max is 40.0ms
At 34.20s in the audio file, encoding took 73.0ms, max is 40.0ms
At 34.40s in the audio file, encoding took 73.0ms, max is 40.0ms
At 38.20s in the audio file, encoding took 71.0ms, max is 40.0ms
At 38.40s in the audio file, encoding took 74.0ms, max is 40.0ms
At 38.80s in the audio file, encoding took 75.0ms, max is 40.0ms
At 39.00s in the audio file, encoding took 73.0ms, max is 40.0ms
At 40.00s in the audio file, encoding took 71.0ms, max is 40.0ms
At 42.80s in the audio file, encoding took 73.0ms, max is 40.0ms
At 43.20s in the audio file, encoding took 71.0ms, max is 40.0ms
At 44.40s in the audio file, encoding took 72.0ms, max is 40.0ms
At 45.00s in the audio file, encoding took 71.0ms, max is 40.0ms
At 47.00s in the audio file, encoding took 71.0ms, max is 40.0ms
At 48.00s in the audio file, encoding took 71.0ms, max is 40.0ms
At 48.60s in the audio file, encoding took 71.0ms, max is 40.0ms
At 48.80s in the audio file, encoding took 75.0ms, max is 40.0ms
At 55.00s in the audio file, encoding took 71.0ms, max is 40.0ms
At 55.60s in the audio file, encoding took 71.0ms, max is 40.0ms
At 57.60s in the audio file, encoding took 72.0ms, max is 40.0ms
At 58.20s in the audio file, encoding took 71.0ms, max is 40.0ms
At 58.40s in the audio file, encoding took 71.0ms, max is 40.0ms
At 60.40s in the audio file, encoding took 78.0ms, max is 40.0ms
At 60.80s in the audio file, encoding took 71.0ms, max is 40.0ms
At 65.20s in the audio file, encoding took 73.0ms, max is 40.0ms
At 69.20s in the audio file, encoding took 72.0ms, max is 40.0ms
At 69.60s in the audio file, encoding took 72.0ms, max is 40.0ms
At 69.80s in the audio file, encoding took 73.0ms, max is 40.0ms
At 70.00s in the audio file, encoding took 74.0ms, max is 40.0ms
At 70.40s in the audio file, encoding took 71.0ms, max is 40.0ms
At 70.60s in the audio file, encoding took 71.0ms, max is 40.0ms
At 71.00s in the audio file, encoding took 73.0ms, max is 40.0ms
At 71.20s in the audio file, encoding took 72.0ms, max is 40.0ms
At 71.60s in the audio file, encoding took 72.0ms, max is 40.0ms
At 71.80s in the audio file, encoding took 72.0ms, max is 40.0ms
At 72.00s in the audio file, encoding took 73.0ms, max is 40.0ms
At 72.20s in the audio file, encoding took 73.0ms, max is 40.0ms
At 72.40s in the audio file, encoding took 72.0ms, max is 40.0ms
At 73.00s in the audio file, encoding took 75.0ms, max is 40.0ms
At 73.60s in the audio file, encoding took 73.0ms, max is 40.0ms
At 73.80s in the audio file, encoding took 73.0ms, max is 40.0ms
At 74.00s in the audio file, encoding took 72.0ms, max is 40.0ms
At 74.20s in the audio file, encoding took 71.0ms, max is 40.0ms
At 74.40s in the audio file, encoding took 71.0ms, max is 40.0ms
At 74.60s in the audio file, encoding took 72.0ms, max is 40.0ms
At 75.00s in the audio file, encoding took 73.0ms, max is 40.0ms
At 75.20s in the audio file, encoding took 73.0ms, max is 40.0ms
At 75.60s in the audio file, encoding took 74.0ms, max is 40.0ms
At 75.80s in the audio file, encoding took 72.0ms, max is 40.0ms
At 76.00s in the audio file, encoding took 72.0ms, max is 40.0ms
At 76.20s in the audio file, encoding took 74.0ms, max is 40.0ms
At 76.60s in the audio file, encoding took 72.0ms, max is 40.0ms
At 76.80s in the audio file, encoding took 74.0ms, max is 40.0ms
At 77.00s in the audio file, encoding took 73.0ms, max is 40.0ms
At 77.20s in the audio file, encoding took 71.0ms, max is 40.0ms
At 78.40s in the audio file, encoding took 74.0ms, max is 40.0ms
At 78.60s in the audio file, encoding took 72.0ms, max is 40.0ms
At 78.80s in the audio file, encoding took 72.0ms, max is 40.0ms
At 79.00s in the audio file, encoding took 77.0ms, max is 40.0ms
At 79.20s in the audio file, encoding took 71.0ms, max is 40.0ms
At 79.60s in the audio file, encoding took 72.0ms, max is 40.0ms
At 79.80s in the audio file, encoding took 73.0ms, max is 40.0ms
At 80.00s in the audio file, encoding took 73.0ms, max is 40.0ms
At 80.20s in the audio file, encoding took 73.0ms, max is 40.0ms
At 80.40s in the audio file, encoding took 73.0ms, max is 40.0ms
At 80.60s in the audio file, encoding took 73.0ms, max is 40.0ms
At 80.80s in the audio file, encoding took 75.0ms, max is 40.0ms
At 81.00s in the audio file, encoding took 71.0ms, max is 40.0ms
At 81.60s in the audio file, encoding took 72.0ms, max is 40.0ms
At 82.00s in the audio file, encoding took 74.0ms, max is 40.0ms
At 82.20s in the audio file, encoding took 72.0ms, max is 40.0ms
At 82.40s in the audio file, encoding took 71.0ms, max is 40.0ms
At 83.20s in the audio file, encoding took 71.0ms, max is 40.0ms
At 83.60s in the audio file, encoding took 73.0ms, max is 40.0ms
At 84.00s in the audio file, encoding took 73.0ms, max is 40.0ms
At 84.40s in the audio file, encoding took 73.0ms, max is 40.0ms
At 92.00s in the audio file, encoding took 72.0ms, max is 40.0ms
At 93.00s in the audio file, encoding took 71.0ms, max is 40.0ms
At 93.40s in the audio file, encoding took 74.0ms, max is 40.0ms
At 93.60s in the audio file, encoding took 71.0ms, max is 40.0ms
At 99.20s in the audio file, encoding took 71.0ms, max is 40.0ms
At 99.60s in the audio file, encoding took 73.0ms, max is 40.0ms
At 110.60s in the audio file, encoding took 73.0ms, max is 40.0ms
At 114.60s in the audio file, encoding took 71.0ms, max is 40.0ms
At 115.00s in the audio file, encoding took 75.0ms, max is 40.0ms
At 115.40s in the audio file, encoding took 72.0ms, max is 40.0ms
At 115.60s in the audio file, encoding took 71.0ms, max is 40.0ms
At 115.80s in the audio file, encoding took 71.0ms, max is 40.0ms
At 116.00s in the audio file, encoding took 72.0ms, max is 40.0ms
At 116.20s in the audio file, encoding took 75.0ms, max is 40.0ms
At 116.40s in the audio file, encoding took 72.0ms, max is 40.0ms
At 116.60s in the audio file, encoding took 73.0ms, max is 40.0ms
At 116.80s in the audio file, encoding took 72.0ms, max is 40.0ms
At 117.20s in the audio file, encoding took 71.0ms, max is 40.0ms
At 117.60s in the audio file, encoding took 72.0ms, max is 40.0ms
At 118.00s in the audio file, encoding took 71.0ms, max is 40.0ms
At 118.20s in the audio file, encoding took 72.0ms, max is 40.0ms
At 118.60s in the audio file, encoding took 80.0ms, max is 40.0ms
At 119.00s in the audio file, encoding took 72.0ms, max is 40.0ms
At 119.20s in the audio file, encoding took 74.0ms, max is 40.0ms
At 119.40s in the audio file, encoding took 72.0ms, max is 40.0ms
At 119.60s in the audio file, encoding took 71.0ms, max is 40.0ms
At 119.80s in the audio file, encoding took 71.0ms, max is 40.0ms
At 120.00s in the audio file, encoding took 71.0ms, max is 40.0ms
At 120.20s in the audio file, encoding took 73.0ms, max is 40.0ms
At 120.40s in the audio file, encoding took 71.0ms, max is 40.0ms
At 120.80s in the audio file, encoding took 73.0ms, max is 40.0ms
At 121.00s in the audio file, encoding took 72.0ms, max is 40.0ms
At 121.40s in the audio file, encoding took 74.0ms, max is 40.0ms
At 121.60s in the audio file, encoding took 76.0ms, max is 40.0ms
At 121.80s in the audio file, encoding took 75.0ms, max is 40.0ms
At 122.00s in the audio file, encoding took 73.0ms, max is 40.0ms
At 122.40s in the audio file, encoding took 73.0ms, max is 40.0ms
At 122.80s in the audio file, encoding took 73.0ms, max is 40.0ms
At 124.00s in the audio file, encoding took 72.0ms, max is 40.0ms
At 124.20s in the audio file, encoding took 74.0ms, max is 40.0ms
At 124.60s in the audio file, encoding took 74.0ms, max is 40.0ms
At 126.60s in the audio file, encoding took 72.0ms, max is 40.0ms
At 130.40s in the audio file, encoding took 73.0ms, max is 40.0ms
At 130.60s in the audio file, encoding took 72.0ms, max is 40.0ms

@robertio
Copy link

robertio commented Jun 3, 2022

Hi Andrew,

I don't fully understand the explanation you provided because I'm not a programmer, but very rarely seen so detailed, so clear precise explanation.
You do an awesome job!
Many thanks!

Question 1: I don't understand if my log shows 151 drops, why I don't hear any problem in ogg file?
Question 2: Why I don't have heard any jumps in my ogg file and YASHKRAJ still has?
Question 3: I also not understand, why audacity analysis didn't show the error at 36 second?
Question 4: As I said I don't fully understand, the problem and the encoding mechanism,
but if cpu resources could cause issues, then the maybe the approach should be changed.
Post process, or multi threads (as u wrote). I don't know which and how. :)
Please consider my phone -K30 Pro is very strong hardware.
Can it cause that I don't have jump/overlap issue with this BCR-1.8.r2.g6eda631-debug?

@chenxiaolong
Copy link
Owner

Thanks and no problem!

Question 1: I don't understand if my log shows 151 drops, why I don't hear any problem in ogg file?
Question 2: Why I don't have heard any jumps in my ogg file and YASHKRAJ still has?
...
Can it cause that I don't have jump/overlap issue with this BCR-1.8.r2.g6eda631-debug?

It might be because of how short the drops are. Yours only exceed the limit a lot more, but only by around 30-35ms and they're pretty consistent (no big jumps). Android can probably tolerate this. YASHKRAJ's had some that were >200ms over and one that was ~800ms over.

Question 3: I also not understand, why audacity analysis didn't show the error at 36 second?

The debug build recorded both .wav and .flac/.ogg at the same time. I did the analysis in audacity to prove that both of the files are identical, so the issue was not caused by a bug in the encoding process. The issue could be heard at 36 seconds in both files.

The CPU load caused by the encoding was slowing down the recording part too much that it affected both the raw audio and the encoded audio.

Question 4: As I said I don't fully understand, the problem and the encoding mechanism,
but if cpu resources could cause issues, then the maybe the approach should be changed.
Post process, or multi threads (as u wrote). I don't know which and how. :)

Yeah, post processing is not a bad idea either.

Please consider my phone -K30 Pro is very strong hardware.

Definitely! I don't think hardware is the issue. Real-time audio is just hard to get right :)

By the way, does your ROM have built-in screen recording with the "device audio and microphone" mode? Screenshot_20220603-004049 I'm curious if the audio is smooth in those recordings. It records almost exactly the same way as BCR's M4A/AAC mode, except it records from the microphone instead of a phone call.

@robertio
Copy link

robertio commented Jun 3, 2022

Hi Andrew,
Thanks for very clear explanations! I got it now.
I tried built in screen recorder with the proposed settings - and it was flowless, no jump or any issue.
So im waiting now to test anything you need.

@chenxiaolong
Copy link
Owner

It turns out MediaCodec is already multithreaded so no changes are needed there.

In version 1.10, I made one final change to give the recording thread a very high CPU priority. Not sure if it helps, but maybe :)

It seems like default OGG/Opus recording is already working well on your devices. I don't think there's anything else I can do to make it better for the slower codecs (eg. FLAC).

@AfridiShahriar
Copy link

Isn't it strange?
Bcz: on my device (with sdm732 - which is not that slow) other call recording apps (boldbeast/axet call rec) don't have this (overlapping audio) bug.
So, is it really a CPU related thing?
And, i tried flac/ops/flac - with least bit rates also, still mostly there was an overlapping...

N.B.: your BCR is very reliable regarding recording calls on A12. (While axet call rec mostly skip recoding calls on A12 devices, idk why)

And, no audio source issue in ur app (like some crappy apps uses mic to rec calls).

So, your app is robust.
Thanks for building it.

I only compared with other apps regarding the overlapping issue (not regarding reliability)

@CodElixer
Copy link
Author

CodElixer commented Jun 4, 2022

It seems like default OGG/Opus recording is already working well on your devices. I don't think there's anything else I can do to make it better for the slower codecs (eg. FLAC).

First of all thanks for continuosly working on this issue to resolve it!

What I'd found that v1.9 was very unstable, it had more audio drops in comparison to previous versions.

I always try to keep recordings in ogg format but on 1.10 version, When I recorded a 4min 2sec long call then the total duration was only of 2min 42sec and the audio issue started from 2min 24th sec whereas the Google's default recorder which records in wav format had recorded total of 4min 2sec call and it hasn't any audio drop issue.

@chenxiaolong
Copy link
Owner

chenxiaolong commented Jun 5, 2022

First of all thanks for continuosly working on this issue to resolve it!

No problem! I don't like giving up 🙂

So, your app is robust.
Thanks for building it.

Thank you!


I'm trying a slightly different approach this time. Does this debug build help at all? BCR-1.10.r9.g7c88a96-debug.zip (Please upload the audio and .log.txt file if possible.)

I significantly increased the buffer size for recording so that if encoding slows down, it can "absorb" the impact. It should hopefully be able to handle up to an 800ms slowdown spike without causing the overlapping audio (maybe!).

There should be no downside to doing this (the latency increases, but doesn't matter for recording purposes). Please let me know if this debug build is somehow worse than previous versions.

@AfridiShahriar
Copy link

AfridiShahriar commented Jun 5, 2022

1.log.txt
Btw, this time no overlapping happened!
Call duration and recoding duration is same.
I tested for a few calls, since v1.10, and, all of them are okay (16Khz, 24kbps m4a)

@CodElixer
Copy link
Author

No problem! I don't like giving up 🙂

Exactly! That's why we're still here on the path of resolving this issue :)


I'm trying a slightly different approach this time. Does this debug build help at all? BCR-1.10.r9.g7c88a96-debug.zip (Please upload the audio and .log.txt file if possible.)

Here are the some recordings which have issue and some haven't.
Please check the zip and read the prefix of file name and if it has text file then read that also for that folder.

Probability of the issue of recordings at 8000Hz sample rate has less comparatively.

  • Noticed in the BCR-1.10.r9.g7c88a96-debug build Native Sample Rate option was missing in all the codec option and WAV codec haven't any bitrate slider(don't remember if previously it had).

@chenxiaolong
Copy link
Owner

Thanks for the logs!

06-05 21:05:51.080 11968 27890 D RecorderThread/2442: AudioRecord minimum buffer size: 640

That is interesting. That buffer size is 1/3 of what it is on my Pixel. (I believe this is controlled by the vendor firmware, not by the ROM.)

Also, this is is interesting/weird from 20220605_210548.762+0530_out_198.log.txt. It's writing a .wav file, so there's no compression/encoding, but somehow, there's a bunch of:

<...> 199.XXXXXXms
<...> 399.XXXXXXms

There should be no reason it takes that long to write < 1KB to the output file.

Out of curiosity, do you have BCR configured to record to the internal storage or an SD card?


Noticed in the BCR-1.10.r9.g7c88a96-debug build Native Sample Rate option was missing in all the codec option

Ah yep, I forgot to mention this. That option had to be removed to be able to change the buffer size. Otherwise, it has to start recording once to detect the sample rate and then stop and restart again to set the buffer size (might cause a couple seconds at the beginning of the call to be lost).

and WAV codec haven't any bitrate slider(don't remember if previously it had).

This part is normal. WAV doesn't support compression, so there's nothing to configure.

@CodElixer
Copy link
Author

CodElixer commented Jun 6, 2022

Out of curiosity, do you have BCR configured to record to the internal storage or an SD card?

Recording in the SD Card.

@CodElixer
Copy link
Author

CodElixer commented Jun 6, 2022

I'd tried changing Recording Location previously in the initial builds of BCR but that time the issue was still there and so after that I haven't tried it.

But when now changed the location to default "storage/emulated/0/Android/data/com.chiller3.bcr/files" on latest v1.10 debug then till now I haven't faced the issue.

I'll test further if I found any issues or it just fixed the issue.

@robertio
Copy link

robertio commented Jun 6, 2022

Hi,

Still has jumps with BCR 1.10 and also with the BCR-1.10.r9.g7c88a96-debug.

  1. OGG - My log and oga file is here: https://easyupload.io/m/prurv7 - made with BCR-1.10.r9.g7c88a96-debug.
    First jumps at around ~20seconds.
    Call was 1 minute but recorded file is only 53 seconds.
    Settings: ogg/opus 48kbps, 12000Hz.

  2. WAV also has jumps. Log and wav is here: https://easyupload.io/m/t4pwa5- made with BCR-1.10.r9.g7c88a96-debug.
    First jumps at around ~10seconds.
    Call was 1:35 minute but recorded file is only 1:22 m.
    Settings: wav/pcm 8000Hz.

I save the record files here:
Screenshot_20220606-112910_BCR

but this only a virtual "external" -it is on the internal flash, -because my phone doesent have external SD at all.

@robertio
Copy link

robertio commented Jun 6, 2022

Hey!! Good news!
If i changed the file save folder to the default, then sounds the records works properly!!
As YASHKRAJ reported also.

But this is very strange in my case because i have only built in memory -no SD- so the filesystem speed should not change when i change the location, however the partitions format can be different.

Andrew: @chenxiaolong Do you need me to change back to debug and make some debug file?

@chenxiaolong
Copy link
Owner

Awesome! It seems like file:// works for both of you, so maybe this is Android's SAF (storage access framework) being slow for small writes.

I created a new debug build: BCR-1.10.r21.gbeb47e0-debug.zip

This build always records to the default file:// path initially and then moves the files to the selected output directory when the recording is complete.

@robertio
Copy link

robertio commented Jun 6, 2022

Hi,
This debug version has no jumps, -files sounds to perfect. :)
oga/txt
files moved to the choosen directory.

Great job! many thanks! :)

@CodElixer
Copy link
Author

Hi Andrew!

All previous changes to BCR as well as this debug build which tricked Android's SAF and which helped to store the recordings in the SD Card flawlessly.

BCR going to be the only winner in call recordings for latest Android Builds!

Cheers!

@chenxiaolong
Copy link
Owner

🎉 Fantastic, thanks for testing! I'll release version 1.11 after work today with these changes.

@robertio
Copy link

robertio commented Jun 7, 2022

It was finally solved, with lots of investigation and work.
Many thanks to you Andrew for fast actions, clear explanations, and never give up. i admire the way how you develop. :)

Many many thanks for this piece of diamond. it is one of the most valuable software on my phone. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants