Compare commits

...

2 Commits

Author SHA1 Message Date
66a2b86ffc fix: fixup readBuffer2() to return samples not bytes 2026-03-06 00:45:20 +01:00
d1b57aae82 fix: fixed mpg123_read() logic 2026-03-05 14:28:23 +01:00
4 changed files with 78 additions and 6 deletions

View File

@@ -10,30 +10,85 @@
#include "mp3file.h" #include "mp3file.h"
#include <vector> #include <vector>
/*
allocated 2304 bytes buffer
blanking the buffer ...
filling 24543 num_samples
readBuffer2() k=0
in readBuffer2() on mp3 != null: 1
in readBuffer2() remaining_samples=24543 offset=0
in readBuffer2() handle != null: 1
in readBuffer2() done=2304
copying 1152 samples, k=0
<segfault>
*/
static inline int readBuffer2(MP3File* mp3) static inline int readBuffer2(MP3File* mp3)
{ {
//LOGI("in readBuffer2() on mp3 != null: %d", mp3 != nullptr);
//if(mp3 == nullptr) return 0;
//LOGI("in readBuffer2() remaining_samples=%d offset=%d", mp3->remaining_samples, mp3->offset);
size_t done = 0; size_t done = 0;
//LOGI("in readBuffer2() handle != null: %d", mp3->handle != nullptr);
int err = mpg123_read(mp3->handle, mp3->buffer, mp3->buffer_size, &done); int err = mpg123_read(mp3->handle, mp3->buffer, mp3->buffer_size, &done);
mp3->leftSamples = done / sizeof(int16_t); //LOGI("in readBuffer2() done=%d", done);
mp3->remaining_samples -= done / sizeof(int16_t);
mp3->offset = 0; mp3->offset = 0;
return err != MPG123_OK ? 0 : done; if (err != MPG123_OK) LOGI("err=%d done=%d", err, done); // err=-12
if(err == MPG123_DONE) return done / sizeof(int16_t);
return err != MPG123_OK ? 0 : done / sizeof(int16_t);
} }
static bool read_mp3(std::string filename, std::vector<float>& samples) { static bool read_mp3(std::string filename, std::vector<float>& samples) {
// TODO: assumes 48000 Hz sampling rate of the file // TODO: assumes 48000 Hz sampling rate of the file
// note: our resource file is mono (1 channel = 1 samples_per_frame)! // note: our resource file is mono (1 channel = 1 samples_per_frame)!
/*
2026-03-05 11:54:44.841 17486-17486 NDK at.lockstep I PlaybackEngine - allocated 2304 bytes buffer
2026-03-05 11:54:44.841 17486-17486 NDK at.lockstep I PlaybackEngine - blanking the buffer ...
2026-03-05 11:54:44.842 17486-17486 NDK at.lockstep I PlaybackEngine - filling 24543 num_samples
copying 1152 samples, k=0
*/
MP3File *mFile = mp3file_open(filename.c_str(), 0); // MPG123_ENC_FLOAT_32 (but does not seem to work) MP3File *mFile = mp3file_open(filename.c_str(), 0); // MPG123_ENC_FLOAT_32 (but does not seem to work)
//LOGI("allocated %d bytes buffer", mFile->buffer_size);
//LOGI("blanking the buffer ...");
memset(mFile->buffer, 0, mFile->buffer_size);
//LOGI("filling %d num_samples", mFile->num_samples);
bool ok1 = mFile != nullptr; bool ok1 = mFile != nullptr;
bool ok2 = readBuffer2(mFile) != 0; // once is enough (maybe the other one needs to pre-fill other buffers, in oboe etc.) int ok2 = true;
int i = 0;
//int k = 0;
if(ok1) {
samples.resize(mFile->num_samples);
while (ok2 && mFile->remaining_samples > 0) {
//LOGI("readBuffer2() k=%d", k);
ok2 = readBuffer2(mFile);
if (!ok2) break; // TODO: check if trailing bit is decoded correctly
//LOGI("copying %d samples, k=%d", mFile->samples_per_frame, k);
for (int j = 0; j < ok2 && i < mFile->num_samples; j++, i++) {
int16_t *src = ((int16_t *) mFile->buffer) + j;
samples[i] = (*src) / 32768.0f;
}
//k++; // debug only
}
}
if(!ok2) {
LOGI("ok2=false at i=%d", i);
}
/*
if(ok1 && ok2) { if(ok1 && ok2) {
// num_frames, num_samples, samples_per_frame // num_frames, num_samples, samples_per_frame
LOGI("filling %d num_samples", mFile->num_samples);
samples.resize(mFile->num_samples); samples.resize(mFile->num_samples);
for(int i = 0; i < mFile->num_samples; i++) { for(int i = 0; i < mFile->num_samples; i++) {
int16_t *src = ((int16_t *) mFile->buffer) + i; int16_t *src = ((int16_t *) mFile->buffer) + i;
samples[i] = (*src) / 32768.0f; samples[i] = (*src) / 32768.0f;
} }
} }*/
if(mFile) if(mFile)
mp3file_delete(mFile); mp3file_delete(mFile);
return ok1 && ok2; return ok1 && ok2;
@@ -44,7 +99,21 @@ PlaybackEngine::PlaybackEngine(std::string filesDir, int resid): mFilesDir(files
LOGI("NDK LOG_LEVEL=%d", LOG_LEVEL); LOGI("NDK LOG_LEVEL=%d", LOG_LEVEL);
// NDK LOG_LEVEL=3 (DEBUG) // NDK LOG_LEVEL=3 (DEBUG)
std::vector<float> samples; std::vector<float> samples;
read_mp3(mFilesDir + "/" + std::to_string(resid) + ".mp3", samples); // BUG!
bool is_ok = read_mp3(mFilesDir + "/" + std::to_string(resid) + ".mp3", samples);
LOGI("read_mp3() is_ok=%d", is_ok);
// begin debug only
/*
// make sine wave (it works)
int fps = 48000;
float dur = 0.3;
float f = 440;
int N = (int) (dur * (float) fps);
samples.resize(N);
for(int n = 0; n < N; n++)
samples[n] = (float) sin(2*M_PI * f * n / N);
*/
// end debug only
mPlayer = new MixingPlayer(samples); mPlayer = new MixingPlayer(samples);
int32_t res = mPlayer->startAudio(); int32_t res = mPlayer->startAudio();
LOGI("startAudio() = %d", res); LOGI("startAudio() = %d", res);

View File

@@ -81,6 +81,8 @@ MP3File* mp3file_open(const char *filename, int forceEncoding) {
else else
mp3->duration = mp3->num_samples / mp3->samples_per_frame * mp3->secs_per_frame; mp3->duration = mp3->num_samples / mp3->samples_per_frame * mp3->secs_per_frame;
mp3->offset = 0;
mp3->remaining_samples = (int) mp3->num_samples;
LOGV("channels: %d rate: %ld num_samples: %ld", mp3->channels, mp3->rate, mp3->num_samples); LOGV("channels: %d rate: %ld num_samples: %ld", mp3->channels, mp3->rate, mp3->num_samples);
return mp3; return mp3;

View File

@@ -19,7 +19,7 @@ struct MP3File
double duration; double duration;
size_t buffer_size; size_t buffer_size;
unsigned char* buffer; unsigned char* buffer;
size_t leftSamples; int remaining_samples;
size_t offset; size_t offset;
}; };

View File

@@ -21,6 +21,7 @@ public class MainActivity extends Activity {
btnStart = findViewById(R.id.btnStart); btnStart = findViewById(R.id.btnStart);
btnStop = findViewById(R.id.btnStop); btnStop = findViewById(R.id.btnStop);
// TODO: handle clicking START button twice
btnStart.setOnClickListener(v -> btnStart.setOnClickListener(v ->
ContextCompat.startForegroundService( ContextCompat.startForegroundService(
MainActivity.this, MainActivity.this,