implement MidiPlayer for android
This commit is contained in:
parent
2f0be71dd8
commit
d25753aee4
1 changed files with 94 additions and 81 deletions
|
|
@ -1,129 +1,142 @@
|
|||
package mg.dot.feufaro.midi
|
||||
|
||||
import java.io.File
|
||||
import android.media.MediaPlayer
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
|
||||
private var androidMediaPlayer: MediaPlayer?= null
|
||||
|
||||
actual class MediaPlayer actual constructor(filename: String, onFinished: () -> Unit) {
|
||||
private val player = androidMediaPlayer?.apply {
|
||||
setDataSource(filename)
|
||||
prepare()
|
||||
setOnCompletionListener {
|
||||
seekTo(0)
|
||||
onFinished()
|
||||
}
|
||||
// val file = File(android.app.Instrumentation().context.filesDir, filename)
|
||||
// if(file.exists()){
|
||||
// androidMediaPlayer?.setDataSource(file.path)
|
||||
// androidMediaPlayer?.prepare()
|
||||
// androidMediaPlayer?.setOnCompletionListener {
|
||||
// onFinished()
|
||||
// }
|
||||
// } else {
|
||||
// println("Fichier midi non trouvée")
|
||||
// }
|
||||
}
|
||||
private var mediaPlayer: MediaPlayer? = MediaPlayer()
|
||||
private val voiceStates = mutableListOf(true, true, true, true)
|
||||
private var currentGlobalVolume: Float = 0.8f
|
||||
// private var currentGlobalVolume: Float = 0.8f
|
||||
|
||||
private var pointA: Long = -1L
|
||||
private var pointB: Long = -1L
|
||||
|
||||
private val playerScope = CoroutineScope(Dispatchers.Default + SupervisorJob())
|
||||
private var abJob: Job? = null
|
||||
|
||||
private var isLoopingAB: Boolean = false
|
||||
|
||||
init {
|
||||
try {
|
||||
val file = File(filename)
|
||||
if (file.exists()) {
|
||||
val fis = FileInputStream(file)
|
||||
mediaPlayer?.setDataSource(fis.fd)
|
||||
mediaPlayer?.prepare()
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
||||
val params = mediaPlayer?.playbackParams ?: android.media.PlaybackParams()
|
||||
params.speed = 1.0f
|
||||
mediaPlayer?.playbackParams = params
|
||||
}
|
||||
fis.close()
|
||||
|
||||
mediaPlayer?.setOnCompletionListener {
|
||||
onFinished()
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
actual fun play() {
|
||||
// player?.start()
|
||||
mediaPlayer?.start()
|
||||
}
|
||||
actual fun pause() {
|
||||
// player?.pause()
|
||||
mediaPlayer?.pause()
|
||||
}
|
||||
actual fun stop() {
|
||||
// player?.stop()
|
||||
mediaPlayer?.stop()
|
||||
mediaPlayer?.prepare()
|
||||
mediaPlayer?.seekTo(0)
|
||||
clearLoop()
|
||||
}
|
||||
|
||||
actual fun getDuration(): Long {
|
||||
// player!!.duration.toLong() ?: 0L
|
||||
return 4.toLong()
|
||||
return mediaPlayer?.duration?.toLong() ?: 0L
|
||||
}
|
||||
|
||||
actual fun getCurrentPosition(): Long {
|
||||
// player!!.currentPosition.toLong()
|
||||
return 4.toLong()
|
||||
return mediaPlayer?.currentPosition?.toLong() ?: 0L
|
||||
}
|
||||
|
||||
actual fun seekTo(position: Long) {
|
||||
// player!!.seekTo(position.toInt())
|
||||
mediaPlayer?.seekTo(position.toInt())
|
||||
}
|
||||
actual fun setVolume(level: Float) {
|
||||
mediaPlayer?.setVolume(level, level)
|
||||
}
|
||||
|
||||
actual fun setVolume(level: Float){
|
||||
// currentGlobalVolume =level
|
||||
// player?.setVolume(level, level)
|
||||
actual fun setPointA() {
|
||||
pointA = mediaPlayer?.currentPosition?.toLong() ?: 0L
|
||||
}
|
||||
|
||||
actual fun getLoopState() = Triple(pointA, pointB, isLoopingAB)
|
||||
|
||||
actual fun toggleVoice(index: Int): Unit{
|
||||
voiceStates[index] = !voiceStates[index]
|
||||
}
|
||||
|
||||
actual fun getVoiceStates(): List<Boolean> = voiceStates
|
||||
|
||||
actual fun changeInstru(noInstru: Int): Unit{
|
||||
|
||||
}
|
||||
|
||||
actual fun setPointA(): Unit{
|
||||
// pointA = getCurrentPosition()
|
||||
}
|
||||
|
||||
actual fun setPointB(): Unit{
|
||||
pointB = getCurrentPosition()
|
||||
if(pointB > pointA) {
|
||||
actual fun setPointB() {
|
||||
pointB = mediaPlayer?.currentPosition?.toLong() ?: 0L
|
||||
if (pointB > pointA && pointA != -1L) {
|
||||
isLoopingAB = true
|
||||
startABMonitor()
|
||||
}
|
||||
}
|
||||
|
||||
actual fun clearLoop(): Unit{
|
||||
actual fun clearLoop() {
|
||||
isLoopingAB = false
|
||||
pointA = -1L
|
||||
pointB = -1L
|
||||
abJob?.cancel()
|
||||
}
|
||||
private fun startABMonitor(){
|
||||
GlobalScope.launch {
|
||||
while(isLoopingAB){
|
||||
// if ((player?.currentPosition ?: 0) >= pointB){
|
||||
// player?.seekTo(pointA?.toInt())
|
||||
// }
|
||||
|
||||
private fun startABMonitor() {
|
||||
abJob?.cancel()
|
||||
abJob = playerScope.launch {
|
||||
while (isLoopingAB) {
|
||||
val currentPos = mediaPlayer?.currentPosition?.toLong() ?: 0L
|
||||
if (currentPos >= pointB) {
|
||||
mediaPlayer?.seekTo(pointA.toInt())
|
||||
}
|
||||
delay(50)
|
||||
}
|
||||
}
|
||||
}
|
||||
actual fun setTempo(factor: Float){
|
||||
|
||||
actual fun getLoopState() = Triple(pointA, pointB, isLoopingAB)
|
||||
actual fun toggleVoice(index: Int) {
|
||||
voiceStates[index] = !voiceStates[index]
|
||||
println("Toggle voice $index (Limitation: Nécessite SoundFont/Fluidsynth sur Android)")
|
||||
}
|
||||
|
||||
actual fun getVoiceStates(): List<Boolean> = voiceStates
|
||||
|
||||
actual fun changeInstru(noInstru: Int) {
|
||||
}
|
||||
|
||||
actual fun setTempo(factor: Float) {
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
||||
mediaPlayer?.let {
|
||||
val params = it.playbackParams
|
||||
params.speed = factor
|
||||
it.playbackParams = params
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
actual fun getCurrentBPM(): Float {
|
||||
return 120f
|
||||
}
|
||||
}
|
||||
/*
|
||||
actual fun MidiPlayer(filename: String, onFinished: () -> Unit) {
|
||||
StopMidi()
|
||||
val file = File(android.app.Instrumentation().context.filesDir, filename)
|
||||
if(file.exists()){
|
||||
androidMediaPlayer?.setDataSource(file.path)
|
||||
androidMediaPlayer?.prepare()
|
||||
androidMediaPlayer?.setOnCompletionListener {
|
||||
onFinished()
|
||||
}
|
||||
androidMediaPlayer?.start()
|
||||
}
|
||||
}
|
||||
|
||||
actual fun StopMidi() {
|
||||
androidMediaPlayer?.let {
|
||||
if (it.isPlaying) {
|
||||
it.stop()
|
||||
it.release()
|
||||
}
|
||||
fun release() {
|
||||
mediaPlayer?.release()
|
||||
mediaPlayer = null
|
||||
playerScope.coroutineContext.cancel()
|
||||
}
|
||||
androidMediaPlayer = null
|
||||
}*/
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue