This commit is contained in:
rustdesk 2022-05-12 17:55:49 +08:00
parent 2e75028d83
commit 1ab061a690
3 changed files with 273 additions and 3 deletions

View File

@ -40,7 +40,7 @@ fn install_oboe() {
} else {
target_arch = "arm".to_owned();
}
let target = format!("{}-android-static", target_arch);
let target = format!("{}-android", target_arch);
let vcpkg_root = std::env::var("VCPKG_ROOT").unwrap();
let mut path: std::path::PathBuf = vcpkg_root.into();
path.push("installed");
@ -63,12 +63,17 @@ fn install_oboe() {
}
fn main() {
hbb_common::gen_version();
install_oboe();
// there is problem with cfg(target_os) in build.rs, so use our workaround
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
if target_os == "android" || target_os == "ios" {
return;
}
#[cfg(all(windows, feature = "inline"))]
build_manifest();
#[cfg(windows)]
build_windows();
#[cfg(target_os = "macos")]
println!("cargo:rustc-link-lib=framework=ApplicationServices");
hbb_common::gen_version();
install_oboe();
}

118
src/oboe.cc Normal file
View File

@ -0,0 +1,118 @@
#include <oboe/Oboe.h>
#include <math.h>
#include <deque>
#include <pthread.h>
// I got link problem with std::mutex, so use pthread instead
class CThreadLock
{
public:
CThreadLock();
virtual ~CThreadLock();
void Lock();
void Unlock();
private:
pthread_mutex_t mutexlock;
};
CThreadLock::CThreadLock()
{
// init lock here
pthread_mutex_init(&mutexlock, 0);
}
CThreadLock::~CThreadLock()
{
// deinit lock here
pthread_mutex_destroy(&mutexlock);
}
void CThreadLock::Lock()
{
// lock
pthread_mutex_lock(&mutexlock);
}
void CThreadLock::Unlock()
{
// unlock
pthread_mutex_unlock(&mutexlock);
}
class Player : public oboe::AudioStreamDataCallback
{
public:
Player(int channels, int sample_rate)
{
this->channels = channels;
oboe::AudioStreamBuilder builder;
// The builder set methods can be chained for convenience.
builder.setSharingMode(oboe::SharingMode::Exclusive)
->setPerformanceMode(oboe::PerformanceMode::LowLatency)
->setChannelCount(channels)
->setSampleRate(sample_rate)
->setFormat(oboe::AudioFormat::Float)
->setDataCallback(this)
->openManagedStream(outStream);
// Typically, start the stream after querying some stream information, as well as some input from the user
outStream->requestStart();
}
~Player() {
outStream->requestStop();
}
oboe::DataCallbackResult onAudioReady(oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames) override
{
float *floatData = (float *)audioData;
int i = 0;
mtx.Lock();
auto n = channels * numFrames;
for (; i < n && i < (int)buffer.size(); ++i, ++floatData)
{
*floatData = buffer.front();
buffer.pop_front();
}
mtx.Unlock();
for (; i < n; ++i, ++floatData)
{
*floatData = 0;
}
return oboe::DataCallbackResult::Continue;
}
void push(const float *v, int n)
{
mtx.Lock();
for (auto i = 0; i < n; ++i, ++v)
buffer.push_back(*v);
// in case memory overuse
if (buffer.size() > 48 * 1024 * 120)
buffer.clear();
mtx.Unlock();
}
private:
oboe::ManagedStream outStream;
int channels;
std::deque<float> buffer;
CThreadLock mtx;
};
extern "C"
{
void *create_oboe_player(int channels, int sample_rate)
{
return new Player(channels, sample_rate);
}
void push_oboe_data(void *player, const float* v, int n)
{
static_cast<Player *>(player)->push(v, n);
}
void destroy_oboe_player(void *player)
{
delete static_cast<Player *>(player);
}
}

147
src/oboe.patch Normal file
View File

@ -0,0 +1,147 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 51a45b2..75be96a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -60,7 +60,7 @@ set (oboe_sources
src/common/Version.cpp
)
-add_library(oboe ${oboe_sources})
+ add_library(oboe STATIC ${oboe_sources})
# Specify directories which the compiler should look for headers
target_include_directories(oboe
@@ -91,4 +91,4 @@ install(TARGETS oboe
ARCHIVE DESTINATION lib/${ANDROID_ABI})
# Also install the headers
-install(DIRECTORY include/oboe DESTINATION include)
\ No newline at end of file
+install(DIRECTORY include/oboe DESTINATION include)
diff --git a/src/common/AudioStreamBuilder.cpp b/src/common/AudioStreamBuilder.cpp
index dffcd75..79984a4 100644
--- a/src/common/AudioStreamBuilder.cpp
+++ b/src/common/AudioStreamBuilder.cpp
@@ -215,3 +215,122 @@ Result AudioStreamBuilder::openStream(std::shared_ptr<AudioStream> &sharedStream
}
} // namespace oboe
+
+#include <oboe/Oboe.h>
+#include <math.h>
+#include <deque>
+#include <pthread.h>
+
+// I got link problem with std::mutex, so use pthread instead
+class CThreadLock
+{
+public:
+ CThreadLock();
+ virtual ~CThreadLock();
+
+ void Lock();
+ void Unlock();
+
+private:
+ pthread_mutex_t mutexlock;
+};
+
+CThreadLock::CThreadLock()
+{
+ // init lock here
+ pthread_mutex_init(&mutexlock, 0);
+}
+
+CThreadLock::~CThreadLock()
+{
+ // deinit lock here
+ pthread_mutex_destroy(&mutexlock);
+}
+void CThreadLock::Lock()
+{
+ // lock
+ pthread_mutex_lock(&mutexlock);
+}
+void CThreadLock::Unlock()
+{
+ // unlock
+ pthread_mutex_unlock(&mutexlock);
+}
+
+class Player : public oboe::AudioStreamDataCallback
+{
+public:
+ ~Player() {
+ outStream->requestStop();
+ }
+
+ Player(int channels, int sample_rate)
+ {
+ this->channels = channels;
+ oboe::AudioStreamBuilder builder;
+ // The builder set methods can be chained for convenience.
+ builder.setSharingMode(oboe::SharingMode::Exclusive)
+ ->setPerformanceMode(oboe::PerformanceMode::LowLatency)
+ ->setChannelCount(channels)
+ ->setSampleRate(sample_rate)
+ ->setFormat(oboe::AudioFormat::Float)
+ ->setDataCallback(this)
+ ->openManagedStream(outStream);
+ // Typically, start the stream after querying some stream information, as well as some input from the user
+ outStream->requestStart();
+ }
+
+ oboe::DataCallbackResult onAudioReady(oboe::AudioStream *oboeStream, void *audioData, int32_t numFrames) override
+ {
+ float *floatData = (float *)audioData;
+ int i = 0;
+ mtx.Lock();
+ auto n = channels * numFrames;
+ for (; i < n && i < (int)buffer.size(); ++i, ++floatData)
+ {
+ *floatData = buffer.front();
+ buffer.pop_front();
+ }
+ mtx.Unlock();
+ for (; i < n; ++i, ++floatData)
+ {
+ *floatData = 0;
+ }
+ return oboe::DataCallbackResult::Continue;
+ }
+
+ void push(const float *v, int n)
+ {
+ mtx.Lock();
+ for (auto i = 0; i < n; ++i, ++v)
+ buffer.push_back(*v);
+ // in case memory overuse
+ if (buffer.size() > 48 * 1024 * 120)
+ buffer.clear();
+ mtx.Unlock();
+ }
+
+private:
+ oboe::ManagedStream outStream;
+ int channels;
+ std::deque<float> buffer;
+ CThreadLock mtx;
+};
+
+extern "C"
+{
+ void *create_oboe_player(int channels, int sample_rate)
+ {
+ return new Player(channels, sample_rate);
+ }
+
+ void push_oboe_data(void *player, const float* v, int n)
+ {
+ static_cast<Player *>(player)->push(v, n);
+ }
+
+ void destroy_oboe_player(void *player)
+ {
+ delete static_cast<Player *>(player);
+ }
+}