fix: mutex fun: ensure a: stretcher for oboe_cb MusicProvider::onAudioReady, b: musicFile for musicFeedThread
This commit is contained in:
@@ -157,6 +157,13 @@ void PlaybackEngine::initRubberBand() {
|
||||
}
|
||||
|
||||
void PlaybackEngine::closeRubberBand() {
|
||||
if (mPlayer) {
|
||||
LOGI("PlaybackEngine: mPlayer->stopAudio() ...");
|
||||
mPlayer->stopAudio();
|
||||
LOGI("PlaybackEngine: mPlayer->stopAudio() done.");
|
||||
delete mPlayer;
|
||||
mPlayer = nullptr;
|
||||
}
|
||||
if(musicFeed) {
|
||||
exitMusicFeedThread.store(true);
|
||||
LOGI("PlaybackEngine: musicFeed->join() ...");
|
||||
@@ -164,7 +171,6 @@ void PlaybackEngine::closeRubberBand() {
|
||||
LOGI("PlaybackEngine: musicFeed->join() done.");
|
||||
musicFeed = nullptr;
|
||||
}
|
||||
closeMusicFile();
|
||||
}
|
||||
|
||||
void PlaybackEngine::closeMusicFile() {
|
||||
@@ -209,6 +215,7 @@ void PlaybackEngine::musicFeedThread() {
|
||||
std::mt19937 mt(42);
|
||||
std::uniform_real_distribution<double> dist(0.98, 1.0);
|
||||
*/
|
||||
bool isOnTrackFinished = false;
|
||||
LOGI("starting musicFeedThread()");
|
||||
|
||||
// strecher num channels: same as output num channels
|
||||
@@ -243,6 +250,11 @@ void PlaybackEngine::musicFeedThread() {
|
||||
// thread 2: polling for decoding more mp3 -> process() -- getSamplesRequired()
|
||||
while(!exitMusicFeedThread.load()) {
|
||||
|
||||
if(isOnTrackFinished) {
|
||||
if(listener) listener->onTrackFinished();
|
||||
isOnTrackFinished = false;
|
||||
}
|
||||
|
||||
if(!haveMusicFile.load()) {
|
||||
// while no MusicProvider is connected, no samples will be read from 'stretcher'
|
||||
// therefore, we do not write any samples into it!
|
||||
@@ -325,6 +337,11 @@ void PlaybackEngine::musicFeedThread() {
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t num_decoded_samples;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMusicLock);
|
||||
if(!haveMusicFile.load()) continue;
|
||||
|
||||
if(idebug++ < 10) {
|
||||
pr = std::max(1L, musicFile->rate);
|
||||
loop_delay_us = std::min((size_t) 50000, (size_t) 1000000 * num_samples / pr);
|
||||
@@ -399,6 +416,8 @@ void PlaybackEngine::musicFeedThread() {
|
||||
stretcher.setPitchScale(1.0);
|
||||
stretcher.process(buf_ptr, 0, true); // set end of playback
|
||||
mPlayer->stopAudio();
|
||||
// TODO: raise error
|
||||
//if(listener) listener->onError(1, "mpg123_read() error");
|
||||
continue;
|
||||
}
|
||||
if(err == MPG123_DONE) {
|
||||
@@ -407,11 +426,12 @@ void PlaybackEngine::musicFeedThread() {
|
||||
LOGI("finished reading mp3 file (MPG123_DONE)");
|
||||
idebug = 0;
|
||||
closeMusicFile();
|
||||
if(listener) listener->onTrackFinished();
|
||||
//if(listener) listener->onTrackFinished();
|
||||
isOnTrackFinished = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t num_decoded_samples = done / sizeof(int16_t) / num_ch_in;
|
||||
num_decoded_samples = done / sizeof(int16_t) / num_ch_in;
|
||||
//LOGD("num_decoded_samples = %d", num_decoded_samples);
|
||||
|
||||
// * convert interleaved int16 to de-interleaved float [-1.0, 1.0] format
|
||||
@@ -421,11 +441,17 @@ void PlaybackEngine::musicFeedThread() {
|
||||
buf[i + buf_stride * j] = static_cast<float>(*(reinterpret_cast<int16_t*>(cbuf) + i * num_ch_in + channel_map[j])) / 32768.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//LOGD("calling stretcher.process()");
|
||||
stretcher.process(buf_ptr, num_decoded_samples, false);
|
||||
}
|
||||
|
||||
if(isOnTrackFinished) {
|
||||
if(listener) listener->onTrackFinished();
|
||||
//isOnTrackFinished = false;
|
||||
}
|
||||
|
||||
LOGI("musicFeedThread() exiting ...");
|
||||
|
||||
free(buf);
|
||||
@@ -462,12 +488,9 @@ void PlaybackEngine::seekTo(double markerPosSec) {
|
||||
void PlaybackEngine::stop() {
|
||||
LOGI("PlaybackEngine::stop()");
|
||||
closeRubberBand();
|
||||
if (mPlayer) {
|
||||
LOGI("PlaybackEngine: mPlayer->stopAudio() ...");
|
||||
mPlayer->stopAudio();
|
||||
LOGI("PlaybackEngine: mPlayer->stopAudio() done.");
|
||||
delete mPlayer;
|
||||
mPlayer = nullptr;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMusicLock);
|
||||
closeMusicFile();
|
||||
}
|
||||
markerPos.store(0.0);
|
||||
duration.store(0.0);
|
||||
@@ -476,10 +499,9 @@ void PlaybackEngine::stop() {
|
||||
PlaybackEngine::~PlaybackEngine() {
|
||||
LOGI("~PlaybackEngine()");
|
||||
closeRubberBand();
|
||||
if (mPlayer) {
|
||||
mPlayer->stopAudio();
|
||||
delete mPlayer;
|
||||
mPlayer = nullptr;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMusicLock);
|
||||
closeMusicFile();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,25 +512,33 @@ void PlaybackEngine::playBeat() {
|
||||
void PlaybackEngine::playMusic(int fd, long long offset, long long length) {
|
||||
if(!mPlayer) return;
|
||||
LOGI("PlaybackEngine::playMusic(fd=%d)", fd);
|
||||
if(musicFile) {
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMusicLock);
|
||||
|
||||
if (musicFile) {
|
||||
if (fd == android_fd)
|
||||
android_fd = 0; // HACK: avoid closing the 'fd' if re-opening the same file
|
||||
// when changing tracks in the UI, close the previous file
|
||||
closeMusicFile();
|
||||
}
|
||||
android_fd = fd;
|
||||
if(fd != 0)
|
||||
if (fd != 0)
|
||||
musicFile.reset(mp3file_open_fd(android_fd, offset, length, 0));
|
||||
if(musicFile) {
|
||||
if (musicFile) {
|
||||
timeRatio.store(((double) playbackRate.load()) / ((double) musicFile->rate));
|
||||
haveTimeRatio.store(true);
|
||||
numInChannels.store(musicFile->channels);
|
||||
haveMusicFile.store(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_finished = (stretcher.available() == -1);
|
||||
if(is_finished) {
|
||||
LOGE("stretcher.available() == -1, this should not happen anymore with current wiring");
|
||||
// so that we may play again after "final chunk"
|
||||
closeRubberBand();
|
||||
// do not closeMusicFile() here, it would close the very file we want to be playing
|
||||
initRubberBand();
|
||||
}
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ private:
|
||||
RubberBand::RubberBandStretcher stretcher;
|
||||
MixingPlayer *mPlayer;
|
||||
std::string mFilesDir;
|
||||
std::mutex mMusicLock;
|
||||
std::unique_ptr<MP3File> musicFile;
|
||||
std::atomic<bool> haveMusicFile;
|
||||
std::unique_ptr<std::thread> musicFeed;
|
||||
|
||||
Reference in New Issue
Block a user