Skip to content

Commit

Permalink
Add support for API 28
Browse files Browse the repository at this point in the history
There was only one API call, AudioFormat.getFrameSizeInBytes(), that
required at least API 29. It's trivial enough to reimplement that
function manually.

Fixes: #6
Signed-off-by: Andrew Gunnerson <chillermillerlong@hotmail.com>
  • Loading branch information
chenxiaolong committed May 22, 2022
1 parent edc0dc0 commit 7dcfb64
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 4 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ android {

defaultConfig {
applicationId = "com.chiller3.bcr"
minSdk = 29
minSdk = 28
targetSdk = 32
versionCode = 2
versionName = "1.1"
Expand Down
1 change: 0 additions & 1 deletion app/src/main/java/com/chiller3/bcr/Permissions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import android.net.Uri
import android.os.PowerManager
import android.provider.Settings
import androidx.core.content.ContextCompat
import androidx.core.os.BuildCompat

object Permissions {
val REQUIRED: Array<String> = arrayOf(Manifest.permission.RECORD_AUDIO)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class RecorderInCallService : InCallService(), RecorderThread.OnRecordingComplet
val state = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
call.details.state
} else {
@Suppress("DEPRECATION")
call.state
}

Expand Down
15 changes: 13 additions & 2 deletions app/src/main/java/com/chiller3/bcr/RecorderThread.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.annotation.SuppressLint
import android.content.Context
import android.media.*
import android.net.Uri
import android.os.Build
import android.os.ParcelFileDescriptor
import android.telecom.Call
import android.util.Log
Expand Down Expand Up @@ -199,7 +200,7 @@ class RecorderThread(
private fun encodeLoop(audioRecord: AudioRecord, codec: MediaCodec, channel: FileChannel) {
// This is the most we ever read from audioRecord, even if the codec input buffer is
// larger. This is purely for fast'ish cancellation and not for latency.
val maxSamplesInBytes = audioRecord.sampleRate / 10 * audioRecord.format.frameSizeInBytes
val maxSamplesInBytes = audioRecord.sampleRate / 10 * getFrameSize(audioRecord.format)

val inputTimestamp = 0L
var inputComplete = false
Expand Down Expand Up @@ -295,7 +296,7 @@ class RecorderThread(
// AOSP ignores this because FLAC compression is lossless, but just in case the system
// uses another FLAC encoder that requiress a non-dummy value (eg. 0), we'll just use
// the PCM s16le bitrate. It's an overestimation, but shouldn't cause any issues.
val bitRate = audioFormat.frameSizeInBytes * sampleRate / 8
val bitRate = getFrameSize(audioFormat) * sampleRate / 8

val format = MediaFormat()
format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_FLAC)
Expand All @@ -319,6 +320,16 @@ class RecorderThread(

return codec
}

private fun getFrameSize(audioFormat: AudioFormat): Int {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
audioFormat.frameSizeInBytes
} else{
// Hardcoded for Android 9 compatibility only
assert(ENCODING == AudioFormat.ENCODING_PCM_16BIT)
2 * audioFormat.channelCount
}
}
}

interface OnRecordingCompletedListener {
Expand Down

0 comments on commit 7dcfb64

Please sign in to comment.