mirror of
https://github.com/badaix/snapcast.git
synced 2025-06-07 13:21:43 +02:00
Fix Anroid headset connect/disconnect
This commit is contained in:
parent
2c5c673c90
commit
869a9a276e
5 changed files with 66 additions and 30 deletions
|
@ -58,7 +58,7 @@ endif
|
||||||
ifeq ($(TARGET), ANDROID)
|
ifeq ($(TARGET), ANDROID)
|
||||||
|
|
||||||
CXX = $(PROGRAM_PREFIX)clang++
|
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++
|
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
|
OBJ += player/opensl_player.o player/oboe_player.o
|
||||||
|
|
||||||
|
|
|
@ -45,38 +45,11 @@ OboePlayer::OboePlayer(boost::asio::io_context& io_context, const ClientSettings
|
||||||
LOG(INFO, LOG_TAG) << "DefaultStreamValues::SampleRate: " << oboe::DefaultStreamValues::SampleRate
|
LOG(INFO, LOG_TAG) << "DefaultStreamValues::SampleRate: " << oboe::DefaultStreamValues::SampleRate
|
||||||
<< ", DefaultStreamValues::FramesPerBurst: " << oboe::DefaultStreamValues::FramesPerBurst << "\n";
|
<< ", 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.
|
auto result = openStream();
|
||||||
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_);
|
|
||||||
LOG(INFO, LOG_TAG) << "BufferSizeInFrames: " << out_stream_->getBufferSizeInFrames() << ", FramesPerBurst: " << out_stream_->getFramesPerBurst() << "\n";
|
LOG(INFO, LOG_TAG) << "BufferSizeInFrames: " << out_stream_->getBufferSizeInFrames() << ", FramesPerBurst: " << out_stream_->getFramesPerBurst() << "\n";
|
||||||
if (result != oboe::Result::OK)
|
if (result != oboe::Result::OK)
|
||||||
LOG(ERROR, LOG_TAG) << "Error building AudioStream: " << oboe::convertToText(result) << "\n";
|
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";
|
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
|
bool OboePlayer::needsThread() const
|
||||||
{
|
{
|
||||||
return false;
|
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()
|
void OboePlayer::start()
|
||||||
{
|
{
|
||||||
// Typically, start the stream after querying some stream information, as well as some input from the user
|
// Typically, start the stream after querying some stream information, as well as some input from the user
|
||||||
|
|
|
@ -39,7 +39,13 @@ public:
|
||||||
void stop() override;
|
void stop() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// AudioStreamCallback overrides
|
||||||
oboe::DataCallbackResult onAudioReady(oboe::AudioStream* oboeStream, void* audioData, int32_t numFrames) override;
|
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;
|
double getCurrentOutputLatencyMillis() const;
|
||||||
|
|
||||||
bool needsThread() const override;
|
bool needsThread() const override;
|
||||||
|
|
|
@ -52,6 +52,8 @@ Resampler::Resampler(const SampleFormat& in_format, const SampleFormat& out_form
|
||||||
// initialize the buffer with 20ms (~latency of the reampler)
|
// initialize the buffer with 20ms (~latency of the reampler)
|
||||||
resample_buffer_.resize(out_format_.frameSize() * static_cast<uint16_t>(ceil(out_format_.msRate() * 20)));
|
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
|
#endif
|
||||||
// resampled_chunk_ = std::make_unique<msg::PcmChunk>(out_format_, 0);
|
// resampled_chunk_ = std::make_unique<msg::PcmChunk>(out_format_, 0);
|
||||||
}
|
}
|
||||||
|
|
2
externals/Makefile
vendored
2
externals/Makefile
vendored
|
@ -137,7 +137,7 @@ oboe: check-env
|
||||||
rm -rf build;
|
rm -rf build;
|
||||||
|
|
||||||
soxr: check-env
|
soxr: check-env
|
||||||
@cd /home/johannes/Develop/soxr; \
|
@cd soxr; \
|
||||||
export CC="$(CC)"; \
|
export CC="$(CC)"; \
|
||||||
export CXX="$(CXX)"; \
|
export CXX="$(CXX)"; \
|
||||||
export CPPFLAGS="$(CPPFLAGS)"; \
|
export CPPFLAGS="$(CPPFLAGS)"; \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue