我正在努力创建一个纯Java音频混合库,最好是可以与Android一起使用的库,不完全实用,但绝对是一件有趣的事情。我确信它已经完成了,但仅仅是因为我自己的学习经验,我试图用wav文件做这个,因为通常没有压缩模型可以解决。
鉴于java.io的性质,它定义了许多InputStream类的类。每个实现主要用于从一些底层资源读取数据的操作。您以后对数据执行的操作,转储或将其聚合到您自己的地址空间等中取决于您自己。我希望这是纯粹的Java,例如适用于任何事物(无需JNI),针对低内存配置进行了优化,并且易于扩展。
我理解RIFF格式的本质以及如何汇编PCM样本数据,但我对于管理将文件充气到内存所需的内存的最佳方法感到茫然。使用FileInputStream,基于底层文件系统以及如何调用读取操作,一次只读取大量数据。 FileInputStream没有提供索引文件中的位置的方法,因此无法检索以后混合的流。我的目标是将RIFF文档扩展为Java对象,以允许读取和写入底层块的适当区域。
如果我为整个事物分配空间,例如所有PCM样本数据,即每首普通歌曲50 MB。在典型的智能手机或平板电脑上,这会影响整体性能的可能性有多大?我是否会更好地提出我自己的InputStream类型,它可能会跟踪块在InputStream中的位置?对于文件,这将在获取PCM样本时导致大量阻塞,但仍将减少系统上的总内存占用量。
答案 0 :(得分:1)
我不确定我理解你的所有问题,但我会尽我所能回答。请随意在评论中澄清,我会编辑。
不要将所有文件数据保存在内存中,以用于DAW类型的应用程序,或任何需要播放大文件的文件/视频播放器。这可能在某些设备上有效,具体取决于内存型号,但是你要求麻烦。
相反,根据需要(即按需)读取文件的必需部分。它实际上比这更复杂,因为你不想在音频播放线程中读取文件(你不希望音频播放,这是低延迟,依赖于文件IO,这是高延迟)。要解决这个问题,您可能需要提前缓冲部分文件。 (这取决于您使用的是回调还是阻止模型)
使用FileInputStream工作正常,您只需要自己跟踪文件中的所有内容(这涉及将毫秒或其他任何内容转换为字节并考虑标题的大小[1])。一个稍微好一点的选项是RandomAccessFile,因为它允许你跳转arround。
关于编写音频软件的演讲中的幻灯片可能有所帮助,特别是如果您对回调阻止感到困惑:http://blog.bjornroche.com/2011/11/slides-from-fundamentals-of-audio.html
[1]或更准确地说,知道文件中音频数据的偏移量。