我正在尝试将原始 pcm 数据编码为 uLaw 以节省传输语音数据所需的带宽。
我在 This page 上遇到了一个名为 UlawEncoderInputStream 的类但是没有文档! :(
构造函数采用输入流和最大 pcm 值(无论是什么)。
/**
* Create an InputStream which takes 16 bit pcm data and produces ulaw data.
* @param in InputStream containing 16 bit pcm data.
* @param max pcm value corresponding to maximum ulaw value.
*/
public UlawEncoderInputStream(InputStream in, int max) {
查看代码后,我怀疑我应该使用提供的函数计算这个“最大值”:maxAbsPcm。问题是,我真的不明白我要传递给它的是什么!我正在将我的原始 pcm 记录到 sdcard 上的一个文件中,因此我没有一个连续的内存常驻数据数组要传递给它。
/**
* Compute the maximum of the absolute value of the pcm samples.
* The return value can be used to set ulaw encoder scaling.
* @param pcmBuf array containing 16 bit pcm data.
* @param offset offset of start of 16 bit pcm data.
* @param length number of pcm samples (not number of input bytes)
* @return maximum abs of pcm data values
*/
public static int maxAbsPcm(byte[] pcmBuf, int offset, int length) {
我在使用这段代码时遇到的另一个问题是我不确定要为 uLaw 数据的 header 写出什么值。如何确定使用 uLaw 编码后字节数据减少了多少?
我听过我在 VLC 媒体播放器(我拥有的唯一会尝试读取该文件的播放器)中创建的(可能)uLaw 编码文件之一,它的声音令人讨厌、 splinter 且有咔嗒声,但仍然可以辨认出来声音。
我正在使用类似于我发现的名为 WaveHeader 的类的代码编写我的 wave header ,可以找到 Here !
如果有人对此事有任何想法,我将不胜感激!:)
非常感谢 德克斯特
最佳答案
构造函数中的max
是PCM数据中的最大幅度。它用于在生成输出之前缩放输入。如果输入非常响亮,您需要一个更高的值,如果它很安静,您需要一个较低的值。如果您传入 0
,编码器将默认使用 8192
,这可能就足够了。
另一种方法中的length
是您要从中找到最大幅度的16 位样本的数量。此类假定输入 PCM 数据始终使用 16 位样本进行编码,这意味着每个样本跨越两个字节:如果您的输入长度为 2000 字节,则您有 1000 个样本。
此类中的编码器为每个 16 位 PCM 样本生成一个 8 位 µ-Law 样本,因此字节大小减半。
关于java - Android PCM转Ulaw编码wav文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7993507/