HABIT IS POWER

习惯就是力量

0%

问题描述

前几天解决了Android下的这个问题:MediaRecorder.start failed: -19,后面发现没有彻底解决:
在Nexus S这部“神机”下,如果使用前置摄像头进行录像,还是会出现start failed -19

解决方案

判断是Nexus S,而且使用的是前置摄像头,调用setVideoFrameRate设置为15,解决。
参考文章是这篇:Android cant record video with Front Facing Camera, MediaRecorder start failed: -19

原文是这样的:

So, if I use the QUALITY_LOW profile AND set the frame-rate to 15 or lower, it magically works.

mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
mediaRecorder.setVideoFrameRate(15);
Infact any value, 1 - 15 works. Which seems weird.

不过我用CamcorderProfile.QUALITY_HIGH也是没问题的,关键是mediaRecorder.setVideoFrameRate(15);

贴下我的代码:

// ... 此处省略代码若干

            CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
            
            profile.fileFormat = MediaRecorder.OutputFormat.MPEG_4;
            profile.videoCodec = MediaRecorder.VideoEncoder.H264;
            profile.audioCodec = MediaRecorder.AudioEncoder.AAC;

            // 设置videoFrameRate会导致Nexus S后置摄像头异常退出-19
            // 但不设置,或者设置的不是15以下的值,Nexus S前置摄像头会异常退出-19
            // @linyehui
            if (isModelNexusS())
            {
                if (!cameraManager.isUseBackCamera())
                {
                    profile.videoFrameRate = 15;
                }
            }
            else
            {
                profile.videoFrameRate = Math.min(HJW_VIDEO_FRAME_RATE, profile.videoFrameRate);
            }

            // ... 此处省略代码若干

    private boolean isModelNexusS() {
         final String MODLE_NEXUS_S = "Nexus S";
         Log.i(LOG_TAG, "MODEL: " + android.os.Build.MODEL);
         
         if (android.os.Build.MODEL.equalsIgnoreCase(MODLE_NEXUS_S))
             return true;
         else
             return false;
    }

小结

我目前的做法就是对Nexus S这种神机进行适配:

  • 如果是Nexus S,前置摄像头,设置videoFrameRate 为 15
  • 如果是Nexus S,后置摄像头,就不要设置videoFrameRate
  • 如果不是Nexus S,正常设置videoFrameRate 即可

– End –

问题描述

Android下,使用MediaRecorder进行视频录制,同一段代码在小米2S下代码运行正常,但是在Nexux S下会直接异常退出,log如下:

05-15 16:22:21.631: E/MediaRecorder(9265): start failed: -19
05-15 16:22:21.635: W/System.err(9265): java.lang.RuntimeException: start failed.
05-15 16:22:21.639: W/System.err(9265): at android.media.MediaRecorder.start(Native Method)

问题解决

去掉对VideoFrameRate的设置:

mediaRecorder.setVideoFrameRate(24);
或者
profile.videoFrameRate = Math.min(24);

参考这个Mediarecorder start failed -19

不过我这还遇到了比其他网友更奇怪的问题:

直接使用MediaRecorer的set方法会异常退出,但是get CamcorderProfile后进行相应的修改就能正常运行

下面这两份代码的视频和音频格式参数都是一样的,但是上面这种写法会导致异常退出:

05-15 16:22:21.631: E/MediaRecorder(9265): start failed: -19
05-15 16:22:21.635: W/System.err(9265): java.lang.RuntimeException: start failed.
05-15 16:22:21.639: W/System.err(9265): at android.media.MediaRecorder.start(Native Method)

失败

// 失败 -19 异常退出
CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
//mediaRecorder.setVideoFrameRate(24);
mediaRecorder.setVideoEncodingBitRate(1000 * 1024);
mediaRecorder.setAudioEncodingBitRate(42 * 1024);
mediaRecorder.setAudioSamplingRate(44100);
mediaRecorder.setAudioChannels(2);
mediaRecorder.setVideoSize(640, 480);

成功

// 成功
CamcorderProfile profile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);    		
profile.fileFormat = MediaRecorder.OutputFormat.MPEG_4;
profile.videoCodec = MediaRecorder.VideoEncoder.H264;
profile.audioCodec = MediaRecorder.AudioEncoder.AAC;
            
// 设置videoFrameRate会导致Nexus S下异常退出-19 @linyehui
//profile.videoFrameRate = 24;
profile.videoBitRate = 1000 * 1024;
profile.audioBitRate = 42 * 1024;
profile.audioSampleRate = 44100;
profile.audioChannels = 2;        

mediaRecorder.setProfile(profile);
mediaRecorder.setVideoSize(640, 480);

总结

会导致MediaRecorder start时-19异常退出,主要有两个原因:

  1. mediaRecorder.setVideoSize设置的大小硬件不支持
    解决方案
    先用getSupportedPreviewSizes获取硬件支持的分辨率再使用

  2. mediaRecorder.setVideoFrameRate设置的参数硬件不支持
    解决方案
    暂时没找到好的办法,我的方法是先不用
    (应该有方法可以获取硬件支持的这个信息,然后根据硬件支持的参数来设置就可以了)

参考

Error when Using Camera on Android 4/Nexus s

Android MediaRecorder - “start failed: -19”

Mediarecorder start failed -19

Error处理: android.media.MediaRecorder.start(Native Method) 报错:start failed: -19

– End –

How to Build FFmpeg for Android On Mac

官方文档在这:CompilationGuide/Android

关于Android上的FFmpeg入门,这个Blog不错:roman10 ffmpeg on Android

关于FFmpeg耻辱名单

使用开源代码,第一步一定是确认开源协议所带来的风险,确认后我们才能决定是否使用这一开源代码。

特别是暴风影音和QQ影音让大家知道了FFmpeg的耻辱名单:Hall of Shame,我们更得先研究下FFmpeg的开源协议了。

被加入这个名单的直接原因是这些产品违反了FFmpeg的开源协议,但具体是违反了那个开源协议呢?这就得从FFmpeg的开源协议说起了:

FFmpeg is licensed under the GNU Lesser General Public License (LGPL) version 2.1 or later. However, FFmpeg incorporates several optional parts and optimizations that are covered by the GNU General Public License (GPL) version 2 or later. If those parts get used the GPL applies to all of FFmpeg.

怎么的就违反开源协议了呢?

  1. 虽然FFmpeg使用的开源协议是LGPL,但是他用到的部分组件是GPL开源协议;
  2. LGPL和GPL有着很大的区别,这个可以参考:关于开源授权协议 GPL 和 LGPL
    简单来说,如果商用产品只是把LGPL的开源代码作为第三方库来使用,商用产品本身是不需要开源的,但GPL就不一样,只要你用了开源代码,整个商用产品就必须开源,这就是常说的“传染性”;
  3. 如果使用FFmpeg没有使用到GPL开源协议的部分组件,那么产品只要遵循LGPL就可以了,哪怕你修改了第三方库,也只需要开源修改后的第三方库代码就不算违反LGPL;
  4. 如果使用到了GPL开源协议的部分组件,如x264,那么商用产品就必须遵循GPL,开源商用产品的所有代码;
  5. 综合上面4点,可以知道如果使用了FFmpeg中使用GPL的部分组件,那么你的商用产品就必须开源,否则就是违反了GPL开源协议,要被加入FFmpeg的Hall of Shame。

一不小心就上了耻辱名单,有没有什么防范措施呢?可以参考FFmpeg官方的License Compliance Checklist

在Mac下编译FFmpeg-2.1.4

概要说明

Mac开发环境,按照这篇文章来的指引编译通过:How to Build ffmpeg with NDK r9

直接按照文章的指引编译通过,只有一个步骤需要特别注意,build_android.sh中:

TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64

改成

TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64

./build_android.sh中的路径要从linux-x86_64改成darwin-x86_64,这个我是在编译错误的时候根据提示发现下面这个路径文件找不到,才知道需要改下,修改之后就可以继续调用./build_android.sh编译了

详细编译步骤

虽然都是按照How to Build ffmpeg with NDK r9中的指引来操作的,我还是把操作流程简单记录如下:

  1. 我的开发环境

    Mac OSX 10.9.2
    XCode 5.0.2(带的gcc)
    NDK r9d

  2. 下载并配置好NDK,我之前已经配好了,不清楚的同学自己看Android的官网帮助文档

  3. 下载ffmpeg源码,我下载时的最新稳定版本是2.1.4,解压到NDK目录下的sources目录下

  4. 修改ffmpeg-2.1.4目录下的configure文件
    Open ffmpeg-2.0.1/configure file with a text editor, and locate the following lines.

    SLIBNAME_WITH_MAJOR=’$(SLIBNAME).$(LIBMAJOR)’
    LIB_INSTALL_EXTRA_CMD=’$$(RANLIB) “$(LIBDIR)/$(LIBNAME)”‘
    SLIB_INSTALL_NAME=’$(SLIBNAME_WITH_VERSION)’
    SLIB_INSTALL_LINKS=’$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)’

    This cause ffmpeg shared libraries to be compiled to libavcodec.so. (e.g. libavcodec.so.55), which is not compatible with Android build system. Therefore we’ll need to replace the above lines with the following lines.

SLIBNAME_WITH_MAJOR=’$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)’
LIB_INSTALL_EXTRA_CMD=’$$(RANLIB) “$(LIBDIR)/$(LIBNAME)”‘
SLIB_INSTALL_NAME=’$(SLIBNAME_WITH_MAJOR)’
SLIB_INSTALL_LINKS=’$(SLIBNAME)’

  1. 新建build_android.sh,下面是使用的配置,主要是开头的三个变量要根据自己机器上的情况修改成对应的路径:

    #!/bin/bash
    NDK=/Applications/android-ndk-r9d
    SYSROOT=$NDK/platforms/android-9/arch-arm/
    TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64
    function build_one
    {
    ./configure
    –prefix=$PREFIX
    –enable-shared
    –disable-static
    –disable-doc
    –disable-ffmpeg
    –disable-ffplay
    –disable-ffprobe
    –disable-ffserver
    –disable-avdevice
    –disable-doc
    –disable-symver
    –cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi-
    –target-os=linux
    –arch=arm
    –enable-cross-compile
    –sysroot=$SYSROOT
    –extra-cflags=”-Os -fpic $ADDI_CFLAGS”
    –extra-ldflags=”$ADDI_LDFLAGS”
    $ADDITIONAL_CONFIGURE_FLAG
    make clean
    make
    make install
    }
    CPU=arm
    PREFIX=$(pwd)/android/$CPU
    ADDI_CFLAGS=”-marm”
    build_one

    我一开始没留意TOOLCHAIN的路径,后面发现编译错误,才修改了build_android.sh中TOOLCHAIN的路径定义:

TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64

改成

TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/darwin-x86_64

  1. 保存build_android.sh,并调用执行编译
    我直接把build_android.sh保存在了ffmpeg-2.1.4根目录下,然后执行:

    sudo chmod +x build_android.sh
    ./build_android.sh

  2. 编译通过,在ffmpeg-2.1.4/Android目录下生成了若干.so文件

解压到别的目录下去编译

文章中把ffmpeg的源代码解压到了NDK的sources目录下,并说明了原因:

The reason we built our ffmpeg source code under $NDK/sources folder is that NDK build system will search for directories under this path for external modules automatically.

其实解压到哪里编译都可以,只是放在NDK目录下其他工程使用ffmpeg时的引用路径配置方便一点。

– The End –

最近在看这本书:《习惯的力量

s26262254.jpg

突然想到核心习惯这个问题,我就发了一条推特

最近看《习惯的力量》,开始思考自己的核心习惯是什么?或者说应该培养怎样的核心习惯对自己的帮助最大,目前想到的是 #GTD;
虽然BIO中声称自己是GTD,但是GTD并不是自己目前的核心习惯;
这个问题还得再琢磨琢磨,但千万不能被现在的核心习惯 #三分钟热度 给抛弃了,发推备忘下

提醒自己核心习惯自我反省下

现在:三分钟热度
期望:GTD,高效,坚持

对我影响最大的三本书:

《把时间当作朋友》
《习惯的力量》
《把信带给加西亚》

2014-05-26 补充

场景化是习惯养成的一个重要条件,当生活的重心全部集中于一点的时候,所有的其他习惯貌似都被打乱了?在新的场景下如何养成新的习惯替代老的习惯呢?
习惯养成应该是有方法论的,这个问题我还要持续思考,希望未来有天我可以在这个点上向世界输出点有用的东西。

需求

在Android下录制视频,录制的视频在手机(iOS和Android)上预览、播放正常;
在手机浏览器中播放正常;
在PC上的浏览器和播放器播放正常。


遇到的问题

预览的时候视频需要旋转90°

这个可以解决,设置下摄像头显示的方向就可以了:

// private Camera camera = null;
// 修改摄像头参数就能解决预览视频的旋转90°问题
// 具体是90还是270我这里就不具体说了,网上很多代码
camera.setDisplayOrientation(90);

参考文章:android中Camera setDisplayOrientation使用

视频文件保存的时候需要旋转90°

导致这个问题的原因是使用MediaRecorder录视频保存的文件都是“横版”的,也就是说:如果你是竖着录制视频,录制保存下来的视频本来就是“旋转了90度的”,这个问题怎么解决呢?

一种有缺陷的解决方案

Android 2.3(API Level 9)之后提供了setOrientationHint方法,但这并不是完美的方案,不是所有的播放起都支持这个设置,看下官方文档:setOrientationHint

Sets the orientation hint for output video playback. This method should be called before prepare(). This method will not trigger the source video frame to rotate during video recording, but to add a composition matrix containing the rotation angle in the output video if the output format is OutputFormat.THREE_GPP or OutputFormat.MPEG_4 so that a video player can choose the proper orientation for playback. Note that some video players may choose to ignore the compostion matrix in a video during playback.

关键是这句:

Note that some video players may choose to ignore the compostion matrix in a video during playback.

这就是我为什么说这是一种有缺陷的解决方案,但这个方案足够简单,只用Android SDK就够了,一句代码搞定:

// private MediaRecorder mediaRecorder = null;
// 用VideoView,Safari,QuickTime Player播放视频,视频角度是正确的
// 用Chrome,QQPlayer,MPlayerX播放视频,视频需要旋转90°才正确
mediaRecorder.setOrientationHint(90);

补充说明:

  1. 使用这个方案并不能完美解决问题,在Chrome,QQPlayer,MPlayerX等播放器中,视频都无法按照“预设的角度”被播放,因为这些播放器并不支持setOrientationHint的这种格式设置;
  2. 如果非要使用这个方案,可以在HTML5中使用CSS对video标签进行旋转,但这样会把整个标签,包括控制条都旋转掉,有个猥琐的解决方案是不显示自带的控制条,而是自己实现简单的控制(播放,暂停)

参考文章:Chrome HTML5 Video Flipping Portrait Sideways

可能的完美方案(未验证)

使用FFMpeg或者OpenCV对录制的视频进行旋转

  1. 对录制后的文件进行直接的FFMpeg旋转
  2. 对录制过程中的每一帧进行旋转,最后生成的文件自然也是正确旋转了的

有个有点沾边的参考文章:[https://groups.google.com/forum/#!msg/javacv/J0O6jV8kK9k/cu0iY6fyNWAJ Can I set the orientation of a video when recording with FfmpegFrameRecorder?]

未完待续……

需求描述

  • Windows下的Beyond Compare是个神器,Mac下也有,那么怎么在Mac下使用Beyond Compare呢?
  • 本文所使用的Beyond Compare是官网下载的Beta版本,版本号:Version 4.0 beta (build 17905),安装包我是从官网下载到的。

Mac下命令行使用Beyond Compare

Mac下的Beyond Compare 4,如果要使用命令行,需要从Beyond Compare的菜单上先安装下命令行工具:

Beyond Compare -> Install Command Line Tools …
安装之后你就能得到:
/usr/local/bin/bcomp:
Launches comparison and waits for it to complete.

/usr/local/bin/bcompare:
Launches comparison and returns immediately.
参考:Using BC4 OSX with Version Control Systems

在git中使用Beyond Compare

直接修改.gitconfig就可以了

[diff]
tool = bcomp
[difftool]
prompt = false
[difftool “bcomp”]
trustExitCode = true
cmd = “/usr/local/bin/bcomp” “$LOCAL” “$REMOTE”
[merge]
tool = bcomp
[mergetool]
prompt = false
[mergetool “bcomp”]
trustExitCode = true
cmd = “/usr/local/bin/bcomp” “$LOCAL” “$REMOTE” “$BASE” “$MERGED”

参考:Using BC4 OSX with Version Control Systems

在SourceTree中配置Beyond Compare

1.首先你要确认你已经从Beyond Compare菜单上安装了命令行工具
2.在SourceTree的Preferences中配置

Visual Diff Tool: Other
Diff Command:/usr/local/bin/bcomp
Parameters:$LOCAL $REMOTE
Merge Tool: Other
Merge Command:/usr/local/bin/bcomp
Paramters:$LOCAL $REMOTE $BASE $MERGED

参考:SourceTree configuration


喜欢Beyond Compare的话就支持正版吧 :)

cygwin安装

正确的安装步骤其实很简单:

  1. 下载setup-86_64.exe
  2. 直接从网上下载安装,选择包时,顶部选择“default”不变
  3. 搜索make,勾选make,cmake,emacs-cmake,libjepg
  4. Shells这个二级目录选择“install”
  5. 下一步,开始安装
  6. 安装完成后调用下make命令看下是否已经安装成功(其实最直接的是测试下ndk-build)
  7. 上面提到的这些包一起,下载后的目录是82MB左右,下载了的话肯定是哪里配置错了,不需要那么多东西。

结论很简单,不过我折腾的过程就有点心酸了:

1.坑爹的安装界面交互

下载setup-x86_64.exe,出现包选择的时候,我点击了下“default”,变成了“install”,那时我像,哦~应该是这样吧,然后我就点了下一步,结果我下了差不多半天,下完发现那个有2G多还是3G,什么乱七八糟的都给我下载下来了。

这个方法明显不对,所以我过段把下载完的东西全删了。

2.默认安装

其实打开setup-x86_64.exe后,选择包的那个界面,保持根上的那个“default”不动,就是默认安装,默认安装几分钟就装好了

3.缺什么包选什么包

默认安装后测试下make命令会发现,make都没有安装;
这个时候也好办,提示你缺什么包,你就回到setup-x86_64.exe,在包选择界面filter进行查找,然后勾选,下一步安装。

测试总结之后,我发现把这几个勾选上,基本的ndk-build已经够用了:

make,cmake,emacs-cmake,libjepg,Shells整个二级目录
这些个下载下来的文件也就82MB多。

4.测试安装是否正常

因为ndk-build会用到make,所以安装完cygwin后,桌面快捷方式打开cygwin,然后测试下make命令,如果提示正常,那就是cygwin安装成功了。

5.不要装写没用的,用到什么装什么

cygwin安装成功的话setup-x86_64.exe是不会有什么错误提示的,如果你装的包越多,cygwin对系统的依赖也就越多,反而会出些不兼容的安装错误。

一开始的时候会提示一个bash错误,后面我发现是我装msysgit时带的bash冲突了,我就先吧msysgit卸载了再安装cygwin就好了。
然后重新安装msysgit时记得选择默认的bash选项:Git Bash only

网上还有文章说ndk编译需要依赖devel和editors,要是傻傻勾选了这两个包目录,那就有得你下载了,其实只需要其中的make相关的几个包就够了,不用整个二级目录都“install”。

Shells目录因为比较小,直接勾选上问题不大。

参考文章:

android-ndk-r7b编译环境Cygwin工具搭建及配置

ndk-build解压并配置

  1. 解压ndk压缩包

  2. 配置环境变量,在C:\cygwin64\home\linyehui.bash_profile最后添加两行

    export ANDROID_NDK_HOME=/cygdrive/c/android-ndk-r9c
    export PATH=$ANDROID_NDK_HOME:$PATH

  3. 测试ndk-build
    bash下直接测试下ndk-build命令,提示正常的话就是安装成功了。

小结

网上的教程挺多的,但没有一个写的特别明白,大多都是让你“全部安装”,或者勾选一大堆,用个cygwin要下载1~2G!这就像电脑开机有点慢,有人跟你说重装系统!!

写这个文章也是希望自己做每个事情都能认真的琢磨透,而不是为了达到目的敷衍了事,回头一遇到点小变化,就还得折腾很久,还不如一次搞定,这才是聪明的懒人。

char is different in iOS and Android!
跨平台开发时很容易忽略的非常坑爹的一个区别。


我的需求是实现一个算法,这个算法在iOS和Android下需要保持一致的结果,很自然的我用C++实现了一份跨平台(cross-platform)代码,在两个平台都可以用,但这份代码在iOS和Android下竟然出现了不同的结果,排查了很久后发现了这个不同:

iOS下char is signed,Android下char is unsigned
也就是说,在iOS下这两个定义是等同的:
char cNum = 100;
signed char cNum = 100;

而在Android下这两个定义是等同的:

char cNum = 100;
unsigned char cNum = 100;

当你用char进行运算的时候,signed和unsigned是有正负号差异的,会导致你的结果变得莫名其妙。

这个代码在iOS和Android下代码执行结果是不一样的

char cNum = 0x80;
float fResult = cNum + 80;

解决方案:
声明char类型的变量时,明确写上是signed char还是unsigned char。

发现了问题之后,再反过来找资料的时候发现了这个,不得不感慨:问题总在解决之后突然就变得简单了:
C Compiler differences for iOS and Android development

In your Android C implementation, char is unsigned, and the conversion from -7 in double to char is producing zero. (The behavior of this conversion when the value cannot be represented in the destination type is not defined by the C standard.)

In iOS, char is signed, and the conversion of -7 in double to char produces -7.

PS.
特别要说明下我的开发工具版本:
XCode:5.0.2
官方ADT:22.3.0

使用C++编写跨平台lib,提供给iOS和Android使用,那么NDK是必然要用到的,那么怎么调试NDK呢?
网上的教程挺多的,但是跟着做下来后还是遇到了不少诡异的问题,对于Android新手的我来说还是有点摸不着头脑,解决后在这备忘下。

我遇到的问题

首先我照着这个教程:利用JNI技术在Android中调用、调试C++代码写了个HelloWorld,而且可以“Debug As Android Application”跑起来,但是我想要“Debug As Android Native Application” 的时候就遇到了下面这些问题:

1.提示 Unknown Application ABI:

你会发现Console中有很多行这个提示,但是其实这个提示是可以先忽略掉的,你可以拿个文本编辑器把重复的这些提示过滤掉,这样你就能看到真正的错误提示了;
我看到的是我的第二个问题

2.提示 Android NDK: WARNING: APP_PLATFORM android-19 is larger than android:minSdkVersion 16

解决方案1,这个提示我暂时还没弄明白原理,但是有个最简单的方法来解决:
到AndroidManifest.xml中把这两个字段都改成最大的版本号

android:minSdkVersion=”19”
android:targetSdkVersion=”19”

解决方案2:
到SDK Manager中去下载对应版本的Android SDK Build-tools和SDK Platform

3.模拟器调试

自带的模拟器有多慢大家肯定是知道的,方便调试我使用的是Genymotion,但是后面我发现Genymotion是不支持Debug As Android Native Application的,会提示下面这个,暂时还没找到问题的解决方案:

[2014-03-23 17:28:00 - HelloNDK] Unable to find a compatible ABI
[2014-03-23 17:28:00 - HelloNDK] ABI’s supported by the application: armeabi
[2014-03-23 17:28:00 - HelloNDK] ABI’s supported by the device: x86, armeabi-v7a

4.提示

[2013-06-25 15:25:22 - TestNDK2] gdbserver output:
[2013-06-25 15:25:22 - TestNDK2] run-as: exec failed for lib/gdbserver Error:No such file or directory
[2013-06-25 15:25:22 - TestNDK2] Verify if the application was built with NDK_DEBUG=1

解决方案:

1.确认编译选项是否加了NDK_DEBUG=1

2.已经加了还是不行,终端中输入下adb看看是不是adb命令不可用,是的话,配置下.bash_profile,把adb的路径加进去,加PATH可以参考这个

3.用这个命令把gdb_server push到Android手机或模拟器上

adb push /Applications/android-ndk-r9d/prebuilt/android-arm/gdbserver/gdbserver /data
参考这个:通过gdbserver实现远程调试

5.NDK调试提示错误:

No symbol table is loaded. Use the “file” command.

使用ndk-gdb –start 启动程序第一个activity,但是此时so文件并没有被加载。解决方法:首先打开程序并使用,在保证so文件已经被使用的情况下,调用ndk-gdb命令调试程序进程。
正确流程:1.创建一个模拟器或者使用真机运行想要调试的程序,确保so文件已经被加载。
一个比较简单的方法,在load so库的java文件中添加一个无关紧要的方法,比如:
Java代码 收藏代码
public static void test1(){

Log.i(tag, "test1");  

}

然后在主activity起来的时候,调用一下这个方法就OK了。
参考这篇文章:android NDK开发、编译、调试环境搭建与操作入门

参考:

网上的教程挺多的,我参考了下面这几篇:
Android官网

超简单的NDK单步调试方法

eclipse下ndk调试

【暗黑世界】NDK调试的设置方法

降噪是什么?其实我们一直在享受这个技术给我们带来的方便,只是我们不知道,本文的主题是简单的介绍双MIC降噪,并索引你进行更深入的了解。

双MIC降噪

科技改变生活,iPhone等目前主流手机都在使用这项技术:双MIC降噪

具体是个什么东西呢?来看下通俗解释:

所谓“双mic抗噪技术”是指通过技术处理,将外界的噪音消除而在这之中的“技术处理”,就是内置的2个麦克风,一个稳定保持清晰通话,另一个麦克风物理主动消除噪音。

引申阅读:★双MIC降噪原理及优缺点分析(技术贴)

对于这个技术的解释,这篇文章介绍的很接地气:手机麦克风是如何消除环境噪音的?

这是一篇关于iPhone5的介绍,从中我们也可以发现苹果对这个技术的使用和加强:

相较iPhone 4以及4S的双麦克,iPhone 5拥有更好的降噪能力。除了仍旧在底部的主麦克风外,还拥有听筒位置以及背部摄像头附近的两个降噪麦。传统双麦降噪手机,通过主麦克以及降噪麦克过滤相同环境噪音,已达到强化用户声音的目的。这样一来,无论身处何处,周围的噪音都会有一定程度的削减。

然而iPhone 5的三麦设计,主要是解决在嘈杂环境下听不清听筒声音的问题。这也就是为什么第二个降噪麦,从机身顶部挪到了听筒的位置。通过背部摄像头附近的麦收集环境噪音,以及听筒附近降噪麦计算用户耳朵贴合手机的角度和距离,测算后从听筒发出干扰声波,以达到降低噪音的功效。

实测iPhone 5在安静环境下,通话质量与iPhone 4/4S并无大异,然而在周围噪音繁杂的环境下,听筒音量并无显著提高,但是噪音过滤比较明显,可以清晰收听对方的声音。

引申阅读:体验全面提升 苹果iPhone 5评测

术语解释

Noise reduction

Microphone Arrays : A Tutorial

中文的降噪我没找到专业的术语解释

其他的引申阅读:

★双MIC降噪原理及优缺点分析(技术贴)

求双MIC的DSP降噪算法?

Google学术搜索:双MIC消噪技术

双MIC消噪技术 资料整理

MOTO丽音技术深度解析,帮助大家了解丽音

为什么小米2在安静环境下通话效果差?双MIC降噪原理解析

声学降噪技术

《看不出的创新,听得见的改变——谈 iPhone 5的通话性能提升》

双MIC消噪技术