Here we have the method that converts audio in AVAudioPCMBuffer
in PCM float 32 bit mono format to audio in ByteArray
in PCM int 16 bit mono format:
fun convertMonoPCMFloat32ToMonoPCMInt16(inputBuffer: AVAudioPCMBuffer, outputSampleRate: Double): ByteArray {
val floatChannelData = inputBuffer.floatChannelData!!
val frameLength = inputBuffer.frameLength.toInt()
val channelCount = inputBuffer.format.channelCount
val inputSampleRate = inputBuffer.format.sampleRate
val resampleRatio = inputSampleRate / outputSampleRate
val outputFrameLength = (frameLength.toDouble() / resampleRatio).toInt()
val outputSize = outputFrameLength * channelCount.toInt()
val outputBuffer = ByteArray(outputSize * 2) // 2 bytes per Int16 sample
var outputIndex = 0
for (outputFrame in 0 until outputFrameLength) {
val inputFrameFloat = outputFrame * resampleRatio
val inputFrame = inputFrameFloat.toInt()
val fraction = inputFrameFloat - inputFrame
for (channel in 0 until channelCount.toInt()) {
// Linear interpolation for resampling
val sample1 = floatChannelData[channel]!![inputFrame]
val sample2 = if (inputFrame + 1 < frameLength) floatChannelData[channel]!![inputFrame + 1] else sample1
val interpolatedSample = (1 - fraction) * sample1 + fraction * sample2
// Convert to Int16
val int16Sample = (interpolatedSample * Short.MAX_VALUE).toInt()
.coerceIn(Short.MIN_VALUE.toInt(), Short.MAX_VALUE.toInt()).toShort()
outputBuffer[outputIndex++] = int16Sample.toByte()
outputBuffer[outputIndex++] = (int16Sample.toInt() shr 8).toByte()
}
}
return outputBuffer
}
Telegram channel
If you still have any questions, feel free to ask me in the comments under this article or write me at promark33@gmail.com.
If I saved your day, you can support me 🤝