feat: LibPasada player using stretcher

This commit is contained in:
2026-06-03 18:13:55 +02:00
parent 922cc5d82a
commit 096c676ce2
6 changed files with 89 additions and 2 deletions

View File

@@ -21,7 +21,7 @@ public final class LibPasada {
if (loaded) {
return;
}
System.loadLibrary("pasada");
System.loadLibrary("lockstep-native");
loaded = true;
}
@@ -72,4 +72,7 @@ public final class LibPasada {
/** Register listener for async events raised from the audio/native thread. */
public static native void setPlaybackListener(PasadaPlaybackListener listener);
/** native version string */
public static native String getVersion();
}

View File

@@ -9,6 +9,8 @@ public interface PasadaPlaybackListener {
/** Current track reached end; service should advance queue and call {@link LibPasada#play}. */
void onTrackFinished();
void onTrackClosed(int fd);
/** Decode / Oboe / pipeline failure; service should stop safely and surface error. */
void onError(int errorCode, String message);
}

View File

@@ -17,6 +17,7 @@ import at.lockstep.player.LockstepApplication
import at.lockstep.player.MainActivity
import at.lockstep.player.R
import at.lockstep.player.playback.engine.ExoPlayerMusicPlayerEngine
import at.lockstep.player.playback.engine.PasadaMusicPlayerEngine
import at.lockstep.player.playback.engine.MusicPlayerEngine
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -204,7 +205,8 @@ class PlaybackService : Service() {
engine?.let {
return it
}
return ExoPlayerMusicPlayerEngine(this)
//return ExoPlayerMusicPlayerEngine(this)
return PasadaMusicPlayerEngine(this)
.also {
it.setListener(engineListener)
it.initSession()

View File

@@ -6,6 +6,7 @@ import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.os.ParcelFileDescriptor
import android.util.Log
import at.lockstep.player.pasada.LibPasada
import at.lockstep.player.pasada.PasadaPlaybackListener
import java.io.IOException
@@ -35,12 +36,18 @@ class PasadaMusicPlayerEngine(
private val nativeListener =
object : PasadaPlaybackListener {
override fun onTrackFinished() {
Log.i(TAG, "PasadaPlaybackListener.onTrackFinished()")
pendingStart = false
mainHandler.post {
listener?.onPlaybackEnded()
}
}
override fun onTrackClosed(fd: Int) {
Log.i(TAG, "onTrackClosed: native returned fd=$fd")
// we handle parcel close() separately
}
override fun onError(
errorCode: Int,
message: String,
@@ -51,13 +58,18 @@ class PasadaMusicPlayerEngine(
}
}
val TAG = "PasadaMusicPlayerEngine"
override fun initSession() {
if (sessionInitialized) {
return
}
Log.i(TAG, "LibPasada.loadNative() ...")
LibPasada.loadNative()
LibPasada.setPlaybackListener(nativeListener)
Log.i(TAG, "LibPasada.init() ...")
LibPasada.init()
Log.i(TAG, "LibPasada.init() done.")
sessionInitialized = true
}
@@ -131,7 +143,9 @@ class PasadaMusicPlayerEngine(
private fun startPendingTrack() {
val fd = trackFd ?: return
Log.i(TAG, "LibPasada.play(fd=$fd, offset=$trackOffset, length=$trackLength) ...")
LibPasada.play(fd, trackOffset, trackLength)
Log.i(TAG, "LibPasada.play() done.")
pendingStart = false
}

View File

@@ -0,0 +1,64 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.rex.logger;
import android.util.Log;
//import proguard.annotation.KeepName;
//@KeepName
/**
* Gather native log into logback, for easy control save log into SDCard
*/
public class NdkLogger {
private static final String TAG = "NDK";
//@KeepName
public static void logWrite(int level, String message) {
//sLogger.trace("level:{} message:{}", level, message);
switch (level) {
case Log.VERBOSE:
Log.v(TAG, message);
break;
case Log.DEBUG:
Log.d(TAG, message);
break;
case Log.INFO:
Log.i(TAG, message);
break;
case Log.WARN:
Log.w(TAG, message);
break;
case Log.ERROR:
Log.e(TAG, message);
break;
}
}
static {
try {
System.loadLibrary("ndk-logger");
} catch (UnsatisfiedLinkError ex) {
Log.e(TAG, "Failed to load library.", ex);
}
}
public static String getABI() { return native_getABI(); }
private static native String native_getABI();
}