如何使用标量手动更改 Android AudioTrack 流的增益级别?

2024-03-19

我正在使用 Android AudioTrack 对象来传输 16 位单声道 PCM 文件。我的代码从 DataInputStream 读取双精度值,将其转换为 8 字节,然后将该 8 字节保存到缓冲区以写入 AudioTrack。这很好用。但现在,我尝试通过将双精度乘以标量(例如 0.5)来调整增益。当我这样做时,它会使我的音频严重失真。我尝试使用浮点数而不是双精度数,得到了相同的结果。有没有更好的方法来改变流的增益?我的最终目标是创建一个简单的回声效果,这就是我这样做的原因。

ByteBuffer bb = ByteBuffer.allocate(8);
while(isPlaying){
        try {
            //fill buffer with bytes from file reader
            for(int i=0; i < BUFFSIZE/8; i++){

                //read double from DataInputStream
                double temp = dis.readDouble();

                //save double to ByteBuffer
                bb.putDouble(0, temp * .5);

                // save 8 bytes to array of bytes
                bb.rewind();
                bb.get(buff,i*8,8);
            }

            //write buffer to track to play
            track.write(buff, 0, BUFFSIZE);

        } catch (IOException e) {
            break; //when eof is reached
        }
    }

如果您使用 Android AudioRecord 和 AudioTrack 类进行录制和播放,请记住,16 位单声道音频样本默认为小端字节序。如果您使用 DataInputStream 类的 readDouble() 方法读取字节,则会不加区别地读取 Big endian 中的 64 位,因此会以错误的顺序读取字节。但请记住,即使 readDouble 会以小端方式读取字节,或者如果您的音频采用大端方式,它也会读取 64 位并将它们视为一个大双值,而实际上每个样本都代表一个带符号短值,其值范围为从 -32768 到 +32767(假设它已签名)。如果出于数字信号处理的目的将其转换为双精度型,最好通过除以 32767.0f 将其标准化为 -1.0 到 +1.0 范围(否则,不必费心将其转换为双精度型)第一名)。当您完成 DSP 的双精度运算后,将其乘以 32767 并将其转换回小端。这是一个快速但肮脏的方法:

try{
    for(int offset=0; offset < buff_size; offset+= 2)  //increment index by two because 16bit mono sample is 2 bytes long
    {

        //reads 2 bytes from stream and stores them in buff at offset. returns number of bytes read.
        if (dis.read(buff,offset, 2) > 0){

            //where buff is an array of bytes
            //                 Low Byte               High Byte    Left Shift
            double sample= ((buff[offset + 0]) | (buff[offset + 1] << 8) );
            /*Explanation: First We take the High Byte and shift it 8 Bytes to the left. In Java, this promotes it to an integer(32 bits).
            * Next we merge the int representing High Byte and the Low Byte byte with a bitwise OR operator
            * 00000000 0000000 10101111 00000000
            *                       OR  10110000 =
            * 00000000 0000000 10101111 10110000 Now our bytes are in the Big Endian order required for primitive types */

            //since 2 bytes is a short which has range -32768 to +32767, we divide by 32768 to normalize to -1.0 to +1.0 range for DSP
            sample = sample /32768.0;

            sample = sample * .5;

            //convert it back to small endian
            int nsample = (int) Math.round(sample * 32767.0);//expands it to the range of -32768 to 32767 range of short, round, & truncate
            buff[offset + 1] = (byte) ((nsample >> 8) & 0xFF); //isolate and extract the high byte
            buff[offset + 0] = (byte) (nsample & 0xFF);        //isolate the low byte with MASK
        }

    }

    track.write(buff, 0, buff_size);
    }catch(Exception e){
        //
    }

来源:http://www.jsresources.org/faq_audio.html#samples_organized http://www.jsresources.org/faq%5faudio.html#samples%5forganized

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用标量手动更改 Android AudioTrack 流的增益级别? 的相关文章

  • 找不到 RecyclerView 类 android.support.v7.recyclerview.R$styleable

    我在我的应用程序上使用 RecyclerView 但在运行时应用程序崩溃并且我的 logcat 读取 java lang RuntimeException Unable to start activity ComponentInfo com
  • Android 中的 XmlPullParser 陷入困境

    经过多个小时的搜索和调试后 我仍然停留在同一个地方 并且 Eclipse 没有帮助我 我试图解析这个 RSS 提要 http fr espnf1 com rss motorsport story feeds 0 xml type 2 这很简
  • 将文本视图包裹在图像视图周围

    晚上好 我正在尝试将文本包裹在图像视图中 就像这里提出的问题一样 Textview 环绕 View https stackoverflow com questions 3626750 textview wrap around view 在风
  • 要在进程中运行 dex,Gradle 守护进程需要更大的堆。目前有 910 MB

    实际上主要错误是 java exe完成非零退出值 1 首先我告诉你安装 studio 后遇到的每个问题 三天前 我刚刚安装了 android studio 并创建了新项目 1 首先它抛出错误 插件太旧 请更新到更新的版本 在谷歌上搜索后我改
  • 检查 Firebase 邀请是否引导至 Play 商店

    当在 Android 上使用 Firebase 邀请并在应用程序启动时访问动态链接时 有没有办法知道用户是通过邀请刚刚安装了该应用程序还是已经安装了该应用程序 非常感谢 Borja 编辑 感谢 Catalin Morosan 的回答 事实证
  • 使用 appcelerator titan 在 android 中后退按钮退出应用程序

    我是钛开发的新手 在本机 android 中 如果我们按下后退按钮 则仅当前活动将被关闭 并且它将返回到上一个活动 但是当我使用 Titanium 在 Android 中按下后退按钮时 它会从应用程序退出 我怎样才能改变这种行为 有两种类型
  • Android Activity 和 Service 关系 - 暂停后、停止后

    假设创建了 Activity A 然后 A 启动了一个 Service S 并将其自身绑定到 S S 通知 A 更新 这将导致 A 的状态发生变化 Android 暂停或停止 A 后 A 和 S 会发生什么 例如 暂停 A 是否会自动解除它
  • 完成特定 Activity 的所有实例

    应用程序中可以有很多活动 最后启动的活动保留在堆栈顶部 按下后它会完成当前活动 我有一系列活动 这是流程 如果我们有 A B C 1 D C 2 活动 C 1 和 C 2 是在导航应用程序时启动的活动 C 的两个不同实例 因此 必需的是清除
  • SDK 管理器中缺少 Google Play 服务

    我想在我的应用程序中使用 Google 地图 我想在 SDK 管理器中安装 Google Play 服务 但是当我转到 SDK 管理器时 我没有看到 Google Play 服务 为什么 我该如何安装这个 我可以独立于 SDK Manage
  • 在InputMethodService 外部调用InputMethodManager.setInputMethod(IBinder token, String id)。哪里可以找到代币?

    我想通过单击按钮在我的 EditText 上显示 Google 语音输入 IME 所以 根据this http android developers blogspot ru 2011 12 add voice typing to your
  • Android 连接有时会被拒绝(并非所有时候)

    我编写了一个 WiFi Direct 代码连接并在它们之间创建了一个连接 然后我创建了一个ServerSocket在第一面和一个Socket在客户端并开始在它们之间发送数据 第一次启动应用程序时它工作成功 但是当我关闭应用程序并再次启动它时
  • Android 如何从我的应用程序使用 SD 卡中的文件路径预览图像

    文件存在于sdcard image jpg我想创建我自己的应用程序 活动 按下按钮时 需要使用内置图像查看器显示存储在 SD 卡中的图像 按图像查看器中的后退按钮后 它应该返回到我正在运行的应用程序 需要一些帮助 您可以为此创建一个具有适当
  • 未调用内容提供商 query() (Android TV)

    据报道 我正在尝试将我的应用程序纳入 Android TV 全局搜索中文档 http developer android com training tv discovery searchable html我必须创建以下内容 内容提供商 可搜
  • 我可以在导航组件中使用多个 NavHostFragment 吗?

    如果您难以理解以下段落 请查看我制作的流程图 我目前正在制作一个带有 3 个顶级目的地的笔记应用程序 顶级目标之一 NotesList 显示用户创建的注释列表 NotesList 有一个过滤器按钮 可显示带有 FilterMenu 目标的底
  • 如何将 currentTimeMillis 转换为可读的日期格式? [复制]

    这个问题在这里已经有答案了 我想用currentTimeMillis两次 这样我就可以计算持续时间 但我也想以用户可读的格式显示时间和日期 我遇到了麻烦currentTimeMillis有利于计算 但我看不到内置函数可以转换为合适的时间或时
  • 当创建 Android Jetpack Compose AndroidView 的参数发生变化时,如何替换它?

    我有一个应用程序 显示封装在其中的几个不同视图AndroidView 在下面重现的简单示例中 这些只是TextView实例 问题是更改文本 在本例中循环显示三个不同的值 似乎不会更新应用程序显示的内容 sealed class AppVie
  • 如何在Webview中保存用户名和密码

    目前 我还在学习Android开发的过程中 所以如果我的这个问题对你来说不太容易理解 请原谅 我创建了一个 Android 应用程序 它使用 RecyclerView 显示一组列表 当用户单击列表中的每个名称时 它会将它们重定向到一组不同的
  • Android Windows:它们何时以及如何创建?

    我已经阅读了标准的 Windows 相关文档并翻阅了 一堆源代码 试图理解 Android 如何以及何时 窗口已创建 我相信我已经拥抱它并愿意 对其进行验证或更正 据我所知 只有两种方法可以获得 Window 对象的句柄 1 Activit
  • c# 模拟 IFormFile CopyToAsync() 方法

    我正在对一个异步函数进行单元测试 该函数将 IFormFile 列表转换为我自己的任意数据库文件类列表 将文件数据转换为字节数组的方法是 internal async Task
  • Android 使用非公历

    我正在创建一个DatePickerDialogFragment用户将在其中选择出生日期 我想确保我可以处理非公历日期 我无法更改在我的设备上使用的日历类型 Android 是否允许用户切换日历类型 如果是的话 步骤是什么 到目前为止我还没有

随机推荐

  • 未捕获的语法错误:意外的标记:

    我正在 MooTools 脚本中运行 AJAX 调用 这在 Firefox 中工作正常 但在 Chrome 中我得到了Uncaught SyntaxError Unexpected token 错误 我无法确定原因 注释掉代码以确定错误代码
  • 传递多个参数来应用 (Python)

    我正在尝试清理 Python 中的一些代码以向量化一组功能 我想知道是否有一种好方法使用 apply 来传递多个参数 考虑以下内容 当前版本 def function 1 x if string in x return 1 else ret
  • Firebase事务api调用当前数据为空

    当我使用transaction 更新一个位置 该位置的数据是返回空值即使该位置有一些数据 I tried transaction 读取数据后在同一位置 它提供该位置的所有数据 我该如何使用transaction 如果情况像上面那样呢 事务以
  • PHP set_time_limit 抛出 500 错误?

    当我使用set time limit如果脚本运行时间超过 360 秒 则会抛出 500 错误 359 没什么 360及以上 错误 我无法访问 php ini 如何修复此错误 脚本运行时间超过 360 秒 就会抛出 500 错误 听起来你在某
  • Kafka消费者启动延迟汇合dotnet

    当启动 confluence dotnet Consumer 时 在调用订阅和后续轮询之后 似乎需要很长时间才能从服务器接收 分区已分配 事件 因此也需要很长时间 大约 10 15 秒 起初我以为存在自动创建主题的开销 但无论消费者的主题
  • 我应该如何设置集成测试以将测试数据库与实体框架结合使用?

    我正在为应用程序编写集成测试 但无法找到有关如何为我的集成套件设置测试数据库的任何最佳实践 我正在使用实体框架代码优先开发 ASP NET MVC4 应用程序 我可以确认我的测试项目中的测试默认与我的计算机上的本地开发数据库进行通信 这并不
  • Fortran 小数和千位分隔符

    有没有办法更改逗号的句点小数分隔符 另外 如何使输出数字具有千位分隔符 这可以是逗号 句号 空格 打开文件时使用参数 DECIMAL COMMA open 100 file logfile status unknown DECIMAL CO
  • 在此上下文中未定义“this”

    我该如何解决以下情况 interface I class A i I class C I A this lt lt this is not defined in this context 简而言之 我想将类实例传递给超类构造函数 在科特林中
  • iOS/iPhone 可达性 - 如何使用 Reachability.m/.h 仅检查互联网丢失/无法可达的情况

    目前我正在使用苹果的reachability m h 的类并且它可以工作 除了它会通知我任何更改 因为我只想在网络无法访问时通知用户 目前 如果我有互联网连接 然后松开网络 它会告诉我 但是 当您重新连接到网络时 它也会告诉我 这是我不想要
  • 如何将LiveData保存到saveStateHandle中?

    如图所示https stackoverflow com a 61166665 3286489 https stackoverflow com a 61166665 3286489 我们可以将LiveData保存在savedStateHand
  • 具有模型属性的 Django 管理 search_fields

    我正在尝试使用模型中的属性作为 django admin 1 2 中的字段 这是我的代码的示例 class Case models Model reference models CharField u Reference max lengt
  • GIT 重命名分支并保留所有提交历史记录

    我有一个关于重命名 git 分支的问题 我创建了一个本地分支dev并将分支推送到远程 我做了很多工作dev分支并定期更新远程分支 现在我想更改分支的名称dev to development 我知道如何重命名 GIT 中的分支 我的问题是 如
  • flex 中 yywrap() 的含义

    该指令在 flex lex 中意味着什么 define yywrap 1 和这个 t 我在下面的代码中找到它 t putchar t 输入 你好世界 输出 你好世界 根据Lex 和 Yacc 页面 http dinosaur compile
  • 如何更改字符串日期的日期格式

    我有像这样的字符串形式的日期 String date 11 12 2018 我想把它改成 2018 12 11 具有相同的变量 因此 我尝试了下面的代码 但它没有给出我期望的输出 String date 11 12 2018 SimpleD
  • 在 C 中,作为参数传递时,“&function”和“function”之间有什么区别?

    例如 include
  • File.Open的默认目录是什么?

    我有这个代码 Stream f File Open data majid FileMode OpenOrCreate FileAccess ReadWrite 文件将在哪里创建 From the File OpenMSDN 文档 http
  • 在哪里可以下载旧版本的 Dart SDK

    我需要获取旧版本的 Dart SDK 来解决问题 具体来说是 Dart SDK 1 5 1 但 dartlang 当前的稳定版本是 1 6 0 是否有一个 URL 可以让我获取所有过去的 Linux 或 MacO 版本的 SDK Updat
  • 这些是 nativecrypto 错误消息吗?

    当我的 Android 手机和服务器之间建立 TLS 连接时 我得到以下信息nativecrypto error messages in logcat 06 30 21 55 06 565 E NativeCrypto 24826 ssl
  • *如果使用 v6 ImageList 控件,.bmp 会丢失透明背景

    抱歉 我的英语不是很好 我需要在我的 D7 应用程序中使用半透明位图图片 所以 我应该使用 XPManifest 和 ImageList version6 而不是 5 8 标准版 但在这种情况下 我遇到了一个问题 当我从流中加载图像时 所有
  • 如何使用标量手动更改 Android AudioTrack 流的增益级别?

    我正在使用 Android AudioTrack 对象来传输 16 位单声道 PCM 文件 我的代码从 DataInputStream 读取双精度值 将其转换为 8 字节 然后将该 8 字节保存到缓冲区以写入 AudioTrack 这很好用