0

有点背景故事,我正在开发一个带有各种音频编解码器的 Java 软电话,经过一些地方的回答,我了解到,由于速度,最好在本机代码中进行音频解码。

所以我的第一步是用 C 语言实现 PCMU G.711 音频编解码器并将其链接到我的 Java 应用程序中,该应用程序已经具有基于 Java 的 PCMU 实现。

我可以用 C 重写它,但我想要一些标准化,所以我正在提取 ITU-T G.191 软件工具库源代码(http://www.itu.int/rec/T-REC -G.191/en )。这样做的目的是我还将 G.191 STL 用于其他 G 系列编解码器。

这就是他们编写 u-law 编码器的方式:

void            ulaw_compress(lseg, linbuf, logbuf)
  long            lseg;
  short          *linbuf;
  short          *logbuf;
{
  long            n;            /* samples's count */
  short           i;        /* aux.var. */
  short           absno;    /* absolute value of linear (input) sample */
  short           segno;    /* segment (Table 2/G711, column 1) */
  short           low_nibble;   /* low  nibble of log companded sample */
  short           high_nibble;  /* high nibble of log companded sample */

  for (n = 0; n < lseg; n++)
  {
    /* -------------------------------------------------------------------- */
    /* Change from 14 bit left justified to 14 bit right justified */
    /* Compute absolute value; adjust for easy processing */
    /* -------------------------------------------------------------------- */
    absno = linbuf[n] < 0   /* compute 1's complement in case of  */
      ? ((~linbuf[n]) >> 2) + 33/* negative samples */
      : ((linbuf[n]) >> 2) + 33;/* NB: 33 is the difference value */
    /* between the thresholds for */
    /* A-law and u-law. */
    if (absno > (0x1FFF))   /* limitation to "absno" < 8192 */
      absno = (0x1FFF);

    /* Determination of sample's segment */
    i = absno >> 6;
    segno = 1;
    while (i != 0)
    {
      segno++;
      i >>= 1;
    }

    /* Mounting the high-nibble of the log-PCM sample */
    high_nibble = (0x0008) - segno;

    /* Mounting the low-nibble of the log PCM sample */
    low_nibble = (absno >> segno)   /* right shift of mantissa and */
      & (0x000F);       /* masking away leading '1' */
    low_nibble = (0x000F) - low_nibble;

    /* Joining the high-nibble and the low-nibble of the log PCM sample */
    logbuf[n] = (high_nibble << 4) | low_nibble;

    /* Add sign bit */
    if (linbuf[n] >= 0)
      logbuf[n] = logbuf[n] | (0x0080);
  }
}

从 Java 到 JNI,我将传递一个 byte[] PCM 线性数据数组并返回一个 byte[] 编码 PCMU 数据数组。假设我为 ITU-T 的上述方法将 Java byte[] 转换为 jbyte* 到 char* 到 short*,我认为它应该采用 16 位代码字并将其压缩为 8 位代码字。

在上面的例子中,linbuf (in) 和 logbuf (out) 都是短数组。我了解发生的大部分情况,但不应该将 linbuf short* 数组中的每个短(有符号 16 位数字)压缩为 char(有符号 8 位数字)并作为 char* 数组放入 logbuf 中吗?

因此,当我得到返回的编码 short* 数组时,我可以将 logbuf short* 数组转换为 char* 数组,然后在 JNI 中将其作为 Java byte[] 数组返回吗?

如果您熟悉 JNI 并且可以快速编写一些伪代码来告诉我从哪里开始转换,我将不胜感激!

4

0 回答 0