我需要根据 RFC 7310 第 5.5 节:
根据 apt-x RTP 布局,用网络字节顺序音频样本填充数据报缓冲区这就是音频样本在我的应用程序内存中的布局:
我在此 cais 中的应用程序缓冲区也被压缩(音频字节布局是小端序):请注意,与 RFC 中需要大端序样本的第 5.5 节末尾的示例相比,我颠倒了下面的 LSB 和 MSB 顺序) - 忽略此示例中的最后一个字节,因为在紧凑形式中,该空白字节将是第二个音频样本的 LSB 等。)
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| LSB | MB | MSB | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
little endian memory layout for 24 bit signed pcm sample.
我需要将我的应用程序缓冲区 memcpy 到数据报缓冲区(从偏移量 12 开始,因为我已经在缓冲区开始处格式化了正确的大端固定 12 字节 RTP 标头)。我应该 std::reverse 我的应用程序缓冲区然后调用 memcpy 还是我需要一些特殊的 endian 库调用来了解 24 位样本?
将音频样本视为英特尔内存中音频的数组 std::uint32_t[样本数]。我可以简单地将每个样本right移动8位以转换为有符号的pcm24 - 但我不知道如何将其插入到目标数据报缓冲区中。
C++ 中的一个简单示例会很棒 - 也许使用
std::endian
或 std::reverse
的 std::byteswap
??
For the example format, the diagram below shows how coded samples
from each channel are packed into a sample block and how sample
blocks 1, 2, and 48 are subsequently packed into the RTP packet.
C:
Channel index: Left (l) = 1, left center (lc) = 2,
center (c) = 3, right (r) = 4, right center (rc) = 5,
and surround (S) = 6.
T:
Sample Block time index: The first sample block is 1; the final
sample is 48.
S(C)(T):
The Tth sample from channel C.
Lindsay & Foerster Standards Track [Page 8]
RFC 7310 apt-X RTP Format July 2014
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| S(1)(1) | S(2)(1) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| S(2)(1) | S(3)(1) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| S(3)(1) | S(4)(1) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| S(5)(1) | S(6)(1) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| S(6)(1) | S(1)(2) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| S(2)(2) | S(3)(2) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| S(4)(2) | S(5)(2) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| S(5)(2) | S(6)(2) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| S(6)(2) | S(1)(3) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| S(6)(47) | S(1)(48) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| S(1)(48) | S(2)(48) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| S(3)(48) | S(4)(48) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| S(4)(48) | S(5)(48) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| S(5)(48) | S(6)(48) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
For the example format, the diagram below indicates the order that
coded bytes are packed into the packet payload in terms of sample
byte significance. The following abbreviations are used.
MSB:
Most Significant Byte of a 24-bit coded sample
MB:
Middle Byte of a 24-bit coded sample
LSB:
Least Significant Byte of a 24-bit coded sample
Lindsay & Foerster Standards Track [Page 9]
RFC 7310 apt-X RTP Format July 2014
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| MSB | MB | LSB | |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
假设问题只是反转三字节整数序列中的字节顺序:当今没有处理器支持三字节整数,因此您必须操作各个字节。类似的东西
unsigned char* src;
unsigned char* dest;
for ( int i = 0; i < sampleCount; ++ i ) {
dest[0] = src[2];
dest[1] = src[1];
dest[2] = src[0];
src += 3;
dest += 3;
}
当然,要对
src
和 dest
进行适当初始化。