diff --git a/app/src/main/cpp/PlaybackEngine.cpp b/app/src/main/cpp/PlaybackEngine.cpp index 53477d8..58026c4 100644 --- a/app/src/main/cpp/PlaybackEngine.cpp +++ b/app/src/main/cpp/PlaybackEngine.cpp @@ -10,12 +10,32 @@ #include "mp3file.h" #include +/* +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 + +*/ 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; + //LOGI("in readBuffer2() handle != null: %d", mp3->handle != nullptr); 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; + if (err != MPG123_OK) LOGI("err=%d done=%d", err, done); // err=-12 + if(err == MPG123_DONE) return done; return err != MPG123_OK ? 0 : done; } @@ -23,17 +43,52 @@ static bool read_mp3(std::string filename, std::vector& samples) { // TODO: assumes 48000 Hz sampling rate of the file // 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) + //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 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) { // num_frames, num_samples, samples_per_frame + LOGI("filling %d num_samples", mFile->num_samples); samples.resize(mFile->num_samples); for(int i = 0; i < mFile->num_samples; i++) { int16_t *src = ((int16_t *) mFile->buffer) + i; samples[i] = (*src) / 32768.0f; } - } + }*/ if(mFile) mp3file_delete(mFile); return ok1 && ok2; @@ -44,7 +99,21 @@ PlaybackEngine::PlaybackEngine(std::string filesDir, int resid): mFilesDir(files LOGI("NDK LOG_LEVEL=%d", LOG_LEVEL); // NDK LOG_LEVEL=3 (DEBUG) std::vector 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); int32_t res = mPlayer->startAudio(); LOGI("startAudio() = %d", res); diff --git a/app/src/main/cpp/mp3file.cpp b/app/src/main/cpp/mp3file.cpp index c7273b0..30395bd 100644 --- a/app/src/main/cpp/mp3file.cpp +++ b/app/src/main/cpp/mp3file.cpp @@ -81,6 +81,8 @@ MP3File* mp3file_open(const char *filename, int forceEncoding) { else 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); return mp3; diff --git a/app/src/main/cpp/mp3file.h b/app/src/main/cpp/mp3file.h index b33c50b..f742631 100644 --- a/app/src/main/cpp/mp3file.h +++ b/app/src/main/cpp/mp3file.h @@ -19,7 +19,7 @@ struct MP3File double duration; size_t buffer_size; unsigned char* buffer; - size_t leftSamples; + int remaining_samples; size_t offset; }; diff --git a/app/src/main/java/at/lockstep/app/MainActivity.java b/app/src/main/java/at/lockstep/app/MainActivity.java index d32b9d9..a219cc3 100644 --- a/app/src/main/java/at/lockstep/app/MainActivity.java +++ b/app/src/main/java/at/lockstep/app/MainActivity.java @@ -21,6 +21,7 @@ public class MainActivity extends Activity { btnStart = findViewById(R.id.btnStart); btnStop = findViewById(R.id.btnStop); + // TODO: handle clicking START button twice btnStart.setOnClickListener(v -> ContextCompat.startForegroundService( MainActivity.this,