zoukankan      html  css  js  c++  java
  • Android使用AudioTrack发送红外信号

    最近要做一个项目,利用手机的耳机口输出红外信号,从而把手机变成红外遥控器,信号处理的知识基本都还给老师了,刚开始真的挺头疼。找了不少资料研究了一下,总算有点心得,在这里做个备忘。

    一、音频信号输出原理

    音频耳机口输出信号的原理已经有大牛的文章,参考http://blog.csdn.net/xl19862005/article/details/8522869

    再补充一点个人的理解,Android音频输出采样率一般为44.1kHz,AudioTrack源码中限制最大采样率为48kHz,也就是说耳机音频口输出的音频频率应该在20kHz左右,基本就是Android音频输出频率极限了。红外信号载波一般是38kHz,所以单纯的想通过音频信号是达不到要求的,需要借助外部硬件,找了一下,发现某宝上有的卖的,配套的app也有,下来试了一下,效果不错。不过既然是自己开发,需要搞清原理,反编译看了一下,核心代码都是native code,还是走正路,自己研究怎么实现。

     网上找了一些相关资料,Linux平台下有相关的开源项目LIRC(Linux Infrared Remote Control):http://www.lirc.org/,支持各种类型的硬件,可以通过配置文件来支持各种类型的遥控设备,电视、dvd等等,是一个相对成熟的项目,目前google play中有很多红外遥控的应用都是基于此项目开发的。不过我这边只关注耳机口输出红外,LIRC中关于audio耳机口输出原理图(http://www.lirc.org/html/audio.html):

                         

    利用耳机的左右声道,输出19kHz音频,通过左边的电路图,输出38kHz。

    二、实现

    原理搞清楚了,接下来实现,通过AudioTrack输出19kHz的正弦波形即可。这里没有将LIRC整体移植到android上,一来工程量太大,二来我只是用耳机这一种,其他的用不上,主要借鉴其中的音频输出原理。LIRC移植到Android可以参考开源项目irdroid:http://www.irdroid.com/

    核心代码, 输出19kHz正弦,参考国外大牛:http://stackoverflow.com/questions/2413426/playing-an-arbitrary-tone-with-android

    public SignalProcessor(final int frequency) {
        int buffSize = AudioTrack.getMinBufferSize(this.sampleRate,
                    AudioFormat.CHANNEL_CONFIGURATION_STEREO,
                    AudioFormat.ENCODING_PCM_16BIT) * 4;
    
        genSignal = new byte[buffSize];
        genSpace = new byte[buffSize];
    
        for (int j = 0; j < buffSize;) {
            double dVal = Math.sin(2 * Math.PI * ((double)j)/4.0
                            / (((double)sampleRate) / ((double)frequency)));
            final short val = (short) ((dVal * 32767));
            final short val_minus = (short) -val;
            // in 16 bit wav PCM, first byte is the low order byte
            genSpace[j] = 0;
            genSignal[j++] = (byte) (val & 0x00ff);
            genSpace[j] = 0;
            genSignal[j++] = (byte) ((val & 0xff00) >>> 8);
            genSpace[j] = 0;
            genSignal[j++] = (byte) (val_minus & 0x00ff);
            genSpace[j] = 0;
            genSignal[j++] = (byte) ((val_minus & 0xff00) >>> 8);
        }
    
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                            this.sampleRate, AudioFormat.CHANNEL_CONFIGURATION_STEREO,
                            AudioFormat.ENCODING_PCM_16BIT, buffSize,
                            AudioTrack.MODE_STREAM);
        audioTrack.play();
    }
    
    public void play(final ArrayList<Integer> SignalSpaceList) {
            boolean signal = true;
            int count=0;
            for (Integer d : SignalSpaceList) {
                    final int stop = (int) (((double) (d * sampleRate)) / 1000000.0) *4 ;
                    if (signal)
                            for (int i = 0; i < stop;)
                            {
                                    if (stop - i < buffSize)
                                            count= audioTrack.write(genSignal, 0, stop - i);
                                    else
                                            count = audioTrack.write(genSignal, 0, buffSize);
                                    if(count>0)
                                            i+=count;
                            }
                    else
                            for (int i = 0; i < stop;)
                            {
                                    if (stop - i < buffSize)
                                            count= audioTrack.write(genSpace, 0, stop - i);
                                    else
                                            count = audioTrack.write(genSpace, 0, buffSize);
                                    if(count>0)
                                            i+=count;
                            }
                    
                    signal = !signal;
            }
    }

    解释一下:

    public void play(final ArrayList<Integer> SignalSpaceList)

    传入信号与空闲时间的一个list,比如NEC编码中如图:

    HEAD信号时间9ms,空闲时间4.5ms,list中传入9000,4500

    测试耳机口单声道输出波形:

     连接外设之后,输出方波:

  • 相关阅读:
    给多个表的Dimension字段赋初值
    第十七章 性能(一)
    终于看到Inside Microsoft Dynamics Ax4.0了
    Snapin
    添加图片
    PHP功能齐全的发送邮件类,可以发送HTML和附件
    js重写的美化版select控件
    纯CSS的下拉菜单 支持IE6 IE7 Firefox
    BluePage通用分页类
    论坛结构改动,URL重写不影响收录地址的访问代码
  • 原文地址:https://www.cnblogs.com/dennytao/p/5351941.html
Copyright © 2011-2022 走看看