协议
DelayWatcher
在 fuchsia.audio/delay.fidl 中定义
观察延迟变化。
WatchDelay
第一个调用会立即返回当前延迟(如果已知)。后续调用会阻塞,直到延迟时间发生变化。最多可以有一个未完成的调用,否则通道可能会关闭。
请求
名称 | 类型 |
---|---|
payload |
DelayWatcherWatchDelayRequest
|
响应
名称 | 类型 |
---|---|
payload |
DelayWatcherWatchDelayResponse
|
GainControl
在 fuchsia.audio/gain.fidl 中定义
实现对音频增益的控制和监控。此接口通常是其他接口的撕裂式接口。
旋钮
此接口公开了两个正交旋钮:
-
gain 旋钮用于控制“相对分贝”的单个值。值为 0 时表示无增益,正值增加增益,负值表示增益。根据上下文,增益可以相对于输入流或某个绝对参照点(例如扬声器的最大音量)应用。
此旋钮未指定最大值或最小值。各个实现可能会限制实现定义的最大值,或将所有低于实现定义的最小值的值视为“静音”,但此行为并非必需。
-
mute 旋钮可控制单个布尔值。当
true
时,GainControl 会被静音,并且有效增益为负无穷大。当该值为false
时,增益由增益旋钮控制。
调度
增益和静音旋钮的更改可以安排在未来的某个时间执行。安排时间戳相对于参考时钟,创建此协议时必须确定该时间。
TODO(https://fxbug.dev/42176154):调度语义可能会发生变化
SetGain
设置增益旋钮。
请求
名称 | 类型 |
---|---|
payload |
GainControlSetGainRequest
|
响应
名称 | 类型 |
---|---|
payload |
GainControl_SetGain_Result
|
SetMute
设置静音旋钮。
请求
名称 | 类型 |
---|---|
payload |
GainControlSetMuteRequest
|
响应
名称 | 类型 |
---|---|
payload |
GainControl_SetMute_Result
|
StreamSink
在 fuchsia.audio/stream_sink.fidl 中定义
用于跨进程音频流传输的数据包接收器,由音频使用方实现,并由音频生产方使用。
结束
表示播放已到结尾。音频渲染程序等使用方会在流结束之前的最后一个数据包已渲染时发出信号,让客户端知道例如何时更改播放器的界面状态,让用户知道内容已播放完毕。此方法的逻辑范围限定为当前细分。此请求后可能会有 SetSegment
请求和(通常)更多数据包。
请求
<EMPTY>
OnWillClose
在使用方关闭之前立即发送,以表明使用方关闭连接的原因。发送此事件后,使用方必须避免发送任何消息,并立即关闭连接。
响应
名称 | 类型 |
---|---|
payload |
StreamSinkOnWillCloseRequest
|
PutPacket
将数据包放入接收器。
请求
名称 | 类型 |
---|---|
payload |
StreamSinkPutPacketRequest
|
StartSegment
开始新的细分。该请求之后和下一个此类请求之前的数据包会被分配给片段。
请求
名称 | 类型 |
---|---|
payload |
StreamSinkStartSegmentRequest
|
WillClose
在提供方关闭之前发送,以指明提供方关闭连接的原因。发送此请求后,提供方必须避免发送任何消息,并立即关闭连接。
请求
名称 | 类型 |
---|---|
payload |
StreamSinkWillCloseRequest
|
结构
UnspecifiedBestEffort
在 fuchsia.audio/stream_sink.fidl 中定义
<EMPTY>
UnspecifiedContinuous
在 fuchsia.audio/stream_sink.fidl 中定义
<EMPTY>
枚举
ChannelConfig 灵活
类型:uint32
在 fuchsia.audio/format.fidl 中定义
渠道的空间分配。
名称 | 值 | 说明 |
---|---|---|
单色 |
1 |
Front.C(CENTER) |
立体声 |
2 |
Front.L(左)| Front.R(右) |
四 |
3 |
Front.L | Front.R | Back.L | Back.R,也称为“四个角” |
SURROUND_3 |
4 |
Front.L | Front.R | Back.C,也称为“LRS” |
SURROUND_4 |
5 |
Front.L | Front.R | Front.C | Back.C,也称为“LRCS” |
SURROUND_5_1 |
6 |
前置 L | 前 R | 前 C | LFE | Side.L | Side.R |
压缩类型 flexible
类型:uint32
在 fuchsia.audio/compression.fidl 中定义
名称 | 值 | 说明 |
---|---|---|
无 |
0 |
|
AAC |
1 |
|
AACLATM |
2 |
|
AMRNB |
3 |
|
AMRWB |
4 |
|
APTX |
5 |
|
FLAC |
6 |
|
GSMMS |
7 |
|
MP3 |
8 |
|
PCMALAW |
9 |
|
《PCMMULAW》 |
10 |
|
SBC |
11 |
|
沃尔比斯 |
12 |
|
OPUS |
13 |
GainError灵活
类型:uint32
在 fuchsia.audio/gain.fidl 中定义
GainControl
返回的错误类型。
名称 | 值 | 说明 |
---|---|---|
MISSING_REQUIRED_FIELD |
1 |
未填写必填字段。 |
UNSUPPORTED_OPTION |
2 |
某个灵活字段包含不受支持的选项。当使用 API 版本 X+1 构建的客户端与使用 API 版本 X 构建的服务器通信时,可能会发生这种情况。 |
SampleType 灵活
类型:uint32
在 fuchsia.audio/format.fidl 中定义
表示各个音频样本的类型。
名称 | 值 | 说明 |
---|---|---|
UINT_8 |
1 |
|
INT_16 |
2 |
|
INT_32 |
3 |
|
FLOAT_32 |
4 |
|
FLOAT_64 |
5 |
表
压缩
在 fuchsia.audio/compression.fidl 中定义
描述应用于流的压缩。
序数 | 字段 | 类型 | 说明 |
---|---|---|---|
1 |
type |
CompressionType
|
应用于数据流的压缩类型。 |
2 |
oob_parameters |
vector<uint8>[32768]
|
描述视频流压缩的不透明“带外”参数。此字段的格式是 |
DelayWatcherWatchDelayRequest
在 fuchsia.audio/delay.fidl 中定义
序数 | 字段 | 类型 | 说明 |
---|
DelayWatcherWatchDelayResponse
在 fuchsia.audio/delay.fidl 中定义
序数 | 字段 | 类型 | 说明 |
---|---|---|---|
1 |
delay |
zx/Duration
|
可选。如果未指定,则延迟时间未知。 |
格式
在 fuchsia.audio/format.fidl 中定义
描述不考虑压缩的情况下用于音频流的格式。如果支持压缩,此类型应与 fuchsia.media2.Compression
结合使用。未压缩的音频流使用 LPCM 编码。
序数 | 字段 | 类型 | 说明 |
---|---|---|---|
1 |
sample_type |
SampleType
|
各个样本的类型。 |
2 |
channel_count |
uint32
|
每帧的样本数量。 |
3 |
frames_per_second |
uint32
|
每秒帧数。 |
4 |
channel_layout |
ChannelLayout
|
每个通道的空间分配。 |
GainControlSetGainRequest
在 fuchsia.audio/gain.fidl 中定义
序数 | 字段 | 类型 | 说明 |
---|---|---|---|
1 |
how |
GainUpdateMethod
|
如何更新增益旋钮。 必选。 |
2 |
when |
fuchsia.media2/RealTime
|
何时应用此更新。 必选。 |
GainControlSetMuteRequest
在 fuchsia.audio/gain.fidl 中定义
序数 | 字段 | 类型 | 说明 |
---|---|---|---|
1 |
muted |
bool
|
静音旋钮的新值。 必选。 |
2 |
when |
fuchsia.media2/RealTime
|
何时应用此更新。 必选。 |
GainControl_SetGain_Response
在 fuchsia.audio/gain.fidl 中定义
序数 | 字段 | 类型 | 说明 |
---|
GainControl_SetMute_Response
在 fuchsia.audio/gain.fidl 中定义
序数 | 字段 | 类型 | 说明 |
---|
包
在 fuchsia.audio/stream_sink.fidl 中定义
描述通过 StreamSink
传送的数据包。
序数 | 字段 | 类型 | 说明 |
---|---|---|---|
1 |
payload |
fuchsia.media2/PayloadRange
|
此数据包的载荷位置。必须填写此字段。 |
2 |
timestamp |
Timestamp
|
指示应提供此数据包的时间的时间戳。省略此字段意味着 |
3 |
capture_timestamp |
zx/Time
|
将此数据包捕获时间作为系统单调时间值。此字段是可选字段,可由捕获器设置,以指明捕获此数据包的时间。 |
4 |
flags |
PacketFlags
|
描述数据包的标志。省略此字段表示所有标志都清除。 |
5 |
front_frames_to_drop |
uint32
|
指示应该从此输入数据包的解码器生成的输出数据包的前面丢弃多少帧。只能为压缩的流提供此值。 如果省略此字段,则不应丢弃任何前帧。 |
6 |
back_frames_to_drop |
uint32
|
指示应从此输入数据包的解码器生成的输出数据包的背面丢弃多少帧。只能为压缩的流提供此值。 如果省略此字段,则不应丢弃任何返回帧。 |
7 |
encryption_properties |
fuchsia.drm/PacketEncryptionProperties
|
说明应用于此数据包的加密。省略此字段意味着数据包未加密。 |
RampFunctionLinearSlope
在 fuchsia.audio/gain.fidl 中定义
增益遵循线性域上的线性斜率。
例如,从增益 -2.3dB 到 -1.6dB 的斜坡属于从 0.1 到 0.5 的线性域内的斜坡。如果超过 4 毫秒,则增益更新顺序为:
- 在 0 毫秒时,增益 = 0.1 = -2.3dB
- 在 1 毫秒时,增益 = 0.2 = -2.0dB
- 在 2 毫秒时,增益 = 0.3 = -1.8dB
- 在 3 毫秒时,增益 = 0.4 = -1.7dB
- 在 4 毫秒时,增益 = 0.5 = -1.6dB
请注意,dB 的变化遵循对数(非线性)曲线。
序数 | 字段 | 类型 | 说明 |
---|
RampedGain
在 fuchsia.audio/gain.fidl 中定义
描述梯度增益命令。应用此命令后,增益会在指定时长内使用指定函数从当前值累积到目标值。
序数 | 字段 | 类型 | 说明 |
---|---|---|---|
1 |
target_gain_db |
float32
|
|
2 |
duration |
zx/Duration
|
|
3 |
function |
RampFunction
|
RingBuffer 资源
在 fuchsia.audio/ring_buffer.fidl 中定义
音频数据的环形缓冲区。
每个环形缓冲区都有一个生产方(向缓冲区写入数据的人员)和一个消耗方(从缓冲区读取数据)。此外,每个环形缓冲区都与一个参考时钟相关联,该时钟用于为缓冲区保留时间。
PCM 数据
PCM 音频的环形缓冲区是进入可能无限的帧序列的窗口。系统会为每一帧分配一个“帧号”,其中无限序列中的第一帧的编号为 0。帧 X
可在环形缓冲区偏移量 (X % RingBufferFrames) * BytesPerFrame
中找到,其中 RingBufferFrames
是环形缓冲区的大小(以帧为单位),BytesPerFrame
是单个帧的大小。
并发协议
每个环形缓冲区都有一个按时间同步的生产方和一个消耗方。根据环形缓冲区的参考时钟,在每个时间点 T 上,我们定义两个函数:
-
SafeWritePos(T)
是提供方可以写入的最低(最早)帧号。生产方可以向此帧或任何编号更高的帧写入数据。 -
SafeReadPos(T)
是使用方能够读取的最高(最新)帧号。使用方可以读取此帧或任何编号较小的帧。
为防止出现冲突,我们将这些字符定义为偏移 1:
SafeWritePos(T) = SafeReadPos(T) + 1
为避免争用,必须有一个提供方,但可以有多个使用方。此外,由于生产方和使用方按时间同步,因此我们需要使用显式栅栏来确保缓存一致性:生产方必须在每次写入后插入适当的栅栏(以刷新 CPU 缓存并防止编译器对存储空间进行重新排序),并且使用方必须在每次读取之前插入适当的栅栏(使 CPU 缓存失效并防止对加载进行重新排序)。
由于缓冲区的大小有限,因此生产方/使用方不能在未来/过去进行无限的写入/读取。我们将 P
帧分配给提供方,并将 C
帧分配给消耗方,其中 P + C <= RingBufferFrames
、P
和 C
均由创建环形缓冲区的用户选择。
决定日期:P
和 C
实际上,生产方/使用方通常会定期批量写入/读取帧。例如,生产方可能会每 Dp
毫秒唤醒一次以写入 DpFrameRate
帧,其中 FrameRate
是 PCM 流的帧速率。如果生产方在时间 T 被唤醒,则最多会用下一个 Dp
时间来写入这些帧。这意味着它可以安全写入的最低帧号是 SafeWritePos(T+Dp)
,相当于 SafeWritePos(T) + Dp
FrameRate
。提供方从该位置开始写入 DpFrameRate
帧。必须在时间 T 将这整个区域(从 SafeWritePos(T)
到 2
DpFrameRate
)分配给提供方。在针对消费者的论点中,我们得出以下限制:
P >= 2
DpFrameRate
C >= 2Dc*FrameRate
RingBufferFrames >= P + C
因此,在实践中,P
和 C
可以派生自生产方和使用方使用的批次大小,其中最大批次大小受环形缓冲区大小的限制。
定义 SafeWritePos
SafeWritePos
(以及隐式 SafeReadPos
)的定义必须在带外提供。
非 PCM 数据
非 PCM 数据的处理方式与 PCM 数据类似,不同之处在于位置以“字节偏移量”而非“帧数”的形式表示,其中无限序列从字节偏移量 0 开始。
序数 | 字段 | 类型 | 说明 |
---|---|---|---|
1 |
buffer |
fuchsia.mem/Buffer
|
实际的环形缓冲区。 必选。 |
2 |
format |
Format
|
对缓冲区中的音频数据进行编码。 必选。 |
3 |
producer_bytes |
uint64
|
分配给提供方的字节数。 对于 PCM 编码,为 非 PCM 编码没有限制,但单个编码可能会施加更严格的要求。 必选。 |
4 |
consumer_bytes |
uint64
|
分配给使用方的字节数。 对于 PCM 编码,应使用 非 PCM 编码没有限制,但单个编码可能会施加更严格的要求。 必选。 |
5 |
reference_clock |
handle<clock>
|
环形缓冲区的参考时钟。 必选。 |
6 |
reference_clock_domain |
uint32
|
域名 可选。如果未指定,则默认为 |
StreamSinkOnWillCloseRequest
在 fuchsia.audio/stream_sink.fidl 中定义
序数 | 字段 | 类型 | 说明 |
---|---|---|---|
1 |
reason |
fuchsia.media2/ConsumerClosedReason
|
连接关闭的原因。 |
StreamSinkPutPacketRequest 资源
在 fuchsia.audio/stream_sink.fidl 中定义
序数 | 字段 | 类型 | 说明 |
---|---|---|---|
1 |
packet |
Packet
|
描述数据包。必须填写此字段。 |
2 |
release_fence |
handle<eventpair>
|
当使用方处理完数据包且与数据包关联的缓冲区区域可以重复使用时,事件对会关闭。数据包可按任意顺序释放。服务可能会复制释放围栏,因此必须使用右侧 |
StreamSinkStartSegmentRequest
在 fuchsia.audio/stream_sink.fidl 中定义
序数 | 字段 | 类型 | 说明 |
---|---|---|---|
1 |
segment_id |
int64
|
标识细分。给定连接的新细分 ID 必须始终严格递增。必须填写此字段。 |
StreamSinkWillCloseRequest
在 fuchsia.audio/stream_sink.fidl 中定义
序数 | 字段 | 类型 | 说明 |
---|---|---|---|
1 |
reason |
fuchsia.media2/ProducerClosedReason
|
连接关闭的原因。 |
联合
ChannelLayout 灵活
在 fuchsia.audio/format.fidl 中定义
表示音频基本流中声道的预期分配。
序数 | 变体 | 类型 | 说明 |
---|---|---|---|
1 |
config |
ChannelConfig
|
该值用于描述每个频道的分配情况。渠道配置必须同意 |
GainControl_SetGain_Result 严格
在 fuchsia.audio/gain.fidl 中定义
序数 | 变体 | 类型 | 说明 |
---|---|---|---|
1 |
response |
GainControl_SetGain_Response
|
|
2 |
err |
GainError
|
GainControl_SetMute_Result 严格
在 fuchsia.audio/gain.fidl 中定义
序数 | 变体 | 类型 | 说明 |
---|---|---|---|
1 |
response |
GainControl_SetMute_Response
|
|
2 |
err |
GainError
|
GainUpdateMethod 灵活
在 fuchsia.audio/gain.fidl 中定义
支持的增益更新类型。
序数 | 变体 | 类型 | 说明 |
---|---|---|---|
1 |
gain_db |
float32
|
立即将增益设置为该值。 |
2 |
ramped |
RampedGain
|
使用斜坡逐渐改变增益。 |
RampFunction 灵活
在 fuchsia.audio/gain.fidl 中定义
支持的升序函数类型。
序数 | 变体 | 类型 | 说明 |
---|---|---|---|
1 |
linear_slope |
RampFunctionLinearSlope
|
时间戳灵活
在 fuchsia.audio/stream_sink.fidl 中定义
指示音频数据包在流时间轴中的位置。
序数 | 变体 | 类型 | 说明 |
---|---|---|---|
1 |
specified |
int64
|
直播时间轴中的特定时间。单位会有所不同,并且在建立连接时会提供。 |
2 |
unspecified_continuous |
UnspecifiedContinuous
|
指示数据包应紧跟在上一个数据包之后呈现(如果已有上一个数据包)。如果没有上一个数据包,此选项相当于 此选项意味着,即使数据包延迟送达,流式传输时间轴也不应该“滑倒”。数据包应在上一个数据包之后立即显示,并且无论数据包的到达时间如何,都将保留最终的时间。 |
3 |
unspecified_best_effort |
UnspecifiedBestEffort
|
表示数据包应在上一个数据包(如果有)之后尽快呈现,否则应该尽快(如果没有)。 此选项意味着,如果数据包到达太晚而无法立即渲染在上一个数据包之后,流式传输时间应该“滑过”。此选项通常在以下情况下使用:未加时间戳的视频流中发生间隙,可能是由于有损的上游来源。 |
BITS
PacketFlags
类型:uint32
在 fuchsia.audio/stream_sink.fidl 中定义
用于描述数据包的标志。
名称 | 值 | 说明 |
---|---|---|
DROP_AFTER_DECODE |
1 | 表示仅提供该数据包,以便对后续数据包进行解释。解码器应丢弃从该数据包生成的解压缩数据包。 |
常量
名称 | 值 | 类型 | 说明 |
---|---|---|---|
MAX_COMPRESSION_PARAMETERS_SIZE |
32768
|
uint64 |
|