【Android 高性能音频】Oboe 开发流程 ( Oboe 完整代码示例 )
文章目錄
- 一、GitHub 地址
- 二、Oboe C++ 代碼
- 三、日志封裝
- 四、Activity 代碼
- 五、AndroidManifest.xml 配置文件
- 六、CMakeLists.txt 構建腳本
- 七、應用 build.gradle 構建腳本
- 八、工程 build.gradle 構建腳本
- 九、Gradle 配置腳本 gradle-wrapper.properties
- 十、配置總結
Oboe GitHub 主頁 : GitHub/Oboe
-
① 簡單使用 : Getting Started
-
② Oboe 全指南 : Full Guide To Oboe
-
③ Oboe API 參考 : API reference
-
④ Android 音頻框架發展 : Android audio history
在 【Android 高性能音頻】Oboe 開發流程 ( 導入 Oboe 庫 | 使用預構建的二進制庫和頭文件 | 編譯 Oboe 源碼 ) 博客中介紹了 如何導入 Oboe 函數庫到項目中 , 本博客中在導入 Oboe 函數庫的基礎上 , 進行 Oboe 播放器功能開發 ;
在 【Android 高性能音頻】Oboe 開發流程 ( 包含頭 Oboe 頭文件 | 創建音頻流 | 設置音頻流 | 音頻流回調類 AudioStreamCallback ) 介紹了如何創建 AudioStreamBuilder , 以及 創建 AudioStreamCallback 回調 ;
在 【Android 高性能音頻】Oboe 開發流程 ( 創建并設置 AudioStreamCallback 對象 | 打開 Oboe 音頻流 | 日志封裝 logging_macros.h ) 博客中介紹了 設置 AudioStreamCallback 對象 , 打開 Oboe 音頻流 操作 , 以及 Google 官方提供的日志封裝有文件 ;
在 【Android 高性能音頻】Oboe 開發流程 ( 檢查 Oboe 音頻流屬性 | 開始播放 | 停止播放 | 關閉 Oboe 音頻流 | 重新配置 Oboe 音頻流屬性 ) 博客中介紹了 如何開始 Oboe 音頻流播放 , 以及 播放完畢后的收尾工作 ;
本篇博客中 , 完整的完成一個 Oboe 播放器的播放操作 ; 代碼中有詳細的注釋 ;
一、GitHub 地址
GitHub 地址 : https://github.com/han1202012/OboeDemo
二、Oboe C++ 代碼
#include <jni.h> #include <string> #include <oboe/Oboe.h> #include "logging_macros.h"// 這部分變量是采樣相關的 , 與 Oboe 操作無關 // 聲道個數 , 2 代表立體聲 static int constexpr kChannelCount = 2; static int constexpr kSampleRate = 48000; // Wave params, these could be instance variables in order to modify at runtime static float constexpr kAmplitude = 0.5f; // 頻率 static float constexpr kFrequency = 440; // PI 圓周率 static float constexpr kPI = M_PI; // 2 PI 兩倍圓周率 static float constexpr kTwoPi = kPI * 2; // 每次累加的采樣值 static double constexpr mPhaseIncrement = kFrequency * kTwoPi / (double) kSampleRate; // 追蹤當前波形位置 float mPhase = 0.0;// Oboe 音頻流回調類 class MyCallback : public oboe::AudioStreamCallback { public:oboe::DataCallbackResultonAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames) {// 需要生成 AudioFormat::Float 類型數據 , 該緩沖區類型也是該類型// 生產者需要檢查該格式// oboe::AudioStream *audioStream 已經轉換為適當的類型// 獲取音頻數據緩沖區auto *floatData = static_cast<float *>(audioData);// 生成正弦波數據for (int i = 0; i < numFrames; ++i) {float sampleValue = kAmplitude * sinf(mPhase);for (int j = 0; j < kChannelCount; j++) {floatData[i * kChannelCount + j] = sampleValue;}mPhase += mPhaseIncrement;if (mPhase >= kTwoPi) mPhase -= kTwoPi;}LOGI("回調 onAudioReady");return oboe::DataCallbackResult::Continue;} };// 創建 MyCallback 對象 MyCallback myCallback = MyCallback(); // 聲明 Oboe 音頻流 oboe::ManagedStream managedStream = oboe::ManagedStream();extern "C" JNIEXPORT jstring JNICALL Java_kim_hsl_oboedemo_MainActivity_stringFromJNI(JNIEnv* env,jobject /* this */) {// 1. 音頻流構建器oboe::AudioStreamBuilder builder = oboe::AudioStreamBuilder();// 設置音頻流方向builder.setDirection(oboe::Direction::Output);// 設置性能優先級builder.setPerformanceMode(oboe::PerformanceMode::LowLatency);// 設置共享模式 , 獨占builder.setSharingMode(oboe::SharingMode::Exclusive);// 設置音頻采樣格式builder.setFormat(oboe::AudioFormat::Float);// 設置聲道數 , 單聲道/立體聲builder.setChannelCount(oboe::ChannelCount::Stereo);// 設置采樣率builder.setSampleRate(48000);// 設置回調對象 , 注意要設置 AudioStreamCallback * 指針類型builder.setCallback(&myCallback);// 2. 通過 AudioStreamBuilder 打開 Oboe 音頻流oboe::Result result = builder.openManagedStream(managedStream);LOGI("openManagedStream result : %s", oboe::convertToText(result));// 3. 開始播放result = managedStream->requestStart();LOGI("requestStart result : %s", oboe::convertToText(result));// 返回數據到std::string hello = "Oboe Test " + std::to_string(static_cast<int>(oboe::PerformanceMode::LowLatency)) + " Result : " + oboe::convertToText(result);return env->NewStringUTF(hello.c_str()); }
三、日志封裝
Google 中提供了一個很好的 log 封裝頭文件 , logging_macros.h , 很多官方示例中都使用這個頭文件 ;
#ifndef __SAMPLE_ANDROID_DEBUG_H__ #define __SAMPLE_ANDROID_DEBUG_H__ #include <android/log.h>#if 1 #ifndef MODULE_NAME #define MODULE_NAME "octopus" #endif#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, MODULE_NAME, __VA_ARGS__) #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, MODULE_NAME, __VA_ARGS__) #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, MODULE_NAME, __VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,MODULE_NAME, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,MODULE_NAME, __VA_ARGS__) #define LOGF(...) __android_log_print(ANDROID_LOG_FATAL,MODULE_NAME, __VA_ARGS__)#define ASSERT(cond, ...) if (!(cond)) {__android_log_assert(#cond, MODULE_NAME, __VA_ARGS__);} #else#define LOGV(...) #define LOGD(...) #define LOGI(...) #define LOGW(...) #define LOGE(...) #define LOGF(...) #define ASSERT(cond, ...)#endif#endif // __SAMPLE_ANDROID_DEBUG_H__四、Activity 代碼
package kim.hsl.oboedemoimport androidx.appcompat.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_main.*class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)sample_text.text = stringFromJNI()}external fun stringFromJNI(): Stringcompanion object {init {System.loadLibrary("native-lib")}} }
五、AndroidManifest.xml 配置文件
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="kim.hsl.oboedemo"><uses-feature android:name="android.hardware.audio.output" android:required="true" /><uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MainActivity"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application></manifest>
六、CMakeLists.txt 構建腳本
cmake_minimum_required(VERSION 3.4.1)add_library(native-libSHAREDnative-lib.cpp )find_package (oboe REQUIRED CONFIG)target_link_libraries(native-liboboe::oboelog )
七、應用 build.gradle 構建腳本
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions'android {compileSdkVersion 29buildToolsVersion "30.0.2"defaultConfig {applicationId "kim.hsl.oboedemo"minSdkVersion 18targetSdkVersion 29versionCode 1versionName "1.0"testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"externalNativeBuild {cmake {cppFlags ""arguments "-DANDROID_STL=c++_shared"}}}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'}}externalNativeBuild {cmake {path "src/main/cpp/CMakeLists.txt"version "3.10.2"}}buildFeatures {prefab true}}dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"implementation 'androidx.appcompat:appcompat:1.2.0'implementation 'androidx.core:core-ktx:1.3.2'implementation 'androidx.constraintlayout:constraintlayout:2.0.2'testImplementation 'junit:junit:4.12'androidTestImplementation 'androidx.test.ext:junit:1.1.2'androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'implementation 'com.google.oboe:oboe:1.4.3' }
八、工程 build.gradle 構建腳本
// Top-level build file where you can add configuration options common to all sub-projects/modules.buildscript {ext.kotlin_version = '1.3.71'repositories {google()jcenter()}dependencies {classpath 'com.android.tools.build:gradle:4.1.0'classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"} }allprojects {repositories {google()jcenter()} }task clean(type: Delete) {delete rootProject.buildDir }
九、Gradle 配置腳本 gradle-wrapper.properties
#Tue Oct 13 10:20:09 CST 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
十、配置總結
配置總結 :
- Android Studio 版本 : 4.1
- Gradle 版本 : 6.6.1
- Gradle 插件版本 : 4.1.0
總結
以上是生活随笔為你收集整理的【Android 高性能音频】Oboe 开发流程 ( Oboe 完整代码示例 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android 高性能音频】Oboe
- 下一篇: 【组合数学】组合数学简介 ( 组合数学脉