有点背景故事,我正在开发一个带有各种音频编解码器的 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 并且可以快速编写一些伪代码来告诉我从哪里开始转换,我将不胜感激!