minor fmod cleanup

This commit is contained in:
qimiko committed 2024-01-18 19:06:31 -07:00
1 parent d1e239037b
commit 6a11b76903
3 files changed
+75 -57

No files matched your search

+48 -20
View File
@@ -1,26 +1,32 @@
package org.fmod
import android.media.AudioAttributes
import android.media.AudioFormat
import android.media.AudioManager
import android.media.AudioTrack
import android.os.Build
import android.util.Log
class AudioDevice {
private var mTrack: AudioTrack? = null
private fun fetchChannelConfigFromCount(i: Int): Int {
if (i == 1) {
return 2
private fun fetchChannelConfigFromCount(speakerCount: Int): Int {
return when (speakerCount) {
1 -> AudioFormat.CHANNEL_OUT_MONO
2 -> AudioFormat.CHANNEL_OUT_STEREO
6 -> AudioFormat.CHANNEL_OUT_5POINT1
8 -> AudioFormat.CHANNEL_OUT_7POINT1_SURROUND
else -> AudioFormat.CHANNEL_INVALID
}
if (i == 2) {
return 3
}
if (i == 6) {
return 252
}
return if (i == 8) 6396 else 0
}
fun init(i: Int, i2: Int, i3: Int, i4: Int): Boolean {
val fetchChannelConfigFromCount = fetchChannelConfigFromCount(i)
val minBufferSize = AudioTrack.getMinBufferSize(i2, fetchChannelConfigFromCount, 2)
fun init(channelCount: Int, sampleRateInHz: Int, sampleSize: Int, sampleCount: Int): Boolean {
val channelConfig = fetchChannelConfigFromCount(channelCount)
val minBufferSize = AudioTrack.getMinBufferSize(
sampleRateInHz,
channelConfig,
AudioFormat.ENCODING_PCM_16BIT
)
if (minBufferSize < 0) {
Log.w(
"fmod",
@@ -29,11 +35,33 @@ class AudioDevice {
} else {
Log.i("fmod", "AudioDevice::init : Min buffer size: $minBufferSize bytes")
}
val i5 = i3 * i4 * i * 2
val i6 = if (i5 > minBufferSize) i5 else minBufferSize
Log.i("fmod", "AudioDevice::init : Actual buffer size: $i6 bytes")
val realBufferSize = sampleSize * sampleCount * channelCount * 2
val bufferSize = minBufferSize.coerceAtLeast(realBufferSize)
Log.i("fmod", "AudioDevice::init : Actual buffer size: $bufferSize bytes")
return try {
val audioTrack = AudioTrack(3, i2, fetchChannelConfigFromCount, 2, i6, 1)
val attributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_GAME)
.build()
val format = AudioFormat.Builder()
.setChannelMask(channelConfig)
.setSampleRate(sampleRateInHz)
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.build()
val audioTrackBuilder = AudioTrack.Builder()
.setAudioAttributes(attributes)
.setAudioFormat(format)
.setBufferSizeInBytes(bufferSize)
.setTransferMode(AudioTrack.MODE_STREAM)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
audioTrackBuilder.setPerformanceMode(AudioTrack.PERFORMANCE_MODE_LOW_LATENCY)
}
val audioTrack = audioTrackBuilder.build()
mTrack = audioTrack
try {
audioTrack.play()
@@ -44,7 +72,7 @@ class AudioDevice {
mTrack = null
false
}
} catch (unused2: IllegalArgumentException) {
} catch (_: IllegalArgumentException) {
Log.e("fmod", "AudioDevice::init : AudioTrack creation caused IllegalArgumentException")
false
}
@@ -60,7 +88,7 @@ class AudioDevice {
mTrack = null
}
fun write(sArr: ShortArray?, i: Int) {
mTrack!!.write(sArr!!, 0, i)
fun write(sArr: ShortArray, size: Int) {
mTrack?.write(sArr, 0, size)
}
}
+16 -28
View File
@@ -5,7 +5,9 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.content.res.AssetManager
import android.media.AudioDeviceInfo
import android.media.AudioManager
import android.net.Uri
import android.os.Build
@@ -23,12 +25,10 @@ object FMOD {
@JvmStatic
fun init(context: Context?) {
gContext = context
if (context != null) {
gContext!!.registerReceiver(
gPluginBroadcastReceiver,
IntentFilter("android.intent.action.HEADSET_PLUG")
)
}
gContext?.registerReceiver(
gPluginBroadcastReceiver,
IntentFilter(Intent.ACTION_HEADSET_PLUG)
)
}
@JvmStatic
@@ -58,29 +58,21 @@ object FMOD {
val isBluetoothOn = isBluetoothOn()
Log.i(
"fmod",
"FMOD::supportsLowLatency : Low latency = $lowLatencyFlag, Pro Audio = $proAudioFlag, Bluetooth On = $isBluetoothOn, Acceptable Block Size = $z ($outputBlockSize)"
"FMOD::supportsLowLatency : Low latency = $lowLatencyFlag, Pro Audio = $proAudioFlag, Bluetooth On = $isBluetoothOn, Acceptable Block Size = $z ($outputBlockSize)"
)
return z && lowLatencyFlag && !isBluetoothOn
}
@JvmStatic
fun lowLatencyFlag(): Boolean {
if (Build.VERSION.SDK_INT < 5) {
return false
}
val context = gContext ?: return false
return context.packageManager.hasSystemFeature("android.hardware.audio.low_latency")
return context.packageManager.hasSystemFeature(PackageManager.FEATURE_AUDIO_LOW_LATENCY)
}
@JvmStatic
fun proAudioFlag(): Boolean {
if (Build.VERSION.SDK_INT < 5) {
return false
}
val context = gContext ?: return false
return context.packageManager.hasSystemFeature("android.hardware.audio.pro")
return context.packageManager.hasSystemFeature(PackageManager.FEATURE_AUDIO_PRO)
}
@JvmStatic
@@ -90,26 +82,18 @@ object FMOD {
@JvmStatic
fun getOutputSampleRate(): Int {
if (Build.VERSION.SDK_INT < 17) {
return 0
}
val context = gContext ?: return 0
val audioService = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
val property = audioService.getProperty("android.media.property.OUTPUT_SAMPLE_RATE")
val property = audioService.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)
return property?.toInt() ?: 0
}
@JvmStatic
fun getOutputBlockSize(): Int {
if (Build.VERSION.SDK_INT < 17) {
return 0
}
val context = gContext ?: return 0
val audioService = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
val property = audioService.getProperty("android.media.property.OUTPUT_FRAMES_PER_BUFFER")
val property = audioService.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER)
return property?.toInt() ?: 0
}
@@ -118,7 +102,11 @@ object FMOD {
fun isBluetoothOn(): Boolean {
val context = gContext ?: return false
val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
return audioManager.isBluetoothA2dpOn || audioManager.isBluetoothScoOn
val devices = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
return devices.any {
it.type == AudioDeviceInfo.TYPE_BLUETOOTH_A2DP || it.type == AudioDeviceInfo.TYPE_BLUETOOTH_SCO
}
}
@JvmStatic
+11 -9
View File
@@ -1,5 +1,6 @@
package org.fmod
import android.media.MediaCodec
import android.media.MediaCrypto
import android.media.MediaDataSource
import android.media.MediaExtractor
@@ -14,8 +15,7 @@ class MediaCodec {
var mCodecPtr: Long = 0
private var mCurrentOutputBufferIndex = -1
private var mDataSourceProxy: Any? = null
private var mDecoder: android.media.MediaCodec? = null
private var mDecoder: MediaCodec? = null
private var mExtractor: MediaExtractor? = null
private var mInputBuffers: Array<ByteBuffer>? = null
private var mInputFinished = false
@@ -57,7 +57,7 @@ class MediaCodec {
)
if (string == "audio/mp4a-latm") {
return try {
mDecoder = android.media.MediaCodec.createDecoderByType(string)
mDecoder = MediaCodec.createDecoderByType(string)
mExtractor!!.selectTrack(i2)
mDecoder!!.configure(trackFormat, null as Surface?, null as MediaCrypto?, 0)
mDecoder!!.start()
@@ -100,7 +100,7 @@ class MediaCodec {
}
}
fun read(bArr: ByteArray?, i: Int): Int {
fun read(bArr: ByteArray, i: Int): Int {
var dequeueInputBuffer = 0
val i2 =
if (!mInputFinished || !mOutputFinished || mCurrentOutputBufferIndex != -1) 0 else -1
@@ -129,14 +129,14 @@ class MediaCodec {
mCurrentOutputBufferIndex = dequeueOutputBuffer
mOutputBuffers!![dequeueOutputBuffer].limit(bufferInfo.size)
mOutputBuffers!![dequeueOutputBuffer].position(bufferInfo.offset)
} else if (dequeueOutputBuffer == -3) {
} else if (dequeueOutputBuffer == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
mOutputBuffers = mDecoder!!.outputBuffers
} else if (dequeueOutputBuffer == -2) {
} else if (dequeueOutputBuffer == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
Log.d(
"fmod",
"MediaCodec::read : MediaCodec::dequeueOutputBuffer returned MediaCodec.INFO_OUTPUT_FORMAT_CHANGED " + mDecoder!!.outputFormat
)
} else if (dequeueOutputBuffer == -1) {
} else if (dequeueOutputBuffer == MediaCodec.INFO_TRY_AGAIN_LATER) {
Log.d(
"fmod",
"MediaCodec::read : MediaCodec::dequeueOutputBuffer returned MediaCodec.INFO_TRY_AGAIN_LATER."
@@ -147,7 +147,7 @@ class MediaCodec {
"MediaCodec::read : MediaCodec::dequeueOutputBuffer returned $dequeueOutputBuffer"
)
}
if (bufferInfo.flags and 4 !== 0) {
if (bufferInfo.flags and MediaCodec.BUFFER_FLAG_END_OF_STREAM != 0) {
mOutputFinished = true
}
}
@@ -188,13 +188,15 @@ class MediaCodec {
}
val bArr = ByteArray(1024)
while (i3 > 0) {
i3 -= read(bArr, Math.min(1024, i3))
i3 -= read(bArr, 1024.coerceAtMost(i3))
}
}
companion object {
@JvmStatic
external fun fmodGetSize(j: Long): Long
@JvmStatic
external fun fmodReadAt(j: Long, j2: Long, bArr: ByteArray?, i: Int, i2: Int): Int
}
}