Convert PCM int16 to float32 iOS
What's inside this article
⌄
- KMP IOS convert PCM int 16bit to PCM float 32bit
- PCM int16 to float32 IOS
- Kotlin Multiplatform PCM conversion
- IOS audio format conversion KMP
- Convert PCM audio format IOS
This code is for converting audio in ByteArray in PCM int 16bit mono format to audio in ABAudioPCMBuffer in PCM float 32bit stereo format:
1fun convertMonoPCMInt16ToStereoPCMFloat32(
2 inputData: ByteArray, inputSampleRate: Double, outputSampleRate: Double
3 ): AVAudioPCMBuffer? {
4 val inputFrameLength = inputData.size / 2 // 2 bytes per Int16 sample
5 val resampleRatio = outputSampleRate / inputSampleRate
6 val outputFrameLength = (inputFrameLength * resampleRatio).toInt()
7
8 val audioFormat = AVAudioFormat(standardFormatWithSampleRate = outputSampleRate, channels = 2u)
9 val outputBuffer = AVAudioPCMBuffer(audioFormat, frameCapacity = outputFrameLength.toUInt()) ?: return null
10
11 val leftChannel = outputBuffer.floatChannelData!![0]
12 val rightChannel = outputBuffer.floatChannelData!![1]
13
14 for (outputFrame in 0 until outputFrameLength) {
15 val inputFrameFloat = outputFrame / resampleRatio
16 val inputFrame = inputFrameFloat.toInt()
17 val fraction = inputFrameFloat - inputFrame
18
19 val sample1 = readInt16Sample(inputData, inputFrame, inputFrameLength)
20 val sample2 = readInt16Sample(inputData, inputFrame + 1, inputFrameLength)
21 val interpolatedSample = (1 - fraction) * sample1 + fraction * sample2
22
23 // Convert to Float and apply gain control
24 val floatSample = (interpolatedSample / Short.MAX_VALUE.toFloat()) * 0.7f // Apply -3dB attenuation
25
26 // Duplicate to stereo
27 leftChannel!![outputFrame] = floatSample.toFloat()
28 rightChannel!![outputFrame] = floatSample.toFloat()
29 }
30
31 outputBuffer.frameLength = outputFrameLength.toUInt()
32 return outputBuffer
33 }
34
35 private fun readInt16Sample(inputData: ByteArray, index: Int, length: Int): Int {
36 if (index >= length) return 0
37 val low = inputData[index * 2].toInt() and 0xFF
38 val high = inputData[index * 2 + 1].toInt()
39 return (high shl 8) or low
40 }
41}