KMP IOS convert PCM int 16 bit to PCM float 32 bit

This code is for converting audio in ByteArray in PCM int 16 bit mono format to audio in ABAudioPCMBuffer in PCM float 32 bit stereo format:

fun convertMonoPCMInt16ToStereoPCMFloat32(
        inputData: ByteArray, inputSampleRate: Double, outputSampleRate: Double
    ): AVAudioPCMBuffer? {
        val inputFrameLength = inputData.size / 2  // 2 bytes per Int16 sample
        val resampleRatio = outputSampleRate / inputSampleRate
        val outputFrameLength = (inputFrameLength * resampleRatio).toInt()

        val audioFormat = AVAudioFormat(standardFormatWithSampleRate = outputSampleRate, channels = 2u)
        val outputBuffer = AVAudioPCMBuffer(audioFormat, frameCapacity = outputFrameLength.toUInt()) ?: return null

        val leftChannel = outputBuffer.floatChannelData!![0]
        val rightChannel = outputBuffer.floatChannelData!![1]

        for (outputFrame in 0 until outputFrameLength) {
            val inputFrameFloat = outputFrame / resampleRatio
            val inputFrame = inputFrameFloat.toInt()
            val fraction = inputFrameFloat - inputFrame

            val sample1 = readInt16Sample(inputData, inputFrame, inputFrameLength)
            val sample2 = readInt16Sample(inputData, inputFrame + 1, inputFrameLength)
            val interpolatedSample = (1 - fraction) * sample1 + fraction * sample2

            // Convert to Float and apply gain control
            val floatSample = (interpolatedSample / Short.MAX_VALUE.toFloat()) * 0.7f  // Apply -3dB attenuation

            // Duplicate to stereo
            leftChannel!![outputFrame] = floatSample.toFloat()
            rightChannel!![outputFrame] = floatSample.toFloat()
        }

        outputBuffer.frameLength = outputFrameLength.toUInt()
        return outputBuffer
    }

    private fun readInt16Sample(inputData: ByteArray, index: Int, length: Int): Int {
        if (index >= length) return 0
        val low = inputData[index * 2].toInt() and 0xFF
        val high = inputData[index * 2 + 1].toInt()
        return (high shl 8) or low
    }

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 🤝