http://blog.csdn.net/chenfeng0104/article/details/7088138
在Android开发中,需要录音并发送到对方设备上。这时问题来了,手机常会是GPRS、3G等方式上网,所以节省流量是非常关键的,使用Speex来压缩音频文件,可以将音频压文件小数倍。

1.去Speex官网下载最新Speex源码

2.创建一个新的应用(我创建的应用名为Audio),并创建一个jni目录($project/jni)。

3.把speex源码目录下的libspeex和include目录及其子目录文件全部拷贝到$project/jni目录下($project/jni/libspeex and $project/jni/include)。

4.在jni目录下新增Android.mk文件,编辑内容如下

  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)
  3. LOCAL_MODULE    := libspeex
  4. LOCAL_CFLAGS = -DFIXED_POINT -DUSE_KISS_FFT -DEXPORT="" -UHAVE_CONFIG_H
  5. LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
  6. LOCAL_SRC_FILES :=  \
  7. ./speex_jni.cpp \
  8. ./libspeex/bits.c \
  9. ./libspeex/buffer.c \
  10. ./libspeex/cb_search.c \
  11. ./libspeex/exc_10_16_table.c \
  12. ./libspeex/exc_10_32_table.c \
  13. ./libspeex/exc_20_32_table.c \
  14. ./libspeex/exc_5_256_table.c \
  15. ./libspeex/exc_5_64_table.c \
  16. ./libspeex/exc_8_128_table.c \
  17. ./libspeex/fftwrap.c \
  18. ./libspeex/filterbank.c \
  19. ./libspeex/filters.c \
  20. ./libspeex/gain_table.c \
  21. ./libspeex/gain_table_lbr.c \
  22. ./libspeex/hexc_10_32_table.c \
  23. ./libspeex/hexc_table.c \
  24. ./libspeex/high_lsp_tables.c \
  25. ./libspeex/jitter.c \
  26. ./libspeex/kiss_fft.c \
  27. ./libspeex/kiss_fftr.c \
  28. ./libspeex/lpc.c \
  29. ./libspeex/lsp.c \
  30. ./libspeex/lsp_tables_nb.c \
  31. ./libspeex/ltp.c \
  32. ./libspeex/mdf.c \
  33. ./libspeex/modes.c \
  34. ./libspeex/modes_wb.c \
  35. ./libspeex/nb_celp.c \
  36. ./libspeex/preprocess.c \
  37. ./libspeex/quant_lsp.c \
  38. ./libspeex/resample.c \
  39. ./libspeex/sb_celp.c \
  40. ./libspeex/scal.c \
  41. ./libspeex/smallft.c \
  42. ./libspeex/speex.c \
  43. ./libspeex/speex_callbacks.c \
  44. ./libspeex/speex_header.c \
  45. ./libspeex/stereo.c \
  46. ./libspeex/vbr.c \
  47. ./libspeex/vq.c \
  48. ./libspeex/window.c
  49. include $(BUILD_SHARED_LIBRARY)

5.在jni目录下新增Application.mk文件,编辑内容如下

  1. APP_ABI := armeabi armeabi-v7a

6.在$project/jni/include/speex/目录下新增speex_config_types.h文件,编辑内容如下

  1. #ifndef __SPEEX_TYPES_H__
  2. #define __SPEEX_TYPES_H__
  3. typedef short spx_int16_t;
  4. typedef unsigned short spx_uint16_t;
  5. typedef int spx_int32_t;
  6. typedef unsigned int spx_uint32_t;
  7. #endif

7.创建JNI包装类speex_jni.cpp,用来调用Speex中的C代码函数,编辑内容如下

  1. #include <jni.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. #include <speex/speex.h>
  5. static int codec_open = 0;
  6. static int dec_frame_size;
  7. static int enc_frame_size;
  8. static SpeexBits ebits, dbits;
  9. void *enc_state;
  10. void *dec_state;
  11. static JavaVM *gJavaVM;
  12. extern "C"
  13. JNIEXPORT jint JNICALL Java_com_audio_Speex_open
  14. (JNIEnv *env, jobject obj, jint compression) {
  15. int tmp;
  16. if (codec_open++ != 0)
  17. return (jint)0;
  18. speex_bits_init(&ebits);
  19. speex_bits_init(&dbits);
  20. enc_state = speex_encoder_init(&speex_nb_mode);
  21. dec_state = speex_decoder_init(&speex_nb_mode);
  22. tmp = compression;
  23. speex_encoder_ctl(enc_state, SPEEX_SET_QUALITY, &tmp);
  24. speex_encoder_ctl(enc_state, SPEEX_GET_FRAME_SIZE, &enc_frame_size);
  25. speex_decoder_ctl(dec_state, SPEEX_GET_FRAME_SIZE, &dec_frame_size);
  26. return (jint)0;
  27. }
  28. extern "C"
  29. JNIEXPORT jint Java_com_audio_Speex_encode
  30. (JNIEnv *env, jobject obj, jshortArray lin, jint offset, jbyteArray encoded, jint size) {
  31. jshort buffer[enc_frame_size];
  32. jbyte output_buffer[enc_frame_size];
  33. int nsamples = (size-1)/enc_frame_size + 1;
  34. int i, tot_bytes = 0;
  35. if (!codec_open)
  36. return 0;
  37. speex_bits_reset(&ebits);
  38. for (i = 0; i < nsamples; i++) {
  39. env->GetShortArrayRegion(lin, offset + i*enc_frame_size, enc_frame_size, buffer);
  40. speex_encode_int(enc_state, buffer, &ebits);
  41. }
  42. //env->GetShortArrayRegion(lin, offset, enc_frame_size, buffer);
  43. //speex_encode_int(enc_state, buffer, &ebits);
  44. tot_bytes = speex_bits_write(&ebits, (char *)output_buffer,
  45. enc_frame_size);
  46. env->SetByteArrayRegion(encoded, 0, tot_bytes,
  47. output_buffer);
  48. return (jint)tot_bytes;
  49. }
  50. extern "C"
  51. JNIEXPORT jint JNICALL Java_com_audio_Speex_decode
  52. (JNIEnv *env, jobject obj, jbyteArray encoded, jshortArray lin, jint size) {
  53. jbyte buffer[dec_frame_size];
  54. jshort output_buffer[dec_frame_size];
  55. jsize encoded_length = size;
  56. if (!codec_open)
  57. return 0;
  58. env->GetByteArrayRegion(encoded, 0, encoded_length, buffer);
  59. speex_bits_read_from(&dbits, (char *)buffer, encoded_length);
  60. speex_decode_int(dec_state, &dbits, output_buffer);
  61. env->SetShortArrayRegion(lin, 0, dec_frame_size,
  62. output_buffer);
  63. return (jint)dec_frame_size;
  64. }
  65. extern "C"
  66. JNIEXPORT jint JNICALL Java_com_audio_getFrameSize
  67. (JNIEnv *env, jobject obj) {
  68. if (!codec_open)
  69. return 0;
  70. return (jint)enc_frame_size;
  71. }
  72. extern "C"
  73. JNIEXPORT void JNICALL Java_com_audio_Speex_close
  74. (JNIEnv *env, jobject obj) {
  75. if (--codec_open != 0)
  76. return;
  77. speex_bits_destroy(&ebits);
  78. speex_bits_destroy(&dbits);
  79. speex_decoder_destroy(dec_state);
  80. speex_encoder_destroy(enc_state);
  81. }

8.在Java层创建Speex工具类,内容如下

  1. package com.audio;
  2. class Speex  {
  3. /* quality
  4. * 1 : 4kbps (very noticeable artifacts, usually intelligible)
  5. * 2 : 6kbps (very noticeable artifacts, good intelligibility)
  6. * 4 : 8kbps (noticeable artifacts sometimes)
  7. * 6 : 11kpbs (artifacts usually only noticeable with headphones)
  8. * 8 : 15kbps (artifacts not usually noticeable)
  9. */
  10. private static final int DEFAULT_COMPRESSION = 8;
  11. Speex() {
  12. }
  13. public void init() {
  14. load();
  15. open(DEFAULT_COMPRESSION);
  16. }
  17. private void load() {
  18. try {
  19. System.loadLibrary("speex");
  20. } catch (Throwable e) {
  21. e.printStackTrace();
  22. }
  23. }
  24. public native int open(int compression);
  25. public native int getFrameSize();
  26. public native int decode(byte encoded[], short lin[], int size);
  27. public native int encode(short lin[], int offset, byte encoded[], int size);
  28. public native void close();
  29. }

9.打开cygwin工具,切换到项目目录(我项目是在F:\workspace\Audio),输入$NDK/ndk-build

cygwin工具的安装与配置,可以看这篇文章——使用NDK与环境搭建

会在项目中生成libs目录和libspeex.so文件,这就是Speex类中System.loadLibrary("speex");代码引用的,系统会根据操作系统由"speex"找到对应的动态库libspeex.so,Windows下是.dll文件,linux下是.so文件。

当前,我的项目结构如下图

Speex for Android的更多相关文章

  1. speex编解码在android上实现

    以前在应用中使用到了Speex编解码,近来总结了一下Speex在android上的实现.Speex是一套主要针对语音的开源免费,无专利保护的音频压缩格式.Speex工程着力于通过提供一个可以替代高性能 ...

  2. Android中使用speex将PCM录音格式转Wav格式

    Android中使用speex将PCM录音格式转Wav格式 2013-09-17 17:24:00|  分类: android |  标签:android  speex  wav  |举报|字号 订阅 ...

  3. Android - 基于 Speex 的高度封装语音库,0 耦合使用

    作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...

  4. Android 基于 Speex 的高度封装语音库,0 耦合,没三方jar包

    作者:林冠宏 / 指尖下的幽灵 掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8 博客:http://www.cnblogs.com/linguan ...

  5. Android 开发:开源库Speex支持arm64的动态库文件

    随着处理器制造工艺的不断进步,和Android系统的不断发展,最近出了arm64-v8a的架构,由于项目中用到了speex的第三方语音编解码的动态库,其他架构的处理器暂不用说,一切正常,唯独到arm6 ...

  6. Android 5.0 到 Android 6.0 + 的深坑之一 之 .so 动态库的适配

    (原创:http://www.cnblogs.com/linguanh) 目录: 前序 一,问题描述 二,为何会如此"无情"? 三,目前存在该问题的知名SDK 四,解决方案,1 对 ...

  7. Android源码目录结构详解(转载)

    转自:http://blog.csdn.net/xiangjai/article/details/9012387 在学习Android的过程中,学习写应用还好,一开始不用管太多代码,直接调用函数就可以 ...

  8. android源码的目录结构

    android源码的目录结构 [以下网络摘抄] |-- Makefile ! l/ a5 n% S% @- `0 d# z# a$ P4 V3 o7 R|-- bionic              ...

  9. Android 4.0 源代码结构

    Android源码的第一级目录结构   Android/abi (abi相关代码.ABI:application binary interface,应用程序二进制接口)   Android/bioni ...

随机推荐

  1. 投影纹理映射(Projective Texture Mapping)

    摘抄“GPU Programming And Cg Language Primer 1rd Edition” 中文名“GPU编程与CG语言之阳春白雪下里巴人”  投影纹理映射( Projective ...

  2. Cookie操作类 实现记住用户名和密码的功能

    import java.util.Hashtable;import java.util.Iterator;import java.util.Set;import javax.servlet.http. ...

  3. Tomcat,Jboss,Glassfish等web容器比较选型

    概述 Web容器是一种服务调用的规范,J2EE运用了大量的容器和组件技术来构建分层的企业应用.在J2EE规范中,相应的有WEB Container和EJB Container等. Web容器给处于其中 ...

  4. ASP.NET MVC路由配置

    一.命名参数规范+匿名对象 routes.MapRoute(name: "Default", url: "{controller}/{action}/{id}" ...

  5. 51nod1239 欧拉函数之和

    跟1244差不多. //由于(x+1)没有先mod一下一直WA三个点我... //由于(x+1)没有先mod一下一直WA三个点我... #include<cstdio> #include& ...

  6. C#发送手机验证码

    C#发送手机验证码,平台有很多,我就说说其中的1个平台 测试环境:.net2.0 测试效果:速度还可以,10秒内接收短信 1.去http://www.yuntongxun.com注册,会送8元测试金额 ...

  7. PHP常见框架

    PHP是一种在国内外都比较流行的开源服务器端脚本开发语言.能够适应大中小型项目的开发需求.我们将在这篇文章中向大家介绍几款主流PHP框架及其相关优缺点评比,作为一个参考分享给朋友们. 主要参考的PHP ...

  8. 【同行说技术】swift最全学习资料汇集(一)

    Swift,苹果于2014年WWDC(苹果开发者大会)发布的新开发语言,可与Objective-C*共同运行于Mac OS和iOS平台,用于搭建基于苹果平台的应用程序.2015年12月4日,苹果公司宣 ...

  9. mac下编译optool方法

    参考地址:http://www.mopsled.com/2016/build-optool-osx/ 1.git clone https://github.com/alexzielenski/opto ...

  10. 树莓派 安装 OpenCV 使用CMake 编译工程 最新版2015

    一.安装make,cmake sudo apt-get install make sudo apt-get install cmake 二.下载deb包 去这里下载libopencv_2.4.10.d ...