【问题标题】:How to convert char buffer (with pcm audio data) to short buffer如何将 char 缓冲区(带有 pcm 音频数据)转换为短缓冲区
【发布时间】:2012-12-03 09:26:16
【问题描述】:

我有从函数 ffmpeg 获得的 char pAudioBuffer 缓冲区:

int len = avcodec_decode_audio3(av_codec_context,
            (int16_t *) pAudioBuffer, &out_size, &packet);

我知道音频格式是每个样本两个字节,我需要将每两个字节转换为短值,我尝试使用下面的代码 sn-p,但我经常得到零而不是短值:

int shortBufIndex = 0;
for (int i = 0; i < (out_size); i += 2) {
    char b1 = pAudioBuffer[i];
    char b2 = pAudioBuffer[i + 1];
    short sample = atoi(&b1) + atoi(&b2);
    shortBuffer[shortBufIndex] = sample;
    shortBufIndex++;
    LOGI("BUFFER_ITEM='%d'", sample);
}

我做错了什么,如何将 char 缓冲区中的每两个字节转换为短并返回。

更新:

系统的字节顺序是 LITTLE_ENDIAN 我有这样的测试:Endianness of Android NDK

如何将缓冲区中的每两个字节转换为短类型样本并返回。请您提供任何代码示例。

更新

我尝试过访问 short 作为对,这是我的固定代码,但它不起作用,我听不到任何声音:

    int shortBufIndex = 0;
    for (int i = 0; i < (out_size); i += 2) {
        char * byte = (char *) pAudioBuffer[i];
        short * sample = byte;
        shortBuffer[shortBufIndex] = sample;
}

我做错了什么? 我需要这样的转换:byte array to short array and back again in java 但在 c.

【问题讨论】:

  • 为什么不直接将shortBuffer 而不是pAudiBuffer 传递给ffmpeg API?
  • @alk 我怎样才能做到这一点,是否只需将pAudioBuffer 替换为shortBuffer
  • 我尝试使用 shortBuffer 而不是 pAudioBuffer,但是当我将它传递给 AudioTrack 时,我听到了一些噪音,我无法使用这种方法。
  • 这里可能存在字节序问题。如果 ffmpeg 和您的系统使用的字节序不同,您可以使用 ntohs()shortBuffer 的每个元素转换为 avcodec_decode_audio3 的调用填充后,如下所示:size_t size = out_size/2; for (size_t i = 0; i &lt; size; ++i) shortBuffer[i] = ntohs(shortBuffer[i]);
  • @alk 当我尝试使用ntohs 时,我只听到噪音,但是当我使用短而没有ntohs 时,我有时会听到噪音(定期)。好像不行。

标签: c android-ndk ffmpeg short


【解决方案1】:

将 atoi() 与变量地址一起使用是完全错误和不正确的。那是为了将值的 ASCII 表示形式转换为数字。在您的情况下,您实际上并没有“字符”的缓冲区,而是字节值的缓冲区,在 C 的历史下,它通常是用 char 类型而不是最近的东西来实现的,确定的,例如 int8_t

要在字符缓冲区和短缓冲区之间进行转换,首先需要回答关键问题,字符缓冲区的编码是按照系统的本机字节序还是相反。

如果它是本地字节序,那么在诸如 C 之类的语言中,您所要做的就是将指针类型转换为 short,然后以字节对的形式访问数据。

但是,如果顺序相反,您将不得不访问这两个字节并以与通常相反的顺序将它们组合(移位 + 加法)。您可以使用一些宏来执行此操作,但手动操作具有使功能完全明显的优势。

【讨论】:

  • 如何定义系统本机字节序中的缓冲区?
  • 1) 确定系统的本机字节序(通过内置定义或测试),2) 检查您正在使用的库函数的文档,了解它的预期。跨度>
  • and access the data as pairs of bytes - 怎么样?能否提供代码示例。
  • 如果它是本机字节序并对齐,只需转换并分配给短指针并使用它进行访问。但是请记住,每个值的偏移量只添加一个(而不是两个),因为短指针指向字节对(编译器在向短指针添加偏移量时执行隐藏乘以 2,在添加到一个 32 位 int 的指针等)。
【解决方案2】:

呐。你必须写

short sample = b1<<8|b2;

或者,根据您的字节序情况,您必须交换 b1 和 b2

【讨论】:

  • 这样做,b1 需要未签名以避免溢出。
  • @alk - 实际上是 b2 需要无符号,因为符号扩展问题是 or 而不是 left 移位
  • @ChrisStratton:你完全正确。谢谢指正。
【解决方案3】:
short *pshBuf = (short*)pCharBuf;

它有效。我也在我的现场项目中使用相同的。

【讨论】:

    猜你喜欢
    • 2017-07-21
    • 2011-12-03
    • 2021-04-04
    • 1970-01-01
    • 1970-01-01
    • 2016-03-09
    • 2021-01-14
    • 1970-01-01
    • 2022-08-05
    相关资源
    最近更新 更多