Add Oboe player for Android

This commit is contained in:
badaix 2020-01-24 23:06:12 +01:00
parent d826a89795
commit 5b9fc3d68d
7 changed files with 167 additions and 10 deletions

View file

@ -58,9 +58,9 @@ endif
ifeq ($(TARGET), ANDROID) ifeq ($(TARGET), ANDROID)
CXX = $(PROGRAM_PREFIX)clang++ CXX = $(PROGRAM_PREFIX)clang++
CXXFLAGS += -pthread -fPIC -DHAS_TREMOR -DHAS_OPENSL -I$(NDK_DIR)/include CXXFLAGS += -pthread -fPIC -DHAS_TREMOR -DHAS_OBOE -I$(NDK_DIR)/include -I/home/johannes/Develop/oboe/include
LDFLAGS = -L$(NDK_DIR)/lib -pie -lvorbisidec -logg -lopus -lFLAC -lOpenSLES -latomic -llog -static-libstdc++ LDFLAGS = -L$(NDK_DIR)/lib -pie -lvorbisidec -logg -lopus -lFLAC -lOpenSLES -loboe -latomic -llog -static-libstdc++
OBJ += player/opensl_player.o OBJ += player/oboe_player.o
else ifeq ($(TARGET), OPENWRT) else ifeq ($(TARGET), OPENWRT)

View file

@ -130,6 +130,8 @@ void Controller::onMessageReceived(ClientConnection* /*connection*/, const msg::
player_ = make_unique<AlsaPlayer>(pcmDevice_, stream_); player_ = make_unique<AlsaPlayer>(pcmDevice_, stream_);
#elif HAS_OPENSL #elif HAS_OPENSL
player_ = make_unique<OpenslPlayer>(pcmDevice_, stream_); player_ = make_unique<OpenslPlayer>(pcmDevice_, stream_);
#elif HAS_OBOE
player_ = make_unique<OboePlayer>(pcmDevice_, stream_);
#elif HAS_COREAUDIO #elif HAS_COREAUDIO
player_ = make_unique<CoreAudioPlayer>(pcmDevice_, stream_); player_ = make_unique<CoreAudioPlayer>(pcmDevice_, stream_);
#else #else

View file

@ -30,6 +30,8 @@
#include "player/alsa_player.hpp" #include "player/alsa_player.hpp"
#elif HAS_OPENSL #elif HAS_OPENSL
#include "player/opensl_player.hpp" #include "player/opensl_player.hpp"
#elif HAS_OBOE
#include "player/oboe_player.hpp"
#elif HAS_COREAUDIO #elif HAS_COREAUDIO
#include "player/coreaudio_player.hpp" #include "player/coreaudio_player.hpp"
#endif #endif

View file

@ -0,0 +1,87 @@
/***
This file is part of snapcast
Copyright (C) 2014-2020 Johannes Pohl
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#include <assert.h>
#include <iostream>
#include "common/aixlog.hpp"
#include "common/snap_exception.hpp"
#include "common/str_compat.hpp"
#include "oboe_player.hpp"
using namespace std;
OboePlayer::OboePlayer(const PcmDevice& pcmDevice, std::shared_ptr<Stream> stream) : Player(pcmDevice, stream), ms_(50), buff_size(0), pubStream_(stream)
{
oboe::AudioStreamBuilder builder;
// The builder set methods can be chained for convenience.
builder.setSharingMode(oboe::SharingMode::Exclusive)
->setPerformanceMode(oboe::PerformanceMode::LowLatency)
->setChannelCount(stream->getFormat().channels)
->setSampleRate(stream->getFormat().rate)
->setFormat(oboe::AudioFormat::I16)
->setCallback(this)
->openManagedStream(out_stream_);
}
OboePlayer::~OboePlayer()
{
}
oboe::DataCallbackResult OboePlayer::onAudioReady(oboe::AudioStream* oboeStream, void* audioData, int32_t numFrames)
{
int32_t buffer_fill_size = oboeStream->getBufferCapacityInFrames() - numFrames;
double delay_ms = static_cast<double>(buffer_fill_size) / stream_->getFormat().msRate();
chronos::usec delay(static_cast<int>(delay_ms * 1000.));
//LOG(INFO) << "onAudioReady frames: " << numFrames << ", capacity: " << oboeStream->getBufferCapacityInFrames() << ", size: " << oboeStream->getBufferSizeInFrames() << ", delay ms: " << delay_ms << "\n";
if (!stream_->getPlayerChunk(audioData, delay, numFrames))
{
// LOG(INFO) << "Failed to get chunk. Playing silence.\n";
memset(audioData, 0, numFrames);
}
else
{
adjustVolume(static_cast<char*>(audioData), numFrames);
}
return oboe::DataCallbackResult::Continue;
}
void OboePlayer::start()
{
// Typically, start the stream after querying some stream information, as well as some input from the user
out_stream_->requestStart();
}
void OboePlayer::stop()
{
out_stream_->requestStop();
}
void OboePlayer::worker()
{
}

View file

@ -0,0 +1,56 @@
/***
This file is part of snapcast
Copyright (C) 2014-2020 Johannes Pohl
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef OBOE_PLAYER_HPP
#define OBOE_PLAYER_HPP
#include <oboe/Oboe.h>
#include "player.hpp"
typedef int (*AndroidAudioCallback)(short* buffer, int num_samples);
/// OpenSL Audio Player
/**
* Player implementation for Oboe
*/
class OboePlayer : public Player, public oboe::AudioStreamCallback
{
public:
OboePlayer(const PcmDevice& pcmDevice, std::shared_ptr<Stream> stream);
virtual ~OboePlayer();
void start() override;
void stop() override;
protected:
oboe::DataCallbackResult onAudioReady(oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames) override;
void worker() override;
oboe::ManagedStream out_stream_;
size_t ms_;
size_t frames_;
size_t buff_size;
std::shared_ptr<Stream> pubStream_;
};
#endif

View file

@ -16,8 +16,8 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
***/ ***/
#ifndef OPEN_SL_PLAYER_H #ifndef OPEN_SL_PLAYER_HPP
#define OPEN_SL_PLAYER_H #define OPEN_SL_PLAYER_HPP
#include <SLES/OpenSLES.h> #include <SLES/OpenSLES.h>
#include <SLES/OpenSLES_Android.h> #include <SLES/OpenSLES_Android.h>
@ -38,8 +38,8 @@ public:
OpenslPlayer(const PcmDevice& pcmDevice, std::shared_ptr<Stream> stream); OpenslPlayer(const PcmDevice& pcmDevice, std::shared_ptr<Stream> stream);
virtual ~OpenslPlayer(); virtual ~OpenslPlayer();
virtual void start(); void start() override;
virtual void stop(); void stop() override;
void playerCallback(SLAndroidSimpleBufferQueueItf bq); void playerCallback(SLAndroidSimpleBufferQueueItf bq);
@ -47,7 +47,7 @@ protected:
void initOpensl(); void initOpensl();
void uninitOpensl(); void uninitOpensl();
virtual void worker(); void worker() override;
void throwUnsuccess(const std::string& phase, const std::string& what, SLresult result); void throwUnsuccess(const std::string& phase, const std::string& what, SLresult result);
std::string resultToString(SLresult result) const; std::string resultToString(SLresult result) const;

14
externals/Makefile vendored
View file

@ -14,9 +14,9 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
.PHONY: all check-env flac ogg opus tremor .PHONY: all check-env flac ogg opus tremor oboe
all: flac ogg opus tremor all: flac ogg opus tremor oboe
check-env: check-env:
# if [ ! -d "flac" ]; then \ # if [ ! -d "flac" ]; then \
@ -115,4 +115,14 @@ tremor: check-env
rm stamp-h1; \ rm stamp-h1; \
rm vorbisidec.pc; rm vorbisidec.pc;
oboe: check-env
@cd oboe; \
export CC="$(CC)"; \
export CXX="$(CXX)"; \
export CPPFLAGS="$(CPPFLAGS)"; \
mkdir build; \
cd build; \
cmake ..; \
make; \
make DESTDIR=$(NDK_DIR) install;