jni: add libmpg123
This commit is contained in:
@@ -29,6 +29,8 @@ add_library(${CMAKE_PROJECT_NAME} SHARED
|
||||
# List C/C++ source files with relative paths to this CMakeLists.txt.
|
||||
lockstep.cpp
|
||||
PlaybackEngine.cpp
|
||||
mp3file.cpp
|
||||
jni_bridge.cpp
|
||||
)
|
||||
|
||||
find_package (oboe REQUIRED CONFIG)
|
||||
@@ -36,13 +38,25 @@ find_package (oboe REQUIRED CONFIG)
|
||||
add_library(ndk-logger SHARED logging.cpp logging_jni.cpp)
|
||||
target_link_libraries(ndk-logger log)
|
||||
|
||||
# Add pre-built libmpg123 library
|
||||
add_library(mpg123 SHARED IMPORTED)
|
||||
set(mpg123_DIR ${CMAKE_SOURCE_DIR}/../lib/mpg123)
|
||||
set_target_properties(mpg123 PROPERTIES IMPORTED_LOCATION
|
||||
${mpg123_DIR}/lib/${ANDROID_ABI}/libmpg123.so)
|
||||
include_directories(${mpg123_DIR}/lib/${ANDROID_ABI}/include)
|
||||
|
||||
# Specifies libraries CMake should link to your target library. You
|
||||
# can link libraries from various origins, such as libraries defined in this
|
||||
# build script, prebuilt third-party libraries, or Android system libraries.
|
||||
target_link_libraries(${CMAKE_PROJECT_NAME}
|
||||
# List libraries link to the target library
|
||||
oboe::oboe
|
||||
mpg123
|
||||
android
|
||||
log
|
||||
ndk-logger
|
||||
)
|
||||
|
||||
# Enable optimization flags: if having problems with source level debugging,
|
||||
# disable -Ofast ( and debug ), re-enable after done debugging.
|
||||
target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE -Wall -Werror "$<$<CONFIG:RELEASE>:-Ofast>")
|
||||
|
||||
16
app/src/main/cpp/jni_bridge.cpp
Normal file
16
app/src/main/cpp/jni_bridge.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
//
|
||||
// Created by david on 02.03.2026.
|
||||
//
|
||||
|
||||
#include <jni.h>
|
||||
#include "mpg123.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_at_lockstep_pb_PlaybackEngine_native_1mpg123_1init
|
||||
(JNIEnv *env, jclass) {
|
||||
return mpg123_init();
|
||||
}
|
||||
|
||||
}
|
||||
93
app/src/main/cpp/mp3file.cpp
Normal file
93
app/src/main/cpp/mp3file.cpp
Normal file
@@ -0,0 +1,93 @@
|
||||
//
|
||||
// Created by david on 17.05.20.
|
||||
//
|
||||
|
||||
#define LOG_TAG "mp3file"
|
||||
|
||||
#include "mp3file.h"
|
||||
#include <string.h>
|
||||
#include <cstdlib>
|
||||
#include "logging.h"
|
||||
|
||||
MP3File* mp3file_init(mpg123_handle *handle) {
|
||||
MP3File* mp3file = (MP3File *) malloc(sizeof(MP3File));
|
||||
if(mp3file == NULL) return NULL;
|
||||
memset(mp3file, 0, sizeof(MP3File));
|
||||
mp3file->handle = handle;
|
||||
return mp3file;
|
||||
}
|
||||
|
||||
void mp3file_delete(MP3File *mp3file) {
|
||||
if(mp3file == NULL) return;
|
||||
mpg123_close(mp3file->handle);
|
||||
mpg123_delete(mp3file->handle);
|
||||
if(mp3file->buffer) {
|
||||
free(mp3file->buffer);
|
||||
mp3file->buffer = 0;
|
||||
}
|
||||
free(mp3file);
|
||||
}
|
||||
|
||||
MP3File* mp3file_open(const char *filename, int forceEncoding) {
|
||||
const char *errorText = "";
|
||||
#define handleError(text) \
|
||||
do { \
|
||||
errorText = text; \
|
||||
goto on_error; \
|
||||
} while(0)
|
||||
|
||||
int err = MPG123_OK;
|
||||
mpg123_handle *mh = mpg123_new(NULL, &err);
|
||||
if(err != MPG123_OK || mh == NULL) {
|
||||
LOGE("mpg123_new() failed: %s", mpg123_plain_strerror(err));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MP3File* mp3 = mp3file_init(mh);
|
||||
if(mp3 == NULL) handleError("malloc() failed");
|
||||
err = mpg123_open(mh, filename);
|
||||
if(err != MPG123_OK) handleError("mpg123_open()");
|
||||
|
||||
int encoding;
|
||||
err = mpg123_getformat(mh, &mp3->rate, &mp3->channels, &encoding);
|
||||
if(err != MPG123_OK) handleError("mpg123_getformat()");
|
||||
if(encoding != MPG123_ENC_SIGNED_16) handleError("unknown file encoding");
|
||||
|
||||
if(forceEncoding != 0) {
|
||||
encoding = forceEncoding;
|
||||
}
|
||||
|
||||
// Ensure that this output format will not change
|
||||
// (it could, when we allow it).
|
||||
mpg123_format_none(mh);
|
||||
err = mpg123_format(mh, mp3->rate, mp3->channels, encoding);
|
||||
if(err != MPG123_OK) handleError("could not set mpg123_format()");
|
||||
|
||||
mp3->buffer_size = mpg123_outblock(mh);
|
||||
mp3->buffer = (unsigned char*) malloc(mp3->buffer_size);
|
||||
if(mp3->buffer == NULL) handleError("malloc() failed");
|
||||
|
||||
mp3->num_samples = mpg123_length(mh);
|
||||
mp3->samples_per_frame = mpg123_spf(mh);
|
||||
mp3->secs_per_frame = mpg123_tpf(mh);
|
||||
|
||||
if (mp3->num_samples == MPG123_ERR || mp3->samples_per_frame < 0)
|
||||
mp3->num_frames = 0;
|
||||
else
|
||||
mp3->num_frames = mp3->num_samples / mp3->samples_per_frame;
|
||||
|
||||
if (mp3->num_samples == MPG123_ERR || mp3->samples_per_frame < 0 || mp3->secs_per_frame < 0)
|
||||
mp3->duration = 0;
|
||||
else
|
||||
mp3->duration = mp3->num_samples / mp3->samples_per_frame * mp3->secs_per_frame;
|
||||
|
||||
LOGV("channels: %d rate: %ld num_samples: %ld", mp3->channels, mp3->rate, mp3->num_samples);
|
||||
return mp3;
|
||||
|
||||
on_error:
|
||||
LOGE("%s, err = %s", errorText, mpg123_plain_strerror(err));
|
||||
mp3file_delete(mp3);
|
||||
return NULL;
|
||||
|
||||
#undef handleError
|
||||
}
|
||||
30
app/src/main/cpp/mp3file.h
Normal file
30
app/src/main/cpp/mp3file.h
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// Created by david on 17.05.20.
|
||||
//
|
||||
|
||||
#ifndef SAMPLES_MP3FILE_H
|
||||
#define SAMPLES_MP3FILE_H
|
||||
|
||||
#include "mpg123.h"
|
||||
|
||||
struct MP3File
|
||||
{
|
||||
mpg123_handle* handle;
|
||||
int channels;
|
||||
long rate;
|
||||
long num_samples;
|
||||
int samples_per_frame;
|
||||
double secs_per_frame;
|
||||
long num_frames;
|
||||
double duration;
|
||||
size_t buffer_size;
|
||||
unsigned char* buffer;
|
||||
size_t leftSamples;
|
||||
size_t offset;
|
||||
};
|
||||
|
||||
MP3File* mp3file_init(mpg123_handle *handle);
|
||||
void mp3file_delete(MP3File *mp3file);
|
||||
MP3File* mp3file_open(const char *filename, int forceEncoding = 0);
|
||||
|
||||
#endif //SAMPLES_MP3FILE_H
|
||||
Reference in New Issue
Block a user