ITU-T G.711 C源代码,用于Java JNI

时间:2013-08-20 22:20:59

标签: java c audio java-native-interface codec

有点背景故事,我正在开发一个带有各种音频编解码器的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,我将传递一个PCM线性数据的byte []数组,并返回一个编码PCMU数据的byte []数组。假设我将Java byte []转换为jbyte *为char *为short *用于ITU-T的上述方法,我认为它应该采用16位代码字并将其压缩为8位代码字。

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

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

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

0 个答案:

没有答案