feat: audio resources
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
#include "PlaybackEngine.h"
|
||||
#include "logging.h"
|
||||
|
||||
PlaybackEngine::PlaybackEngine() {
|
||||
PlaybackEngine::PlaybackEngine(std::string filesDir): mFilesDir(filesDir) {
|
||||
LOGI("PlaybackEngine()");
|
||||
LOGI("NDK LOG_LEVEL=%d", LOG_LEVEL);
|
||||
// NDK LOG_LEVEL=3 (DEBUG)
|
||||
|
||||
@@ -6,13 +6,15 @@
|
||||
#define LOCKSTEP_PLAYBACKENGINE_H
|
||||
|
||||
#include "OboeSinePlayer.h"
|
||||
#include <string>
|
||||
|
||||
class PlaybackEngine {
|
||||
public:
|
||||
PlaybackEngine();
|
||||
PlaybackEngine(std::string filesDir);
|
||||
virtual ~PlaybackEngine();
|
||||
private:
|
||||
OboeSinePlayer *mPlayer;
|
||||
std::string mFilesDir;
|
||||
};
|
||||
|
||||
#endif //LOCKSTEP_PLAYBACKENGINE_H
|
||||
|
||||
@@ -4,9 +4,12 @@
|
||||
|
||||
#include <jni.h>
|
||||
#include "mpg123.h"
|
||||
#include <oboe/Oboe.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
// nice-to: merge with lockstep.cpp
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_at_lockstep_pb_PlaybackEngine_native_1mpg123_1init
|
||||
(JNIEnv *env, jclass) {
|
||||
|
||||
@@ -30,15 +30,13 @@ extern "C" {
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_at_lockstep_pb_PlaybackEngine_native_1createEngine(
|
||||
JNIEnv *env,
|
||||
jclass /*unused*/) {
|
||||
/*
|
||||
jclass /*unused*/, jstring filesDir) {
|
||||
const char* filesDirTemp = env->GetStringUTFChars(filesDir, NULL);
|
||||
std::string filesDirString(filesDirTemp);
|
||||
env->ReleaseStringUTFChars(filesDir, filesDirTemp);
|
||||
*/
|
||||
|
||||
// We use std::nothrow so `new` returns a nullptr if the engine creation fails
|
||||
auto *engine = new(std::nothrow) PlaybackEngine();
|
||||
auto *engine = new(std::nothrow) PlaybackEngine(filesDirString);
|
||||
return reinterpret_cast<jlong>(engine);
|
||||
}
|
||||
|
||||
@@ -51,4 +49,13 @@ jlong engineHandle) {
|
||||
delete reinterpret_cast<PlaybackEngine *>(engineHandle);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_at_lockstep_pb_PlaybackEngine_native_1setDefaultStreamValues(JNIEnv *env,
|
||||
jclass type,
|
||||
jint sampleRate,
|
||||
jint framesPerBurst) {
|
||||
oboe::DefaultStreamValues::SampleRate = (int32_t) sampleRate;
|
||||
oboe::DefaultStreamValues::FramesPerBurst = (int32_t) framesPerBurst;
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
60
app/src/main/java/at/lockstep/pb/AudioResources.java
Normal file
60
app/src/main/java/at/lockstep/pb/AudioResources.java
Normal file
@@ -0,0 +1,60 @@
|
||||
package at.lockstep.pb;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import at.lockstep.R;
|
||||
|
||||
/**
|
||||
* Resource helpers.
|
||||
*
|
||||
* @author David Madl (git@abanbytes.eu)
|
||||
* @date 2020-05-16
|
||||
*/
|
||||
public class AudioResources {
|
||||
/**
|
||||
* Copy raw tracks to filesystem:
|
||||
* otherwise, packaged resources cannot directly be accessed from C code.
|
||||
*/
|
||||
public static void copyRawTracksToFilesystem(Context context) throws IOException {
|
||||
Field[] fields = R.raw.class.getFields();
|
||||
long before = SystemClock.uptimeMillis();
|
||||
try {
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
String assetName = fields[i].getName();
|
||||
if (assetName.startsWith("track_")) {
|
||||
int resourceId = fields[i].getInt(null);
|
||||
copyFileUsingStream(context.getResources().openRawResource(resourceId), new File(context.getFilesDir() + "/" + resourceId + ".mp3"));
|
||||
}
|
||||
}
|
||||
} catch(IllegalAccessException iae) {
|
||||
// reflection should always work on R.raw
|
||||
iae.printStackTrace();
|
||||
}
|
||||
long after = SystemClock.uptimeMillis();
|
||||
Log.i("LoadTracks", String.format("copyRawTracksToFilesystem() took %.3f s", ((float)(after-before))/1e3f));
|
||||
}
|
||||
|
||||
private static void copyFileUsingStream(InputStream is, File dest) throws IOException {
|
||||
OutputStream os = null;
|
||||
try {
|
||||
os = new FileOutputStream(dest);
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = is.read(buffer)) > 0) {
|
||||
os.write(buffer, 0, length);
|
||||
}
|
||||
} finally {
|
||||
is.close();
|
||||
os.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,16 @@
|
||||
package at.lockstep.pb;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Build;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class PlaybackEngine {
|
||||
static long mEngineHandle = 0;
|
||||
static final int MPG123_OK = 0;
|
||||
static boolean mFilesystemInitialized = false;
|
||||
|
||||
static {
|
||||
System.loadLibrary("lockstep-native");
|
||||
@@ -15,14 +20,36 @@ public class PlaybackEngine {
|
||||
}
|
||||
|
||||
public static boolean create(Context context) {
|
||||
try {
|
||||
if(!mFilesystemInitialized) {
|
||||
AudioResources.copyRawTracksToFilesystem(context);
|
||||
mFilesystemInitialized = true;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mEngineHandle == 0) {
|
||||
//setDefaultStreamValues(context); // TODO
|
||||
setDefaultStreamValues(context);
|
||||
Log.i("PlaybackEngine", "Hello PlaybackEngine");
|
||||
mEngineHandle = native_createEngine();
|
||||
mEngineHandle = native_createEngine(context.getFilesDir().toString());
|
||||
}
|
||||
return (mEngineHandle != 0);
|
||||
}
|
||||
|
||||
private static void setDefaultStreamValues(Context context) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1){
|
||||
AudioManager myAudioMgr = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
String sampleRateStr = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
|
||||
int defaultSampleRate = Integer.parseInt(sampleRateStr);
|
||||
String framesPerBurstStr = myAudioMgr.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
|
||||
int defaultFramesPerBurst = Integer.parseInt(framesPerBurstStr);
|
||||
|
||||
native_setDefaultStreamValues(defaultSampleRate, defaultFramesPerBurst);
|
||||
}
|
||||
}
|
||||
|
||||
public static void delete() {
|
||||
if (mEngineHandle != 0){
|
||||
native_deleteEngine(mEngineHandle);
|
||||
@@ -30,8 +57,9 @@ public class PlaybackEngine {
|
||||
mEngineHandle = 0;
|
||||
}
|
||||
|
||||
private static native long native_createEngine();
|
||||
private static native long native_createEngine(String filesDir);
|
||||
private static native void native_deleteEngine(long engineHandle);
|
||||
private static native void native_setDefaultStreamValues(int sampleRate, int framesPerBurst);
|
||||
|
||||
private static native int native_mpg123_init();
|
||||
}
|
||||
|
||||
BIN
app/src/main/res/raw/track_beat.mp3
Normal file
BIN
app/src/main/res/raw/track_beat.mp3
Normal file
Binary file not shown.
Reference in New Issue
Block a user