PaddleSpeech的TTSAndroid编译armv7版本

1.下载docker镜像

docker pull paddlepaddle/paddle-lite:2.0.0_beta

2.克隆代码

git clone https://github.com/PaddlePaddle/Paddle-Lite.git

3.运行容器

docker run -it --name paddlelite_docker  -v $PWD/Paddle-Lite:/Paddle-Lite  --net=host paddlepaddle/paddle-lite /bin/bash

4.编译opt工具

cd Paddle-Lite
./lite/tools/build.sh build_optimize_tool --with_extra=ON

5.下载模型

https://paddlespeech.bj.bcebos.com/Parakeet/released_models/fastspeech2/fastspeech2_cnndecoder_csmsc_static_1.0.0.zip

https://paddlespeech.bj.bcebos.com/Parakeet/released_models/mb_melgan/mb_melgan_csmsc_static_0.1.1.zip

mb_melgan_csmsc_static_0.1.1.zip

fastspeech2_cnndecoder_csmsc_static_1.0.0.zip

6.模型转换

cd /Paddle-Lite/build.opt/lite/api
./opt --model_file=/Paddle-Lite/models/fastspeech2_cnndecoder_csmsc_static_1.0.0/fastspeech2_csmsc.pdmodel --param_file=/Paddle-Lite/models/fastspeech2_cnndecoder_csmsc_static_1.0.0/fastspeech2_csmsc.pdiparams --valid_targets=arm --optimize_out_type=naive_buffer --optimize_out=/Paddle-Lite/models/fastspeech2_csmsc_arm --quant_model=true --quant_type=QUANT_INT8 

./opt --model_file=/Paddle-Lite/models/mb_melgan_csmsc_static_0.1.1/mb_melgan_csmsc.pdmodel --param_file=/Paddle-Lite/models/mb_melgan_csmsc_static_0.1.1/mb_melgan_csmsc.pdiparams --valid_targets=arm --optimize_out_type=naive_buffer --optimize_out=/Paddle-Lite/models/mb_melgan_csmsc_arm --quant_model=true --quant_type=QUANT_INT8

mb_melgan_csmsc_arm.nb

fastspeech2_csmsc_arm.nb

7.编译预测动态库

a.修改代码Paddle-Lite/lite/kernels/arm/slice_compute.cc

inline std::vector<int64_t> get_new_data_from_tensorlist(
    const std::vector<lite::Tensor*>& list_new_data_tensor) {
  // get tensor
  std::vector<int64_t> vec_new_data;
  for (size_t i = 0; i < list_new_data_tensor.size(); ++i) {
    auto tensor = list_new_data_tensor[i];
    LOG(WARNING) <<" tensor dims is :"<<tensor->dims();
    // CHECK_EQ(tensor->dims(), DDim({1})) << "shape of dim tensor should be [1]";
    if (tensor->precision() == PrecisionType::kInt32) {
      vec_new_data.push_back(static_cast<int64_t>(*tensor->data<int32_t>()));
    } else if (tensor->precision() == PrecisionType::kInt64) {
      vec_new_data.push_back(static_cast<int64_t>(*tensor->data<int64_t>()));
    } else {
      vec_new_data.push_back(static_cast<int64_t>(*tensor->data<int32_t>()));
      LOG(WARNING) << "slice StartsTensor or EndsTensor :The dtype of Tensor "
                      "must be int32 "
                      "or int64";
    }
  }
  return vec_new_data;
}

b.修改Paddle-Lite/lite/api/android/jni/native/tensor_jni.h,新增声明

/*
 * Class:     com_baidu_paddle_lite_Tensor
 * Method:    nativeSetData
 * Signature: ([J)Z
 */
JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_lite_Tensor_nativeSetData___3J(
    JNIEnv *, jobject, jlongArray);

c.修改Paddle-Lite/lite/api/android/jni/native/tensor_jni.cc,新增实现

JNIEXPORT jboolean JNICALL Java_com_baidu_paddle_lite_Tensor_nativeSetData___3J(
    JNIEnv *env, jobject jtensor, jlongArray buf) {
  std::unique_ptr<Tensor> *tensor = get_writable_tensor_pointer(env, jtensor);
  if (tensor == nullptr || (*tensor == nullptr)) {
    return JNI_FALSE;
  }
  int64_t buf_size = (int64_t)env->GetArrayLength(buf);
  if (buf_size != product((*tensor)->shape())) {
    return JNI_FALSE;
  }

  int64_t *input = (*tensor)->mutable_data<int64_t>();
  env->GetLongArrayRegion(buf, 0, buf_size, input);
  return JNI_TRUE;
}

d.编译脚本

./lite/tools/build_android.sh --arch=armv7 --toolchain=gcc --android_stl=c++_static --with_java=ON --with_extra=ON

e.编译产物

libpaddle_lite_jni.so

8.调整Android工程代码

a.修改D:\02Code\code\PaddleSpeech-r1.4.1\demos\TTSAndroid\app\build.gradle

import java.security.MessageDigest

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.baidu.paddle.lite.demo.tts"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        ndk {
            abiFilters 'armeabi-v7a'//, 'arm64-v8a'

        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:design:28.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation files('libs/PaddlePredictor.jar')
}

b.修改com/baidu/paddle/lite/demo/tts/Predictor.java及对应的调用地方,主要是数据类型由float改为long

public boolean runModel(long[] phones) {
	if (!isLoaded()) {
		return false;
	}
	Date start = new Date();
	Tensor am_output_handle = getAMOutput(phones, AMPredictor);
	wav = getVOCOutput(am_output_handle, VOCPredictor);
	Date end = new Date();
	inferenceTime = (end.getTime() - start.getTime());
	Log.d(TAG, "runModel: "+inferenceTime+"ms");
	return true;
}

public Tensor getAMOutput(long[] phones, PaddlePredictor am_predictor) {
        Tensor phones_handle = am_predictor.getInput(0);
        long[] dims = {phones.length};
        phones_handle.resize(dims);
        phones_handle.setData(phones);
        am_predictor.run();
        Tensor am_output_handle = am_predictor.getOutput(0);
        // [?, 80]
        // long outputShape[] = am_output_handle.shape();
        float[] am_output_data = am_output_handle.getFloatData();
        return am_output_handle;
    }

c.工程结构
在这里插入图片描述
在这里插入图片描述

ndk需要于docker镜像一致,采用17.2
在这里插入图片描述

d.编译产出

TTSAndroid.apk
下载地址
https://download.csdn.net/download/q317379184/89316395

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
好的,以下是编译FFmpeg ARMv7-A版本的步骤: 1. 首先,你需要下载NDK工具包并解压。你可以从这里下载最新版本:https://developer.android.com/ndk/downloads/ 2. 接着,你需要下载FFmpeg源代码。你可以从这里下载最新版本:https://ffmpeg.org/download.html 3. 解压FFmpeg源代码并进入解压后的目录。 4. 执行以下命令以配置FFmpeg: ``` ./configure \ --disable-shared \ --enable-static \ --arch=arm \ --target-os=android \ --enable-cross-compile \ --cross-prefix=$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin/armv7a-linux-androideabi21- \ --sysroot=$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/sysroot \ --extra-cflags="-march=armv7-a -mfloat-abi=softfp -mfpu=neon" \ --extra-ldflags="-L$NDK_HOME/sources/cxx-stl/llvm-libc++/libs/armeabi-v7a -lc++_static" ``` 其中,$NDK_HOME是你解压NDK工具包的路径。上述命令的作用是配置FFmpeg,禁用共享库,启用静态库,指定编译目标为ARMv7-A架构,指定编译目标操作系统为Android,启用交叉编译,指定交叉编译工具链前缀,指定系统根目录,设置编译器选项和链接器选项。 5. 执行以下命令以编译FFmpeg: ``` make -j4 ``` 其中,-j4表示使用4个线程进行编译,你可以根据自己的情况进行调整。 6. 编译完成后,你可以在当前目录下的lib目录中找到编译好的静态库文件libavcodec.a、libavformat.a、libavutil.a等。 7. 最后,你可以将这些静态库文件打包成一个共享库文件,以便在Android应用中使用。你可以使用Android Studio或者手动编写Android.mk文件进行打包。 以上就是编译FFmpeg ARMv7-A版本的步骤,希望能对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

random_2011

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值