Fix Anroid headset connect/disconnect

This commit is contained in:
badaix 2020-09-29 22:32:23 +02:00
parent 2c5c673c90
commit 869a9a276e
5 changed files with 66 additions and 30 deletions

View file

@ -58,7 +58,7 @@ endif
ifeq ($(TARGET), ANDROID)
CXX = $(PROGRAM_PREFIX)clang++
CXXFLAGS += -pthread -fPIC -DHAS_TREMOR -DHAS_OPENSL -DHAS_OBOE -I$(TOOLCHAIN)/sysroot/usr/include -I$(TOOLCHAIN)/sysroot/$(NDK_TARGET)/usr/local/include
CXXFLAGS += -pthread -fPIC -DHAS_TREMOR -DHAS_OPENSL -DHAS_OBOE -DHAS_SOXR -I$(TOOLCHAIN)/sysroot/usr/include -I$(TOOLCHAIN)/sysroot/$(NDK_TARGET)/usr/local/include
LDFLAGS = -L$(TOOLCHAIN)/sysroot/$(NDK_TARGET)/usr/local/lib -pie -lvorbisidec -logg -lopus -lFLAC -lOpenSLES -loboe -latomic -llog -lsoxr -static-libstdc++
OBJ += player/opensl_player.o player/oboe_player.o

View file

@ -45,38 +45,11 @@ OboePlayer::OboePlayer(boost::asio::io_context& io_context, const ClientSettings
LOG(INFO, LOG_TAG) << "DefaultStreamValues::SampleRate: " << oboe::DefaultStreamValues::SampleRate
<< ", DefaultStreamValues::FramesPerBurst: " << oboe::DefaultStreamValues::FramesPerBurst << "\n";
oboe::SharingMode sharing_mode = oboe::SharingMode::Shared;
if (settings.sharing_mode == ClientSettings::SharingMode::exclusive)
sharing_mode = oboe::SharingMode::Exclusive;
// The builder set methods can be chained for convenience.
oboe::AudioStreamBuilder builder;
auto result = builder.setSharingMode(sharing_mode)
->setPerformanceMode(oboe::PerformanceMode::LowLatency)
->setChannelCount(stream->getFormat().channels())
->setSampleRate(stream->getFormat().rate())
->setFormat(oboe::AudioFormat::I16)
->setCallback(this)
->setDirection(oboe::Direction::Output)
//->setFramesPerCallback((8 * stream->getFormat().rate) / 1000)
//->setFramesPerCallback(2 * oboe::DefaultStreamValues::FramesPerBurst)
//->setFramesPerCallback(960) // 2*192)
->openStream(out_stream_);
auto result = openStream();
LOG(INFO, LOG_TAG) << "BufferSizeInFrames: " << out_stream_->getBufferSizeInFrames() << ", FramesPerBurst: " << out_stream_->getFramesPerBurst() << "\n";
if (result != oboe::Result::OK)
LOG(ERROR, LOG_TAG) << "Error building AudioStream: " << oboe::convertToText(result) << "\n";
if (out_stream_->getAudioApi() == oboe::AudioApi::AAudio)
{
LOG(INFO, LOG_TAG) << "AudioApi: AAudio\n";
// mLatencyTuner = std::make_unique<oboe::LatencyTuner>(*out_stream_);
mLatencyTuner = nullptr;
}
else
{
LOG(INFO, LOG_TAG) << "AudioApi: OpenSL\n";
out_stream_->setBufferSizeInFrames(4 * out_stream_->getFramesPerBurst());
}
LOG(INFO, LOG_TAG) << "Init done\n";
}
@ -94,6 +67,42 @@ OboePlayer::~OboePlayer()
}
oboe::Result OboePlayer::openStream()
{
oboe::SharingMode sharing_mode = oboe::SharingMode::Shared;
if (settings_.sharing_mode == ClientSettings::SharingMode::exclusive)
sharing_mode = oboe::SharingMode::Exclusive;
// The builder set methods can be chained for convenience.
oboe::AudioStreamBuilder builder;
auto result = builder.setSharingMode(sharing_mode)
->setPerformanceMode(oboe::PerformanceMode::LowLatency)
->setChannelCount(stream_->getFormat().channels())
->setSampleRate(stream_->getFormat().rate())
->setFormat(oboe::AudioFormat::I16)
->setCallback(this)
->setDirection(oboe::Direction::Output)
//->setFramesPerCallback((8 * stream->getFormat().rate) / 1000)
//->setFramesPerCallback(2 * oboe::DefaultStreamValues::FramesPerBurst)
//->setFramesPerCallback(960) // 2*192)
->openStream(out_stream_);
if (out_stream_->getAudioApi() == oboe::AudioApi::AAudio)
{
LOG(INFO, LOG_TAG) << "AudioApi: AAudio\n";
// mLatencyTuner = std::make_unique<oboe::LatencyTuner>(*out_stream_);
mLatencyTuner = nullptr;
}
else
{
LOG(INFO, LOG_TAG) << "AudioApi: OpenSL\n";
out_stream_->setBufferSizeInFrames(4 * out_stream_->getFramesPerBurst());
}
return result;
}
bool OboePlayer::needsThread() const
{
return false;
@ -153,6 +162,25 @@ oboe::DataCallbackResult OboePlayer::onAudioReady(oboe::AudioStream* /*oboeStrea
}
void OboePlayer::onErrorBeforeClose(oboe::AudioStream* oboeStream, oboe::Result error)
{
std::ignore = oboeStream;
LOG(INFO, LOG_TAG) << "onErrorBeforeClose: " << oboe::convertToText(error) << "\n";
stop();
}
void OboePlayer::onErrorAfterClose(oboe::AudioStream* oboeStream, oboe::Result error)
{
std::ignore = oboeStream;
LOG(INFO, LOG_TAG) << "onErrorAfterClose: " << oboe::convertToText(error) << "\n";
auto result = openStream();
if (result != oboe::Result::OK)
LOG(ERROR, LOG_TAG) << "Error building AudioStream: " << oboe::convertToText(result) << "\n";
start();
}
void OboePlayer::start()
{
// Typically, start the stream after querying some stream information, as well as some input from the user

View file

@ -39,7 +39,13 @@ public:
void stop() override;
protected:
// AudioStreamCallback overrides
oboe::DataCallbackResult onAudioReady(oboe::AudioStream* oboeStream, void* audioData, int32_t numFrames) override;
void onErrorBeforeClose(oboe::AudioStream* oboeStream, oboe::Result error) override;
void onErrorAfterClose(oboe::AudioStream* oboeStream, oboe::Result error) override;
protected:
oboe::Result openStream();
double getCurrentOutputLatencyMillis() const;
bool needsThread() const override;

View file

@ -52,6 +52,8 @@ Resampler::Resampler(const SampleFormat& in_format, const SampleFormat& out_form
// initialize the buffer with 20ms (~latency of the reampler)
resample_buffer_.resize(out_format_.frameSize() * static_cast<uint16_t>(ceil(out_format_.msRate() * 20)));
}
#else
LOG(WARNING, LOG_TAG) << "Soxr not available, resampling not supported\n";
#endif
// resampled_chunk_ = std::make_unique<msg::PcmChunk>(out_format_, 0);
}

2
externals/Makefile vendored
View file

@ -137,7 +137,7 @@ oboe: check-env
rm -rf build;
soxr: check-env
@cd /home/johannes/Develop/soxr; \
@cd soxr; \
export CC="$(CC)"; \
export CXX="$(CXX)"; \
export CPPFLAGS="$(CPPFLAGS)"; \