11package io.github.lemcoder.mikrosoundfont.internal
22
3+ import io.github.lemcoder.mikrosoundfont.Channel
4+ import io.github.lemcoder.mikrosoundfont.SoundFont
35import kotlinx.cinterop.CPointer
46import kotlinx.cinterop.ExperimentalForeignApi
5- import kotlinx.cinterop.refTo
7+ import kotlinx.cinterop.memScoped
8+ import kotlinx.cinterop.readBytes
69import kotlinx.cinterop.reinterpret
710import kotlinx.cinterop.toCValues
811import kotlinx.cinterop.toKString
9- import io.github.lemcoder.mikrosoundfont.Channel
10- import io.github.lemcoder.mikrosoundfont.SoundFont
12+ import platform.posix.malloc
1113import tinySoundFont.TSFOutputMode
1214import tinySoundFont.tsf_active_voice_count
1315import tinySoundFont.tsf_bank_get_presetname
@@ -87,9 +89,11 @@ internal class SoundFontDelegate : SoundFont {
8789 return withSoundFont {
8890 val tsfMode = when (outputMode) {
8991 SoundFont .OutputMode .TSF_STEREO_INTERLEAVED -> TSFOutputMode .TSF_STEREO_INTERLEAVED
90- SoundFont .OutputMode .TSF_STEREO_UNWEAVED -> TSFOutputMode .TSF_STEREO_UNWEAVED
91- SoundFont .OutputMode .TSF_MONO -> TSFOutputMode .TSF_MONO
92+ SoundFont .OutputMode .TSF_STEREO_UNWEAVED -> TSFOutputMode .TSF_STEREO_UNWEAVED
93+ SoundFont .OutputMode .TSF_MONO -> TSFOutputMode .TSF_MONO
9294 }
95+
96+ tsf_set_output(it.reinterpret(), tsfMode, sampleRate, globalGainDb)
9397 }
9498 }
9599
@@ -149,13 +153,28 @@ internal class SoundFontDelegate : SoundFont {
149153
150154 override fun renderFloat (samples : Int , channels : Int , isMixing : Boolean ): FloatArray {
151155 return withSoundFont {
152- val buffer = FloatArray (samples * channels)
153- val flagMixing = if (isMixing) 1 else 0
154- tsf_render_float(it.reinterpret(), buffer.refTo(0 ), samples, flagMixing)
155- buffer
156+ memScoped {
157+ val buffer = malloc((samples * channels * Float .SIZE_BYTES ).toULong()) ? : return @withSoundFont floatArrayOf()
158+ val flagMixing = if (isMixing) 1 else 0
159+ tsf_render_float(it.reinterpret(), buffer.reinterpret(), samples, flagMixing)
160+
161+ val bytes = buffer.readBytes(samples * channels * Float .SIZE_BYTES )
162+
163+ bytes.toFloatArray()
164+ }
156165 }
157166 }
158167
159168 private fun <T > withSoundFont (block : (soundFont: CPointer <* >) -> T ): T =
160169 this .soundFont.let (block) ? : throw IllegalStateException (" SoundFont not loaded" )
170+
171+ private fun ByteArray.toFloatArray (): FloatArray {
172+ return FloatArray (size / Float .SIZE_BYTES ) { index ->
173+ val intBits = (this [index * Float .SIZE_BYTES ].toInt() and 0xFF ) or
174+ ((this [index * Float .SIZE_BYTES + 1 ].toInt() and 0xFF ) shl 8 ) or
175+ ((this [index * Float .SIZE_BYTES + 2 ].toInt() and 0xFF ) shl 16 ) or
176+ ((this [index * Float .SIZE_BYTES + 3 ].toInt() and 0xFF ) shl 24 )
177+ Float .fromBits(intBits)
178+ }
179+ }
161180}
0 commit comments