dart - 通过IOSink.Add写UInt16List,结果如何?
问题描述
尝试将音频样本写入文件。我有 16 位整数列表
UInt16List _samples = new UInt16List(0);
当样本进入时,我将元素添加到此列表中。然后我可以像这样写入 IOSink:
IOSink _ios = ...
List<int> _toWrite;
_toWrite.addAll(_samples);
_ios.add(_toWrite);
或者
_ios.add(_samples);
List<int>
可以正常工作,尽管有 add take和 not的签名,但类型没有问题UInt16List
。
正如我所读到的,在 Dart 中,“int”类型是 64 位的。上面写的都是一样的吗?他们是否在此文件中生成打包的 16 位整数?
解决方案
一个Uint16List
是一个List<int>
。它是一个整数列表,它将写入截断为 16 位,并且总是读出 16 位整数,但它是一个整数列表。
如果将这些整数复制到普通的 growableList<int>
中,它将包含相同的整数值。
因此,doingios.add(_sample)
与 的作用相同ios.add(_toWrite)
,而且很可能两者都不是你想要的。
的方法需要一个字节列表IOSink
。因此,它将采用整数列表并假设它们是字节。这意味着它将只使用每个整数的低 8 位,如果您尝试将其作为 16 位音频样本播放,这可能听起来很糟糕。add
如果要存储所有 16 位,则需要弄清楚如何将每个 16 位值存储在两个字节中。简单的选择是假设平台字节顺序很好,然后做ios.add(_samples.buffer.asUint8List(_samples.offsetInBytes, _samples.lengthInBytes))
. 这将使 16 位数据视图的字节数增加两倍,然后写入这些字节。
这些字节的字节顺序(高字节在前还是最后)取决于平台,因此如果您想安全起见,可以先将字节转换为固定字节顺序:
if (Endian.host == Endian.little) {
ios.add(
_samples.buffer.asUint8List(_samples.offsetInBytes, _samples.lengthInBytes);
} else {
var byteData = ByteData(_samples.length * 2);
for (int i = 0; i < _samples.length; i++) {
byteData.setUint16(i * 2, _samples[i], Endian.little);
}
var littleEndianData = byteData.buffer.asUint8List(0, _samples.length * 2);
ios.add(littleEndianData);
}
推荐阅读
- django - 在同一域下使用 Nginx 和 Gunicorn 为多个 Django 应用程序提供服务
- javascript - .show() 不能立即工作 - jQuery
- java - 导入的 Java 类无法运行
- swift - Swift UITextField:在自动布局中创建一个动态减小的 UITextField 框架
- jquery - 如何计算两个不同的值而不是同时停止
- typescript - 如何在打字稿中为这个咖喱函数分配正确的类型签名?
- java - 使用 Jsoup 抓取网页
- html - 如何摆脱“订阅我们的时事通讯”部分上方的空白
- reactjs - 如何使用 react-navigation 预加载路由
- php - Symfony4 setter在哪里getter匹配id路由?