SDL2:Android APP编译使用 -- SDL2多媒体库使用音频实例


更多内容:XiaoJ的知识星球


SDL2:Android APP编译使用


SDL2(Simple DirectMedia Layer 2)是一个开源的跨平台多媒体开发库,它提供了一套简洁高效的API,用于处理图形渲染、音频播放、输入设备管理等功能,帮助开发者轻松创建出能在多种操作系统上运行的多媒体应用程序。

3. SDL2:Android APP编译使用

参考:https://github.com/mayzelf/SDL2/blob/release-2.28.4/docs/README-android.md

3.1 Android Studio环境准备:

(1)安装JDK、Android Studio

(2)安装Android SDK、Android NDK

shell 复制代码
export AS_DIR=$MY_ENV_HOME/App/Android_Studio/android-studio-2022.1.1.19
export ANDROID_HOME=$MY_ENV_HOME/App/Android_Studio/Android-2022.1.1.19
export ANDROID_NDK_HOME=$ANDROID_HOME/Sdk/ndk/28.0.12674087
export PATH=$PATH:$AS_DIR

3.2 构建Android APP

先下载SDL2源代码,SDL2官方网站下载或以下方式:

shell 复制代码
wget https://www.libsdl.org/release/SDL2-2.28.4.tar.gz
tar -zxvf SDL2-2.28.4.tar.gz
mv  SDL2-2.28.4   /home/SDL

有以下方式,构建不同程度需求的APK:

(1)方式一:快速构建APK工程
shell 复制代码
cd /home/SDL 
cd build-scripts
./androidbuild.sh org.libsdl.testgles ../test/testgles.c
# 或
# ./androidbuild.sh org.libsdl.audio ../test/*audio*


# 输出
To build and install to a device for testing, run the following:
cd /home/SDL/build/org.libsdl.testgles
./gradlew installDebug
(2)方式二:自定义APK工程

1.将 SDL/android-project 目录复制并重命名,如YOURPROJECT

2.将 SDL 目录移动或符号链接到 YOURPROJECT/app/jni目录。

3.编辑YOURPROJECT/app/jni/src/Android.mk以包含您的源文件:

  • 它们应该在 LOCAL_SRC_FILES := 声明后用空格分隔

4a.如想用 Android Studio,只需打开您的YOURPROJECT目录并开始构建。

4b. 如要手动构建,在项目目录运行 ./gradlew installDebug

  • 它将在任何连接的 Android 设备上构建和安装您的 .apk

实际操作如下:

shell 复制代码
# 构建工程目录
cp -rf  SDL/android-project/  YOURPROJECT
cp -rf  SDL  YOURPROJECT/app/jni/SDL

# APK工程相应修改
    # (1) 替换源和gradle版本:
    # 打开YOURPROJECT/gradle/wrapper/gradle-wrapper.properties
    #distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
    distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-7.5-bin.zip
    # 打开YOURPROJECT/build.gradle
        // classpath 'com.android.tools.build:gradle:8.1.1'
        classpath 'com.android.tools.build:gradle:7.4.0'

    # (2) 添加音频权限声明: 在AndroidManifest.xml中添加
    <uses-permission android:name="android.permission.RECORD_AUDIO"/>

    # (3) 生成源文件:YOURPROJECT/app/jni/src/*.cpp(例如testSDL2.cpp, 代码详情附在下面)
    # 在YOURPROJECT/app/jni/src/Android.mk中,"LOCAL_SRC_FILES := " 声明*.cpp后用空格分隔

# 编译运行apk
  # 方式一:用 Android Studio构建
  # 方式二:运行 ./gradlew installDebug
cpp 复制代码
#include "SDL.h"

#include <stdlib.h>
#include <stdio.h>

static SDL_AudioSpec spec;
static SDL_AudioDeviceID devid_in = 0;
static SDL_AudioDeviceID devid_out = 0;

static void
audio_callback(void *userdata, Uint8 *stream, int len)
{
    // 这里可以添加音频处理逻辑
    SDL_Log("标志:音频回调函数被调用,数据长度 = %d\n", len);
}

int main(int argc, char **argv)
{
    SDL_AudioSpec wanted;
    int devcount;
    int i;

    /* 启用标准应用程序日志 */
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);

    /* 加载SDL库 */
    if (SDL_Init(SDL_INIT_AUDIO) < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "标志:无法初始化SDL: %s\n", SDL_GetError());
        return 1;
    }

    SDL_Log("标志:使用的音频驱动: %s\n", SDL_GetCurrentAudioDriver());

    devcount = SDL_GetNumAudioDevices(SDL_TRUE);
    for (i = 0; i < devcount; i++) {
        SDL_Log("标志:捕获设备 #%d: '%s'\n", i, SDL_GetAudioDeviceName(i, SDL_TRUE));
    }

	SDL_zero(wanted);
	wanted.freq = 44100;  // 采样率
	wanted.format = AUDIO_S16SYS;  // 格式
	wanted.channels = 1;  // 通道数
	wanted.samples = 1024;  // 样本数
	wanted.callback = audio_callback;

    SDL_zero(spec);

    /* 打开默认播放设备 */
    SDL_Log("标志:打开默认播放设备...\n");
    devid_out = SDL_OpenAudioDevice(NULL, SDL_FALSE, &wanted, &spec, SDL_AUDIO_ALLOW_ANY_CHANGE);
    if (!devid_out) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "标志:无法打开音频播放设备: %s!\n", SDL_GetError());
        SDL_Quit();
        exit(1);
    }

    /* 打开默认捕获设备 */
    SDL_Log("标志:打开默认捕获设备...\n");
    // devid_in = SDL_OpenAudioDevice(NULL, SDL_TRUE, &spec, &spec, 0);
    devid_in = SDL_OpenAudioDevice(SDL_GetAudioDeviceName(0, SDL_TRUE), SDL_TRUE, &spec, &spec, 0);
    if (!devid_in) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "标志:无法打开音频捕获设备: %s!\n", SDL_GetError());
        SDL_Quit();
        exit(1);
    }

    SDL_Log("标志:音频设备成功打开!\n");

    /* 启动音频播放和捕获 */
    SDL_PauseAudioDevice(devid_out, 0);
    SDL_PauseAudioDevice(devid_in, 0);

    SDL_Log("标志:音频播放和捕获已启动。按回车键停止。\n");

    /* 等待用户输入停止 */
    getchar();

    /* 停止音频播放和捕获 */
    SDL_PauseAudioDevice(devid_out, 1);
    SDL_PauseAudioDevice(devid_in, 1);

    SDL_Log("标志:关闭音频设备。\n");

    /* 关闭音频设备 */
    SDL_CloseAudioDevice(devid_out);
    SDL_CloseAudioDevice(devid_in);

    /* 退出SDL库 */
    SDL_Quit();

    return 0;
}
(3)方式三:CMake构建APK工程

1.将 SDL/android-project 目录复制并重命名,如YOURPROJECT

2.将 SDL 目录移动或符号链接到 YOURPROJECT/app/jni目录。

3.编辑YOURPROJECT/app/build.gradle:注掉 ndk-build 的部分,取消注释 cmake 部分。向CMake调用添加参数。

4.编辑YOURPROJECT/app/jni/CMakeLists.txt以包含您的项目(默认添加src子目录):

  • 请注意,您的项目中将 SDL2、SDL2main 和 SDL2-static 作为目标,因此您的 CMakeLists.txt 文件中应该有target_link_libraries(yourgame SDL2 SDL2main)

  • 另请注意,对包含main函数的目标,应使用add_library()而不是add_executable()

5a. 如想用 Android Studio,只需打开您的YOURPROJECT目录并开始构建。

6b. 如要手动构建,在项目目录运行 ./gradlew installDebug

  • 它将在任何连接的 Android 设备上构建和安装您的 .apk

3.3 android-project 项目文件说明

bash 复制代码
android-project/app
    build.gradle            - 构建信息,包括应用程序版本和SDK
    src/main/AndroidManifest.xml    - 包清单。其中包含主Activity的类名和应用程序的包名等信息。
    jni/                    - 存放原生代码的目录
    jni/Application.mk      - 应用程序JNI设置,包括目标平台和STL库
    jni/Android.mk          - 可递归调用所有子目录中Android.mk文件的Android makefile
    jni/CMakeLists.txt      - 顶级CMake项目,将SDL作为子项目添加
    jni/SDL/                - (指向)存放SDL库文件的目录
    jni/SDL/Android.mk      - 创建SDL共享库的Android makefile
    jni/src/                - 存放C/C++源代码的目录
    jni/src/Android.mk      - 你应该定制的Android makefile,用于包含源代码和任何库引用
    jni/src/CMakeLists.txt  - 你可以定制的CMake文件,用于包含源代码和任何库引用
    src/main/assets/        - 存放应用程序资产文件的目录
    src/main/res/           - 存放应用程序资源的目录
    src/main/res/mipmap-*   - 存放不同手机硬件图标文件的目录
    src/main/res/values/strings.xml - 应用程序中使用的字符串,包括应用程序名称
    src/main/java/org/libsdl/app/SDLActivity.java - 处理SDL初始化和绑定的Java类。要非常小心地修改这个类,因为SDL库依赖于这个实现。你应该为你的应用程序继承这个类。

.


声明:资源可能存在第三方来源,若有侵权请联系删除!

相关推荐
xiangpanf7 小时前
Laravel 10.x重磅升级:五大核心特性解析
android
robotx10 小时前
安卓线程相关
android
消失的旧时光-194310 小时前
Android 面试高频:JSON 文件、大数据存储与断电安全(从原理到工程实践)
android·面试·json
dalancon11 小时前
VSYNC 信号流程分析 (Android 14)
android
dalancon11 小时前
VSYNC 信号完整流程2
android
dalancon11 小时前
SurfaceFlinger 上帧后 releaseBuffer 完整流程分析
android
用户693717500138412 小时前
不卷AI速度,我卷自己的从容——北京程序员手记
android·前端·人工智能
程序员Android13 小时前
Android 刷新一帧流程trace拆解
android
墨狂之逸才13 小时前
解决 Android/Gradle 编译报错:Comparison method violates its general contract!
android
阿明的小蝴蝶14 小时前
记一次Gradle环境的编译问题与解决
android·前端·gradle