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