Android PCM转Ulaw编码wav文件

发布于 2024-12-13 17:23:33 字数 1620 浏览 2 评论 0原文

我正在尝试将原始 pcm 数据编码为 uLaw,以节省传输语音数据所需的带宽。

我在 这个页面但是没有文档! :(

构造函数采用输入流和最大 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) {

查看代码后,我怀疑我应该使用提供的函数来计算这个“最大值”:ma​​xAbsPcm。问题是,我真的不明白我要传递给它什么!我正在将原始 pcm 记录到 SD 卡上的文件中,所以我没有一个连续的内存驻留数据数组可以传递给它

  /**
     * 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 数据的标头写入什么值。我如何确定使用 uLaw 编码后的字节数据少了多少?

我听过我在 VLC 媒体中创建的(可能)uLaw 编码文件之一。播放器(我拥有的唯一会尝试读取文件的播放器),它的声音令人讨厌、破碎且有点击声,但仍然可以听出声音

我正在使用类似于我发现的名为 WaveHeader 的类的代码编写我的波形头。发现这里

如果有人对此事有任何想法,我将非常感激听到他们的声音!:)

非常感谢 德克斯特

I'm trying to encode raw pcm data as uLaw to save on the bandwidth required to transmit speech data.

I have come across a class called UlawEncoderInputStream on This page but there is no documentation! :(

The constructor takes an input stream and a max pcm value (whatever that is).

  /**
     * 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) {

After looking through the code, I suspect that i should calculate this "max" value using a supplied function: maxAbsPcm. Problem is, i dont really understand what I'm meant to pass into it! I am recording my raw pcm to a file on the sdcard so I dont have one continuous memory resident array of data to pass to this.

  /**
     * 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) {

Another problem I have using this code is I am unsure what values to write out for the header for uLaw data. How do i determine how much less byte data there is after encoding with uLaw?

I have listened to one of the (potentially) uLaw encoded files that I created in VLC media player (the only player i have that will attempt to read the file) and its sounds nasty, broken and clicky but can still make out the voice.

I am writing my wave header using code similar to a class I found called WaveHeader which can be found Here!

If anyone has any thoughts on this matter I would be most grateful to hear them!:)

Many thanks
Dexter

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

鯉魚旗 2024-12-20 17:23:33

构造函数中的max是PCM数据中的最大幅度。它用于在生成输出之前缩放输入。如果输入声音很大,则需要较高的值,如果输入安静,则需要较低的值。如果您传入 0,编码器将默认使用 8192,这可能就足够了。

另一种方法中的长度是您要从中查找最大幅度的 16 位样本的数量。此类假设输入 PCM 数据始终使用 16 位样本进行编码,这意味着每个样本跨越两个字节:如果您的输入长度为 2000 字节,则您有 1000 个样本。

此类编码器为每个 16 位 PCM 样本生成一个 8 位 µ-Law 样本,因此字节大小减半。

The max in the constructor is the maximum amplitude in the PCM data. It is used to scale the input before generating the output. If the input is very loud you need a higher value, if it's quiet you need a lower one. If you pass in 0 the encoder will use 8192 by default, which may be good enough.

The length in the other method is the number of 16-bit samples from which you want to find the maximum amplitude. This class assumes that the input PCM data is always encoded with 16-bit samples, which means that each sample spans two bytes: if your input is 2000 bytes long you have 1000 samples.

The encoder in this class produces one 8-bit µ-Law sample for every 16-bit PCM sample, so the size in bytes is halved.

爺獨霸怡葒院 2024-12-20 17:23:33

这与您想要做的相反,但我认为这可能对某人有帮助。下面是一个示例方法,它将使用内置 Java 方法将 8 位 uLaw 编码的二进制文件转换为 16 位 WAV 文件。

public static void convertULawFileToWav(String filename) {
    File file = new File(filename);
    if (!file.exists())
        return;
    try {
        long fileSize = file.length();
        int frameSize = 160;
        long numFrames = fileSize / frameSize;
        AudioFormat audioFormat = new AudioFormat(Encoding.ULAW, 8000, 8, 1, frameSize, 50, true);
        AudioInputStream audioInputStream = new AudioInputStream(new FileInputStream(file), audioFormat, numFrames);
        AudioSystem.write(audioInputStream, Type.WAVE, new File("C:\\file.wav"));
    } catch (IOException e) {
        e.printStackTrace();
    }
}

This is the opposite of what you are trying to do, but I thought it could be helpful to someone. Here is an exmple method that will convert an 8-bit uLaw encoded binary file into a 16-bit WAV file using built-in Java methods.

public static void convertULawFileToWav(String filename) {
    File file = new File(filename);
    if (!file.exists())
        return;
    try {
        long fileSize = file.length();
        int frameSize = 160;
        long numFrames = fileSize / frameSize;
        AudioFormat audioFormat = new AudioFormat(Encoding.ULAW, 8000, 8, 1, frameSize, 50, true);
        AudioInputStream audioInputStream = new AudioInputStream(new FileInputStream(file), audioFormat, numFrames);
        AudioSystem.write(audioInputStream, Type.WAVE, new File("C:\\file.wav"));
    } catch (IOException e) {
        e.printStackTrace();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文