安卓手把手教你学习并实现 安卓耳机口音频转红外发射

news/2024/12/29 12:15:42/

###安卓实现耳机口音频转红外发射

前一段时间因为找工作,完了之后又有两个项目做,一个 BLE4.0 的项目,一个红外控制的项目,因此也好久没写文章了。BLE4.0 的资料网上一抓一大把,就不多说了。

虽说红外很早就开始火了,从最早的遥控器,到红外测距等等,但是网上关于 Android 红外开发的相关资料几乎没有。那就只能硬着头皮自己上。

手机自带红外有 ConsumerIrManager 类,很好用,略过。而我们今天看的是另一种红外发送方式:音频转红外


1、相关知识介绍:

这里写图片描述
这是网上找的格力空调的开机短码,将这些数字理解成一个 TA 自己规定的协议,9000,4500 为帧头,560,1690 代表 1,560,560 代表 0。先不管帧头,剩下的翻译过来就是{1,0,1,0 , 1,0,1,0,0,1,0,1,0,1,0,1},再翻译为16进制,即为0xAA,0x55,这是一个开机命令。

注:红外遥控器原理和NEC协议,这里面有相关的知识,建议先阅读。


采样率 44100:通俗理解就是 在1s内在一条连续的正玄波上面采集 44100 个点。
载波 38KHZ: 即为我们发出的音频信号需要放在 38KHZ 的载波上才能发送出去被红外接收头接收。

音频转红外要做的就是生成 PCM(单/双声道)数据,即为音频数据,按照硬件支持的 NEC 协议,指定采样率,指定载波,使用 Android SDK 中的 audioTrack 类播放这段音频即可

这里写图片描述

注:多媒体基础知识之PCM数据,这里面有 PCM 相关的知识,包括采样率、载波等。

注:硬件自己焊接或者淘宝:android 音频红外发射头,附焊接教程


2、音频调试:

音频调试我使用的电脑软件 cooledit,百度一下就有免费的,再加一根3.5mm 的公对公耳机线。

这里写图片描述这里写图片描述

  • step1:使用遥控精灵搜到你的空调型号。

  • step2:公头线一头插耳机口,一头插电脑音频 mic 口,手机音量调到最大,并在电脑上打开 cooledit 软件。

  • step3:点击 cooledit 的录音键,选择采样率 44100,双声道,16 位。打开遥控精灵,打到你的空调按钮面板,连续点击几次开机键。

  • step4:可以看到 cooledit 软件界面上有一些绿色的声音波形。

这里写图片描述

上面这张图片是我抓的遥控精灵发出的电平信号,可以看到 9ms 的高电平和 4.5ms 的低电平,虽然看到这儿是方波,但是再往后其实 TA 也是正玄波。高电平这儿全部是标准的正玄波组成的,宽度为时间宽度 9ms。

那对于我们来说只要仿造出图中那样的波形,9ms高、4.5ms低…,即可和遥控精灵一样控制我们的空调了。

3、仿造波形:

要仿造一段 20KHZ(因为耳机口只能输出这么大),采样率 44100 , 16 位双声道的 PCM 音频数据,网上还是有点资料可寻的。

目前,我没有找到输出方波的方法,再加上经过对遥控精灵输出波形的观察,也是输出的正玄波,所以就放心的输出 Sin 正玄波吧。

必要了解 ①:

 buffSize = AudioTrack.getMinBufferSize(this.sampleRate,AudioFormat.CHANNEL_OUT_STEREO,AudioFormat.ENCODING_PCM_16BIT) * 4;

AudioTrack:音频播放类。
sampleRate:采样率。
AudioFormat.CHANNEL_OUT_STEREO:双声道输出,即为立体声,但同时也增加了文件大小。
AudioFormat.ENCODING_PCM_16BIT:16位,一个采样点占16位。但同时也增加了文件大小。

必要了解 ②:

y(t) = A * sin (ωt + φ)//ω即为角速度,在一段周期内转过了多少角度。
//T为周期。
//f为频率。
ω = 2π/T = 2πf  y(t) = A * sin (2πft + φ)

正玄波重要函数,

  • A: 振幅,这里为1;
  • f : 频率,这里为 freqOfTone;(即为19000HZ)
  • t: 时间,这里为 (i/sampleRate);(当i为44100时是不是就是1s了)
  • φ: 相位,这里为0;

表示下来就是这样:

  sample[i] = Math.sin(2 * Math.PI  * i * (freqOfTone /sampleRate));

必要了解 ③:

 audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,this.sampleRate, AudioFormat.CHANNEL_OUT_STEREO,AudioFormat.ENCODING_PCM_16BIT, bytes1.length,AudioTrack.MODE_STREAM);

STREAM_MUSIC:播放类型,有 Alerm、Notification 等。
AudioTrack.MODE_STREAM:MODE 有 STREAM 和 STATIC 两种。STREAM 类型意味着音频可以被连续播放,只需要一直往缓冲池写即可。STATIC 通常用于播放游戏音等,适合短小音频。
bytes1.length:一次可播放音频文件的缓冲池大小。

核心代码片段:

       for (final double dVal : sample) {final short val = (short) ((dVal * 32767));final short val_minus = (short) -val;//左声道generatedSnd[idx] = (byte) (val & 0x00ff);generatedSnd[idx+1] = (byte) ((val & 0xff00) >>> 8);//16位双声道  右声道generatedSnd[idx+2] = (byte) (val_minus & 0x00ff);generatedSnd[idx+3] = (byte) ((val_minus & 0xff00) >>> 8);idx=idx+4;}

代码解释:

上面第2行和第3行是将振幅缩放到最大振幅(32767是16位整数的最大值)。

上面第5、6行和第8、9行是填充PCM数据,上面有文章讲了PCM数据格式,在16位wav PCM中,低字节到高字节:
|样本大小| 数据格式| 最小值| 最大值|
|: -------------|:-------------|: -----|: -----|
|8位PCM | int |-128|127|
| 16位PCM | int | -32768 |32767|

填充完毕后,我们就有了完整的正玄波数据。(即高电平正玄波)

        List<Byte> listByte = new ArrayList<>();for (int j = 0; j < patterns.length; j++) {int d=patterns[j];final int points = (int) ((((double) d / 1000000.0) * sampleRate)*4);if (j % 2 == 0) {for (int i = 0; i < points; i++) {listByte.add(generatedSnd[i]);}} else {for (int i = 0; i < points; i++) {listByte.add((byte) 0);}}}

代码解释:
patterns 即为我们要发送的电平数组,9000 , 4500… 那个。

看第4行,9000是 μs,9000/1000000,是将 μs 转化为秒,再乘sampleRate 即为在9000μs 这段时间内占有多少个采样点。

因为9000为高电平,4500为低电平,再接下来又为高电平,然后又是低电平…所以偶数位为高电平 ,所以偶数位上这 points 个点都为高电平,到奇数位了这 points 个点都为低电平,低电平使用0表示即可。然后将所有的点拼装到一起,组成完成的PCM数据,使用 AudioTrack 播放即可。

try {audioTrack.play();} catch (IllegalStateException e) {LogUtil.e( e.getMessage());}audioTrack.write(listByte, 0, listByte.length);

格力空调的控制码网上一搜一大堆,在这里我不会开放源代码,核心代码已经给出了,自己好好理解理解,分析分析,就可以自己写出来了。

这个也是自己花了好长时间才搞定的,所以请尊重他人劳动成果,不做伸手党。当然有不明白的可以在下面留言,欢迎交流,共同学习。


my QQ : 1003077897
my csdn:http://blog.csdn.net/u012534831
my gay:https://github.com/qht1003077897

欢迎交流。


http://www.ppmy.cn/news/211514.html

相关文章

从政府研发投入看各行业的前景

本文转载自公众号“宁南山” 很多小伙伴在微信私聊问博主关于专业前景的一些问题&#xff0c;关于行业前景、大学专业选择、求职方向等一些关于前景的问题都存在些许不确定性&#xff0c;但是总体的方向却是有据可行&#xff0c;这篇文章深入分析了国家最近三年对各个产业的研发…

智能音箱二战:国内Q1出货量5倍增长,BAX上屏、扩类、做家居

智能音箱二战&#xff1a;国内Q1出货量5倍增长&#xff0c;BAX上屏、扩类、做家居 5月20日&#xff0c;市场调研机构Canalys、Strategy Analytics相继公布了2019年Q1智能音箱市场出货情况&#xff0c;二者均特别针对中国智能音箱市场进行了分析和预测&#xff0c;并指出&#x…

业务知识 - 行业笔记

目录 一、抖音的竞争力 二、中国产业升级三座城市 三、七夕蛤蟆&#xff0c;日赚10W 四、2020年上半年中国移动互联网行业分析笔记 五、2020 KOL 生态报告笔记 六、社群买菜大战 七、火山引擎增长 八、2021鹅厂片单 九、微信小程序生态 十、互联网广告模式 十一、反…

员工和供应商,撑起了董明珠的手机梦

点击蓝字 关注我们 出品 / 新浪科技 ID&#xff1a;techsina 作者 / 张俊 “你为什么会想买格力的手机&#xff1f;” 当新浪科技在格力电器专卖店询问购买格力手机时&#xff0c;专卖店店长也显得有些匪夷所思&#xff0c;并表示格力手机只有内部人员在使用&#xff0c;线下门…

机器学习 | 分类问题

目录 一、K近邻算法 二、决策树 1.一些原理介绍 2.决策树案例与实践 三、距离 一、K近邻算法 我们引入accuracy_score&#xff0c;利用score()的方法评估准确性。k近邻算法中的k是一个超参数&#xff0c;需要事先进行定义。 k值得选取经验做法是一般低于训练样本得平方根…

【简单实用框架】【读Excel表】【可移植】

☀️博客主页&#xff1a;CSDN博客主页 &#x1f4a8;本文由 我是小狼君 原创&#xff0c;首发于 CSDN&#x1f4a2; &#x1f525;学习专栏推荐&#xff1a;面试汇总 ❗️游戏框架专栏推荐&#xff1a;游戏实用框架专栏 ⛅️点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd;&…

Linux 之JavaEE定制篇-搭建JavaEE 环境

Linux 之JavaEE 定制篇-搭建JavaEE 环境 注意 本篇软件链接提供 链接&#xff1a;https://pan.baidu.com/s/1y5qqQvWGQ-iz5M2WUrjD3A?pwdv5l2 提取码&#xff1a;v5l2 如果嫌自己下载麻烦或者难找可以考虑 概述 如果需要在Linux 下进行JavaEE 的开发&#xff0c;我们需要…

PHP基于MVC的Web应用

预计更新 第一章&#xff1a;入门 1.1 环境搭建1.2 变量和数据类型1.3 控制流程 第二章&#xff1a;函数 2.1 函数的定义和调用2.2 函数的参数和返回值2.3 匿名函数和闭包 第三章&#xff1a;数组 3.1 数组的基本操作3.2 多维数组3.3 数组函数和排序 第四章&#xff1a;文…