feat: reduce buffers to 1024
This commit is contained in:
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user