fix oboe
This commit is contained in:
parent
2e75028d83
commit
1ab061a690
11
build.rs
11
build.rs
@ -40,7 +40,7 @@ fn install_oboe() {
|
|||||||
} else {
|
} else {
|
||||||
target_arch = "arm".to_owned();
|
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 vcpkg_root = std::env::var("VCPKG_ROOT").unwrap();
|
||||||
let mut path: std::path::PathBuf = vcpkg_root.into();
|
let mut path: std::path::PathBuf = vcpkg_root.into();
|
||||||
path.push("installed");
|
path.push("installed");
|
||||||
@ -63,12 +63,17 @@ fn install_oboe() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
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"))]
|
#[cfg(all(windows, feature = "inline"))]
|
||||||
build_manifest();
|
build_manifest();
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
build_windows();
|
build_windows();
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
println!("cargo:rustc-link-lib=framework=ApplicationServices");
|
println!("cargo:rustc-link-lib=framework=ApplicationServices");
|
||||||
hbb_common::gen_version();
|
|
||||||
install_oboe();
|
|
||||||
}
|
}
|
||||||
|
118
src/oboe.cc
Normal file
118
src/oboe.cc
Normal 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
147
src/oboe.patch
Normal 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);
|
||||||
|
+ }
|
||||||
|
+}
|
Loading…
x
Reference in New Issue
Block a user