Files
lockstep/app/src/main/cpp/PlaybackEngine.cpp

77 lines
2.4 KiB
C++
Raw Normal View History

2026-02-01 02:54:05 +01:00
//
// Created by david on 01.02.2026.
//
#define LOG_TAG "PlaybackEngine"
#include "PlaybackEngine.h"
#include "logging.h"
#include "mpg123.h"
#include "mp3file.h"
#include <vector>
2026-02-01 02:54:05 +01:00
2026-03-06 00:50:38 +01:00
/**
* Read samples from the next mp3-frame into the struct MP3File's buffer.
* @return number of samples read (uses buffer_size which is much smaller than total length)
*/
static inline int readBuffer2(MP3File* mp3)
{
size_t done = 0;
int err = mpg123_read(mp3->handle, mp3->buffer, mp3->buffer_size, &done);
2026-03-05 14:28:23 +01:00
mp3->remaining_samples -= done / sizeof(int16_t);
mp3->offset = 0;
2026-03-06 00:50:38 +01:00
if (err != MPG123_OK && err != MPG123_DONE) LOGE("mpg123_read() err=%d done=%d", err, done);
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) {
// TODO: assumes 48000 Hz sampling rate of the file
// note: our resource file is mono (1 channel = 1 samples_per_frame)!
MP3File *mFile = mp3file_open(filename.c_str(), 0); // MPG123_ENC_FLOAT_32 (but does not seem to work)
2026-03-05 14:28:23 +01:00
memset(mFile->buffer, 0, mFile->buffer_size);
bool ok1 = mFile != nullptr;
2026-03-05 14:28:23 +01:00
int ok2 = true;
int i = 0;
if(ok1) {
samples.resize(mFile->num_samples);
while (ok2 && mFile->remaining_samples > 0) {
ok2 = readBuffer2(mFile);
2026-03-06 00:50:38 +01:00
if (!ok2) break;
2026-03-05 14:28:23 +01:00
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;
}
}
}
if(!ok2) {
LOGI("ok2=false at i=%d", i);
}
if(mFile)
mp3file_delete(mFile);
return ok1 && ok2;
}
PlaybackEngine::PlaybackEngine(std::string filesDir, int resid): mFilesDir(filesDir) {
2026-02-01 02:54:05 +01:00
LOGI("PlaybackEngine()");
LOGI("NDK LOG_LEVEL=%d", LOG_LEVEL);
// NDK LOG_LEVEL=3 (DEBUG)
std::vector<float> samples;
2026-03-05 14:28:23 +01:00
bool is_ok = read_mp3(mFilesDir + "/" + std::to_string(resid) + ".mp3", samples);
LOGI("read_mp3() is_ok=%d", is_ok);
mPlayer = new MixingPlayer(samples);
2026-02-01 02:54:05 +01:00
int32_t res = mPlayer->startAudio();
LOGI("startAudio() = %d", res);
}
PlaybackEngine::~PlaybackEngine() {
LOGI("~PlaybackEngine()");
mPlayer->stopAudio();
delete mPlayer;
mPlayer = nullptr;
}
2026-03-04 01:31:35 +01:00
void PlaybackEngine::playBeat() {
if(mPlayer) mPlayer->setStartBeat();
}