- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在开发一个 Android 应用程序(显然是用 Java 编写的)并且我最近更新了我的 UDP 阅读器代码。在这两个版本中,我都设置了一些缓冲区并接收了一个 UDP 数据包:
byte[] buf = new byte[10000];
short[] soundData = new short[1000];
DatagramPacket packet = new DatagramPacket (buf, buf.length);
socket.receive (packet);
在初始版本中,我一次一个字节地将数据放回一起(实际上是 16 个 PCM 音频数据):
for (int i = 0; i < count; i++)
soundData[i] = (short) (((buf[k++]&0xff) << 8) + (buf[k++]&0xff));
在更新的版本中,我使用了一些我开始时不知道的很酷的 Java 工具:
bBuffer = ByteBuffer.wrap (buf);
sBuffer = bBuffer.asShortBuffer();
sBuffer.get (soundData, 0, count);
在这两种情况下,“计数”都被正确填充(我检查过)。但是,我的流式音频似乎出现了新问题——也许它的处理速度不够快——这对我来说没有任何意义。显然,缓冲区代码被编译成远远超过三个 JVM 代码语句,但当我开始这个时,第二个版本比第一个版本更快似乎是一个合理的假设。
表面上,我并不是坚持我的代码必须使用 Java NIO 缓冲区,但至少乍一看,这样做确实像是一个 mo'betta'。
有人对快速、简单的 Java UDP 阅读器有任何建议吗?是否有普遍接受的“最佳方法”?
谢谢,
最佳答案
如果不是将数据包读入字节数组(将数据从 native 缓冲区复制到数组中)然后将其包装在新的 ByteBuffer 中(创建新对象)并转换为 ShortBuffer,您的代码会更高效(创建一个新对象)您只设置了一次对象并避免了复制。
您可以通过使用 DatagramChannel.socket() 创建套接字,然后像往常一样连接它并使用 socket.getChannel() 获取 DatagramChannel 对象来完成此操作。该对象将允许您将数据包直接读入现有的 ByteBuffer(您应该使用 ByteBuffer.allocateDirect 创建以获得最大效率)。然后,您只需使用一次 asShortBuffer() 即可将您的数据创建为短裤,并在每次重新填充 ByteBuffer 后从该 ShortBuffer 中读取。
因此代码如下所示:
DatagramSocket socket = DatagramChannel.socket();
// code to connect socket
DatagramChannel channel = socket.getChannel();
ByteBuffer buffer = ByteBuffer.allocateDirect (10000);
// you may want to invoke buffer.order(...) here to tell it what byte order to use
ShortBuffer shortBuf = buffer.asShortBuffer();
// in your receive loop:
buffer.clear();
channel.receive(buffer);
shortBuf.position(0).limit(buffer.position()/2); // may ignore a byte if odd number received
shortBuf.get(soundBuf,0,shortBuf.limit());
您应该会发现这比您以前的代码更有效,因为它避免了数据的完整副本,并且格式转换由手动优化的代码处理,而不是由编译器生成的字节操作处理,后者可能不是最优的。如果您使用平台本地字节顺序,它会更有效率(我相信 Android 在所有可用的平台上使用小端字节顺序,并且您上面的代码似乎是大端字节序,所以这可能是不可能的对你来说),在这种情况下 shortBuf.get() 变成直接内存拷贝。
关于java - ByteBuffer/IntBuffer/ShortBuffer Java 类速度快吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4037851/
谷歌没有找到答案,所以我来问 static float vertices_textures[] = { //vertices //positions
我正在使用 : 读取整数文件 int len = (int)(new File(file).length()); FileInputStream fis = new FileInputStream(f
我想在 Java 中分配一个直接 IntBuffer,比如说 10 亿个元素(64 位系统)。我知道的唯一方法是创建一个直接 ByteBuffer 并将其视为直接 IntBuffer。但是,4*1,0
所以我有一大堆我必须处理的整数(大约 70Mb)。作为阅读过程的一部分,我需要暂时存储它们。我可以将它们分布在多个 IntBuffer 上,或者分配几个大数组。 但是,我找不到任何关于 IntBuff
每当我运行以下代码时,java 在释放 IntBuffer 时都会返回 EXCEPTION_ACCESS_VIOLATION: public int[] size(){ IntBuffer s
我在 IntBuffer 中有图像的 RGB 数据,并希望通过绘画将其显示在 JPanel 上。最有效的方法是什么? 编辑 目前我通过以下代码将数据绘制到 BufferedImage 上,但想知道是否
abstract class IntBuffer 似乎无论如何都无法创建此类的实例,因为它声明为抽象,但同时,还有一个静态工厂方法IntBuffer allocate(intcapacity) 现在您
正如标题所说,它想要创建一个由特定(已经存在的)IntBuffer 支持的 BufferedImage。 到目前为止,我有以下代码: final IntBuffer buf = ...; DataBu
我有以下代码: IntBuffer DrawBuffers = Utils.createIntBuffer(2); int bfs[] = {GL30.GL_COLOR_ATTACHMENT0
在使用堆外缓冲区时,可能需要将它们复制到数组中。假设我们不知道缓冲区是关闭还是在堆上。如何填写执行? IntBuffer b = ... // could be off or on -heap int
在大多数 Android 设备上,如果我用整数而不是 float 进行所有 OpenGL 顶点计算/渲染,我是否应该期待性能提升? 我最近从使用 0:width, 0:height 而不是 -1:1,
我试图获取一组 mipmaplevels 并将其保存到本地缓存文件,以避免每次都重建它们(并且预先生成它们是不切实际的......) 我已经将 mipmaplevels 放入了一组位图中,现在想将它们
我正在开发一个 Android 应用程序(显然是用 Java 编写的)并且我最近更新了我的 UDP 阅读器代码。在这两个版本中,我都设置了一些缓冲区并接收了一个 UDP 数据包: byte[] buf
我知道一个快速的方法,可以将byte/short/int/long数组转换成ByteBuffer,然后得到一个字节数组。例如,要将字节数组转换为短数组,我可以这样做: byte[] bArray =
我有三个代码 fragment ,它们的行为应该相似,也可能不是,我仍在研究 OpenGL ES 如何与 Android 的 Java 绑定(bind)。但是我真的很想知道为什么 fragment B
我希望能够在我的 Android 应用程序中添加一些 native C 代码。我有一个 IntBuffer 用作 OpenGL 的 glColorPointer 方法的参数。这是填充/使用这样的东西:
这里还有其他关于此主题的问题,其中大部分涉及 ByteBuffer 和 asIntBuffer。但是,我还没有看到任何关于如何在转换为 IntBuffer 时防止值被截断的解释。 例子: byte[]
我最近在 Badlogicgames.com 上阅读了一篇关于加速将信息添加到顶点缓冲区(或任何其他 intbuffer)的过程的文章,它确实提高了我的项目速度,但我不太明白 "Noticing th
我上周开始使用 OpenGL 3.3+,在尝试让索引绘图工作时遇到了这个问题。现在,我只是尝试使用 IBO 绘制一个三角形。 索引缓冲区和indexHandle: int[] tIndices = {
我是一名优秀的程序员,十分优秀!