feat: reduce buffers to 1024

This commit is contained in:
2026-03-22 07:49:05 +01:00
parent b0f6d6d5c9
commit 6382c57ccc
3 changed files with 32 additions and 38 deletions

View File

@@ -55,6 +55,8 @@ public:
return (int32_t) result; return (int32_t) result;
} }
int getRate() { return kSampleRate; }
// Call this from Activity onPause() // Call this from Activity onPause()
void stopAudio() { void stopAudio() {
// Stop, close and delete in case not already closed. // Stop, close and delete in case not already closed.

View File

@@ -82,7 +82,8 @@ PlaybackEngine::PlaybackEngine(std::string filesDir, int resid):
exitMusicFeedThread(false), exitMusicFeedThread(false),
android_fd(0), android_fd(0),
haveTimeRatio(false), haveTimeRatio(false),
timeRatio(1.0) timeRatio(1.0),
playbackRate(48000)
{ {
LOGI("PlaybackEngine()"); LOGI("PlaybackEngine()");
LOGI("NDK LOG_LEVEL=%d", LOG_LEVEL); LOGI("NDK LOG_LEVEL=%d", LOG_LEVEL);
@@ -92,6 +93,7 @@ PlaybackEngine::PlaybackEngine(std::string filesDir, int resid):
LOGI("read_mp3() is_ok=%d", is_ok); LOGI("read_mp3() is_ok=%d", is_ok);
mPlayer = new MixingPlayer(samples); mPlayer = new MixingPlayer(samples);
int32_t res = mPlayer->startAudio(); int32_t res = mPlayer->startAudio();
playbackRate = mPlayer->getRate();
LOGI("startAudio() = %d", res); LOGI("startAudio() = %d", res);
initRubberBand(); initRubberBand();
} }
@@ -150,15 +152,14 @@ void PlaybackEngine::closeMusicFile() {
} }
void PlaybackEngine::musicFeedThread() { void PlaybackEngine::musicFeedThread() {
// refactor: rename to 'num_buf_samples' size_t num_buf_samples = buf_size_samples;
size_t num_pad = 48000; // hack! how much to actually reserve? is getPreferredStartPad() always < getSamplesRequired()? size_t buf_stride = num_buf_samples;
size_t buf_stride = num_pad; float* buf = (float*) malloc(num_buf_samples * 2 * sizeof(float));
float* buf = (float*) malloc(num_pad*2*sizeof(float)); float* buf_ptr[] {buf, buf + num_buf_samples};
float* buf_ptr[] {buf, buf + num_pad}; memset(buf, 0, num_buf_samples * 2 * sizeof(float));
memset(buf, 0, num_pad*2*sizeof(float)); unsigned char* cbuf = (unsigned char*) malloc(num_buf_samples * 2 * sizeof(int16_t));
unsigned char* cbuf = (unsigned char*) malloc(num_pad*2*sizeof(int16_t)); memset(cbuf, 0, num_buf_samples * 2 * sizeof(int16_t));
memset(cbuf, 0, num_pad*2*sizeof(int16_t)); size_t cbuf_size_bytes = num_buf_samples * 2 * sizeof(int16_t);
size_t cbuf_size_bytes = num_pad*2*sizeof(int16_t);
int idebug = 0; int idebug = 0;
@@ -185,8 +186,8 @@ void PlaybackEngine::musicFeedThread() {
continue; continue;
} }
if (num_samples > num_pad) { if (num_samples > num_buf_samples) {
LOGE("wanted %d samples but buf is only %d samples", num_samples, num_pad); LOGE("wanted %d samples but buf is only %d samples", num_samples, num_buf_samples);
continue; continue;
} }
@@ -226,7 +227,8 @@ void PlaybackEngine::musicFeedThread() {
} }
size_t num_decoded_samples = done / sizeof(int16_t) / 2; // 2 channels - TODO: actually use mp3 channels!! below, too. 2. size_t num_decoded_samples = done / sizeof(int16_t) / 2; // 2 channels - TODO: actually use mp3 channels!! below, too. 2.
LOGI("num_decoded_samples = %d", num_decoded_samples); //LOGD("num_decoded_samples = %d", num_decoded_samples);
// convert interleaved int16 to de-interleaved float [-1.0, 1.0] format // convert interleaved int16 to de-interleaved float [-1.0, 1.0] format
for(size_t i = 0; i < num_decoded_samples; i++) { for(size_t i = 0; i < num_decoded_samples; i++) {
for(size_t j = 0; j < 2; j++) { for(size_t j = 0; j < 2; j++) {
@@ -234,7 +236,7 @@ void PlaybackEngine::musicFeedThread() {
} }
} }
LOGI("calling stretcher.process()"); //LOGD("calling stretcher.process()");
stretcher.process(buf_ptr, num_decoded_samples, false); stretcher.process(buf_ptr, num_decoded_samples, false);
} }
} }
@@ -253,35 +255,23 @@ void PlaybackEngine::playBeat() {
void PlaybackEngine::playMusic(int fd) { void PlaybackEngine::playMusic(int fd) {
if(!mPlayer) return; if(!mPlayer) return;
// TODO: fetch sampling rate from mp3 file, and use librubberband to correct for it
// MixingPlayer::kSampleRate (48000)
// mp3->rate
// feed samples to librubberband
// fetch resamples out of librubberband
//if(mPlayer) mPlayer->playMusic();
// TODO: fd is opened; dispose of fd when stopping or being discarded ...
LOGI("PlaybackEngine::playMusic(fd=%d)", fd); LOGI("PlaybackEngine::playMusic(fd=%d)", fd);
//close(fd); // for now, nothing is implemented. we just close it again.
// we will use mp3file_open_fd() later.
android_fd = fd; android_fd = fd;
musicFile.reset(mp3file_open_fd(android_fd, 0)); musicFile.reset(mp3file_open_fd(android_fd, 0));
if(musicFile) { if(musicFile) {
timeRatio = ((double) 48000) / ((double) musicFile->rate); timeRatio = ((double) playbackRate) / ((double) musicFile->rate);
haveTimeRatio.store(true); haveTimeRatio.store(true);
} }
haveMusicFile.store(true); haveMusicFile.store(true);
mPlayer->setMusic(std::make_shared<MusicProvider>(&stretcher)); mPlayer->setMusic(std::make_shared<MusicProvider>(&stretcher, buf_size_samples));
} }
MusicProvider::MusicProvider(RubberBand::RubberBandStretcher *stretcher) : stretcher(stretcher), idebug(0) { MusicProvider::MusicProvider(RubberBand::RubberBandStretcher *stretcher, size_t buf_size_samples) :
// refactor: rename to 'num_buf_samples' stretcher(stretcher),
// TODO: for cache-friendliness, it would be better to have smaller 'num_buf_samples' idebug(0),
// hack! how much to actually reserve? is getPreferredStartPad() always < getSamplesRequired()? buf_size_samples(buf_size_samples)
//size_t buf_stride = num_pad; {
buf = (float*) malloc(num_buf_samples*2*sizeof(float)); buf = (float*) malloc(buf_size_samples*2*sizeof(float));
//float* buf_ptr[] {buf, buf + num_pad}; //float* buf_ptr[] {buf, buf + num_pad};
} }
@@ -296,8 +286,8 @@ void MusicProvider::onAudioReady(float *data, int32_t frames) {
} }
// 1. read from oboe into our temp de-interleaved buffer 'buf' // 1. read from oboe into our temp de-interleaved buffer 'buf'
size_t num_frames = std::min((size_t) frames, num_buf_samples); size_t num_frames = std::min((size_t) frames, buf_size_samples);
float* buf_ptr[] {buf, buf + num_buf_samples}; float* buf_ptr[] {buf, buf + buf_size_samples};
stretcher->retrieve(buf_ptr, num_frames); stretcher->retrieve(buf_ptr, num_frames);
// 2. convert to add samples to interleaved *data // 2. convert to add samples to interleaved *data

View File

@@ -18,16 +18,16 @@
/** Provides music through a regular callback to oboe. Called from separate oboe thread. */ /** Provides music through a regular callback to oboe. Called from separate oboe thread. */
class MusicProvider : public AudioCallbackProvider { class MusicProvider : public AudioCallbackProvider {
public: public:
explicit MusicProvider(RubberBand::RubberBandStretcher *stretcher); explicit MusicProvider(RubberBand::RubberBandStretcher *stretcher, size_t buf_size_samples);
~MusicProvider() override; ~MusicProvider() override;
/** Called from separate oboe thread. */ /** Called from separate oboe thread. */
void onAudioReady(float *data, int32_t frames) override; void onAudioReady(float *data, int32_t frames) override;
private: private:
const size_t num_buf_samples = 48000;
RubberBand::RubberBandStretcher *stretcher; RubberBand::RubberBandStretcher *stretcher;
float *buf; float *buf;
int idebug; int idebug;
size_t buf_size_samples;
}; };
class PlaybackEngine : public StepListener { class PlaybackEngine : public StepListener {
@@ -48,6 +48,8 @@ private:
int android_fd; int android_fd;
std::atomic<bool> haveTimeRatio; std::atomic<bool> haveTimeRatio;
double timeRatio; double timeRatio;
int playbackRate;
static size_t constexpr buf_size_samples = 1024;
void initRubberBand(); void initRubberBand();
void closeRubberBand(); void closeRubberBand();
void closeMusicFile(); void closeMusicFile();