Android 开发一个耳返程序(录音,实时播放)

本文目录 点击直达

  • Android 开发一个耳返程序
    • 程序编写
      • 1. 配置 `AndroidManifast.xml`
      • 2.编写耳返管理器
      • 3. 录音权限申请
      • 4. 使用
      • 注意
  • 最后我还有一句话要说
      • 怕相思,已相思,轮到相思没处辞,眉间露一丝

Android 开发一个耳返程序

耳返程序是声音录入设备实时播放的一种程序,理论上实现方案是通过手机录音功能录制音频的同时播放音频,这样就可以简单达到耳返的目的。

分析完毕之后通过了解Android官方API和文档,决定采用AudioRecord/AudioTrack的方式实现简单的PCM编码录制和播放来实现耳返,接下来我们直接进入正题

程序编写

1. 配置 AndroidManifast.xml

录音需要使用录音权限,将以下代码写入AndroidManifast.xml文件中

    <uses-permission android:name="android.permission.RECORD_AUDIO" />

效果如下
配置权限

2.编写耳返管理器

这里我们创建一个类IEMSManager.kt,用来处理音频录制和播放

object IEMSManager {//录音来源使用通话语音,这样可以防止啸叫的同时拥有系统降噪private const val AUDIO_SOURCE = MediaRecorder.AudioSource.VOICE_COMMUNICATION// 采样频率:44100Hz是唯一目前所有Android设备都保证支持的采样频率private const val SAMPLE_RATE = 44100// 音频通道使用双声道输入private const val CHANNEL_IN = AudioFormat.CHANNEL_IN_STEREO// 音频通道使用双声道输出private const val CHANNEL_OUT = AudioFormat.CHANNEL_OUT_STEREO// PCM 16bits每个样本,所有设备保证支持private const val AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT// 录音时音频数据写入的buffer的大小private var recordBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_IN, AUDIO_FORMAT)// 播放时音频数据读取的buffer的大小private val trackBufferSize =AudioTrack.getMinBufferSize(SAMPLE_RATE, CHANNEL_OUT, AUDIO_FORMAT);//构建描述音频属性的对象private val attributes by lazy {AudioAttributes.Builder()//设置音频流的用途属性.setUsage(AudioAttributes.USAGE_ASSISTANT)//设置音频内容属性.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH).build()}//构建描述音频格式的对象private val format = AudioFormat.Builder()//设置采样频率.setSampleRate(SAMPLE_RATE)//设置音频格式的编码方式.setEncoding(AUDIO_FORMAT)//设置通道掩码.setChannelMask(CHANNEL_OUT).build()//控制耳返的状态private var isRunning = false//音频录制器,可以录制音频裸数据PCMprivate var audioRecorder: AudioRecord? = null//音频播放器,支持PCM裸数据渲染private var audioTrack: AudioTrack? = null@RequiresPermission(android.Manifest.permission.RECORD_AUDIO)fun start() {if (isRunning) returnisRunning = true//初始化音频录制器audioRecorder = AudioRecord(AUDIO_SOURCE,SAMPLE_RATE,CHANNEL_IN,AUDIO_FORMAT,recordBufferSize)//初始化音频播放器audioTrack = AudioTrack(attributes,format,trackBufferSize,AudioTrack.MODE_STREAM,AudioManager.AUDIO_SESSION_ID_GENERATE)//开启线程thread {//创建字节数组存储PCM的二进制数据val data = ByteArray(recordBufferSize)//开始录制audioRecorder?.startRecording()//开始播放audioTrack?.play()while (isRunning) {//录音数据是根据录制缓冲区大小试试读取的val byteSize = audioRecorder?.read(data, 0, recordBufferSize) ?: 0//检查到录制数据正常if (byteSize >= AudioRecord.SUCCESS) {//AudioTrack实时渲染刚刚录制的部分audioTrack?.write(data, 0, byteSize)}}//释放资源audioRecorder?.stop()audioRecorder?.release()audioTrack?.stop()audioTrack?.release()audioRecorder = nullaudioTrack = null}}fun stop() {isRunning = false}
}

3. 录音权限申请

在使用耳返功能前,需要检查权限,并且授予RECORD_AUDIO权限,否则会闪退

            if (ActivityCompat.checkSelfPermission(this,Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {requestPermissions(arrayOf(Manifest.permission.RECORD_AUDIO), 0x1)return@setOnClickListener}

4. 使用

代码已经编写完成,只需要调用IEMSManager.kt使用即可听到自己发出的声音

IEMSManager.start()
IEMSManager.stop()

注意

因为使用通话的双通道麦克风实现了降噪,所以使用时可能声音较小,如果没有声音,请将声音调到最大,然后凑近麦克风吼两句"感谢博主,我会一键三连的"

最后我还有一句话要说

怕相思,已相思,轮到相思没处辞,眉间露一丝

明·俞彦《长相思·折花枝》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/698960.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

内容检索(2024.02.23)

随着创作数量的增加&#xff0c;博客文章所涉及的内容越来越庞杂&#xff0c;为了更为方便地阅读&#xff0c;后续更新发布的文章将陆续在此汇总并附上原文链接&#xff0c;感兴趣的小伙伴们可持续关注文章发布动态&#xff01; 本期更新内容&#xff1a; 1. 电磁兼容理论与实…

oracle读写分离多数据源

1、配置数据源 package com.netintech.core.config;import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties; im…

springboot基础(82):分布式定时任务解决方案shedlock

文章目录 前言简介shedlock dbSchedulerLock注解说明 shedlock redis遇到的问题1.配置shedlock不生效 前言 多节点或者多服务器拥有相同的定时任务&#xff0c;这种情况下&#xff0c;不同节点的相同定时任务会被重复执行。如何解决分布式定时任务重复执行问题&#xff1f;此…

fpga_cpu加速

一 cpu流水线执行指令 二 计算机体系结构 注&#xff1a;ARM就是典型的哈佛结构 三 cpu加速 同样采用流水线&#xff0c;哈佛结构的指令效率更高&#xff0c;通过指令预取&#xff0c;提高了流水线的并行度。

【初中生讲机器学习】11. 回归算法中常用的模型评价指标有哪些?here!

创建时间&#xff1a;2024-02-19 最后编辑时间&#xff1a;2024-02-23 作者&#xff1a;Geeker_LStar 你好呀~这里是 Geeker_LStar 的人工智能学习专栏&#xff0c;很高兴遇见你~ 我是 Geeker_LStar&#xff0c;一名初三学生&#xff0c;热爱计算机和数学&#xff0c;我们一起加…

有趣且重要的JS知识合集(19)前端实现图片的本地上传/截取/导出

input[file]太丑了&#xff0c;又不想去改button样式&#xff0c;那就自己实现一个上传按钮的div&#xff0c;然后点击此按钮时&#xff0c;去触发file上传的事件, 以下就是 原生js实现图片前端上传 并且按照最佳宽高比例展示图片&#xff0c;然后可以自定义截取图片&#xff0…

ChatGpt的初步认知(认知搬运工)

前言 ChatGpt火了有一段时间了&#xff0c;对各行各业也有了一定的渗透&#xff0c;当然发展过程中也做了一些安全约束&#xff0c;今天主要是来跟大家分享下关于chatGpt的初步认知。 一、chatGpt是什么&#xff1f; ChatGPT&#xff0c;全称聊天生成预训练转换器&#xff08;英…

X-Rhodamine maleimide ,ROX 马来酰亚胺,实验室常用的荧光染料

您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;X-Rhodamine maleimide &#xff0c;X-Rhodamine mal&#xff0c;ROX-maleimide&#xff0c;ROX 马来酰亚胺 一、基本信息 【产品简介】&#xff1a;ROX, also known as Rhodamine 101, is a product whose active …

使用ffmpeg实现视频片段截取并保持清晰度

1 原始视频信息 通过ffmpeg -i命令查看视频基本信息 ffmpeg -i input.mp4 ffmpeg version 6.1-essentials_build-www.gyan.dev Copyright (c) 2000-2023 the FFmpeg developersbuilt with gcc 12.2.0 (Rev10, Built by MSYS2 project)configuration: --enable-gpl --enable-ve…

算法沉淀——FloodFill 算法(leetcode真题剖析)

算法沉淀——FloodFill 算法 01.图像渲染02.岛屿数量03.岛屿的最大面积04.被围绕的区域05.太平洋大西洋水流问题06.扫雷游戏07.衣橱整理 Flood Fill&#xff08;泛洪填充&#xff09;算法是一种图像处理的基本算法&#xff0c;用于填充连通区域。该算法通常从一个种子点开始&am…

nginx基础模块配置详解

目录 一、Nginx相关配置 1、nginx配置文件 2、nginx模块 二、nginx全局配置 1、关闭版本或修改版本 1.1 关闭版本 1.2 修改版本 2、修改nginx启动的子进程数 3、cpu与worker进程绑定 4、PID路径 5、nginx进程的优先级 6、调试worker进程打开文件的个数 7、nginx服…

Linux命令-chcon命令(修改对象(文件)的安全上下文)

说明 chcon命令 是修改对象&#xff08;文件&#xff09;的安全上下文&#xff0c;比如&#xff1a;用户、角色、类型、安全级别。也就是将每个文件的安全环境变更至指定环境。使用 --reference 选项时&#xff0c;把指定文件的安全环境设置为与参考文件相同。chcon命令位于 /…

【Java程序设计】【C00288】基于Springboot的篮球竞赛预约平台(有论文)

基于Springboot的篮球竞赛预约平台&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的篮球竞赛预约平台 本系统分为前台功能模块、管理员功能模块以及用户功能模块。 前台功能模块&#xff1a;用户进入到平台首页&a…

解释 C++ 中的拷贝构造函数和赋值运算符重载,并指出它们之间的区别。

解释 C 中的拷贝构造函数和赋值运算符重载&#xff0c;并指出它们之间的区别。 拷贝构造函数和赋值运算符重载是 C 中用于实现对象拷贝的两种重要成员函数。它们的作用是将一个对象的值复制给另一个对象&#xff0c;但在使用方式和调用时机上有一些区别。 拷贝构造函数&#…

无刷电机的2种电流采样方式以及优缺点比较

低端电流采样&#xff1a; 在低端采样方式中&#xff0c;电流检测电阻&#xff08;分流电阻&#xff09;通常被放置在逆变器下桥臂MOSFET或IGBT的低端&#xff0c;即靠近电机绕组的地线侧。这种情况下&#xff0c;只有当对应相位的下管导通时&#xff0c;才能通过这个电阻来测量…

C++基础入门(省略版本)(黑马笔记)

C基础入门&#xff08;部分省略&#xff09; 数据类型 整型 数据类型占用空间取值范围short2字节(-215-215-1)int4字节(-231-231-1)longWindows为4字节&#xff0c;Linux为4字节(32位)&#xff0c;8字节(64位)(-231-231-1)long long8字节(-263-263-1) 浮点型 数据类型占用…

【刷题记录】链表的回文结构

本系列博客为个人刷题思路分享&#xff0c;有需要借鉴即可。 1.题目链接&#xff1a; LINK 2.详解思路&#xff1a; 思路&#xff1a;思路&#xff1a;先找到中间节点&#xff0c;然后逆置后半部分链表&#xff0c;一个指针指向链表的头节点&#xff0c;再一个指针指向逆置的头…

深度学习介绍与环境搭建

深度学习介绍与环境搭建 慕课大学人工智能学习笔记&#xff0c;自己学习记录用的。&#xff08;赋上连接&#xff09; https://www.icourse163.org/learn/ZUCC-1206146808?tid1471365447#/learn/content?typedetail&id1256424053&cid1289366515人工智能、机器学习与…

【工具类】阿里域名关联ip(python版)

获取代码如下 # codingutf-8import argparse import json import urllib import logging# 加载 ali 核心 SDK from aliyunsdkcore.client import AcsClient from aliyunsdkalidns.request.v20150109 import (DescribeSubDomainRecordsRequest,AddDomainRecordRequest,UpdateDo…

Java 序列化与反序列化的原理

在Java中&#xff0c;序列化&#xff08;Serialization&#xff09;是将对象转换为字节流的过程&#xff0c;而反序列化&#xff08;Deserialization&#xff09;是将字节流转换回对象的过程。这种机制允许对象在网络上传输或在磁盘上持久化存储。 序列化的原理 标记接口 Ja…