音频服务 Audio Service

小技巧

如果图片看不清楚。你可以 在图片上点击鼠标右键 –> 在新标签页中打开图片 ,然后你可以放大、缩小、移动图片。

audio_service.c.

概述

音频服务 Audio Servcie,可能是为 DuerOS Servcie、BlueTooth Service 等 音频子服务 提供一个框架 —— 前者是父类,后者是子类。

但实际上,只有 DuerOS Servcie 是按 Audio Servcie 这个框架实现的;BlueTooth Service 则 与 Audio Servcie 相差甚远。

当前的代码实现(如 DuerOS Service),后者实现时基本上完全覆盖(或继承)前者的方法 —— 除了创建 Create 与特殊 API 要调用音频子服务的API;一般都调用音频服务的 API

类图

../_images/fb5049bd115175bd1e393d80665d1b0f3bff942edda94aff4a689afb90c0371c.svg

我们用类图的形式,描述音频服务 Audio Servcie 的实现(实际上代码是用 C 语言实现的):

  • 结构体 audio_service_impl_t ,是内部私有数据。

    • .service_destroy: 销毁服务的回调函数。
    • .service_start: 启动服务的回调函数。
    • .service_stop: 停止服务的回调函数。
    • .service_connect: 连接服务的回调函数。
    • .service_disconnect: 断开服务的回调函数。
    • .callback_func: 事件处理的回调函数。
    • .user_cb_ctx: callback_func 的参数。
    • .user_data: 存放音频子服务的数据。
  • public method 部分,是 Audio Servcie 的提供的 API 函数。这些函数的实现大部分都很简单:

    • audio_service_create() 的实现略微复杂一点,看这里 API
    • audio_service_destroy() 执行回调函数 .service_destroy
    • audio_service_start() 执行回调函数 .service_start
    • audio_service_stop() 执行回调函数 .service_stop
    • audio_service_connect() 执行回调函数 .service_connect
    • audio_service_disconnect() 执行回调函数 .service_disconnect
    • audio_service_set_callback() 设置回调函数 .callback_func 及 上下文 user_cb_ctx
    • audio_service_callback() 执行回调函数 .callback_func
    • audio_service_set_data() 设置变量 .user_data 。实际上大部分时候都是在 audio_service_create() 里设置 .user_data此函数可能有缺陷
    • audio_service_get_data() 获取变量 .user_data

序列图

../_images/ed7080c79e5336ca9d013a832441fff8bca4fd7238dd994b9633d73f1d9e9cf3.svg

对像说明:

  • xxx_app.c: 某个用户程序
  • xxx_service.c: 某个音频子服务
  • xxx_service_task(): 音频子服务的内部任务
  • audio_service.c:音频服务

流程说明:

  1. xxx_app.c 调用某个音频子服务 xxx_service_create()
  2. xxx_service.c 调用 audio_service_create(), 并会将 .service_destroy.service_start , .service_stop , .service_connect , .service_disconnect , 等回调函数作为参数的字段传入。 同时也会将自已的地址,作为 .user_data 参数字段传入。 若音频子服务需要创建内部任务,则会将内部任务函数作为 .task_func 参数字段传入。
  3. audio_service.c 将上述回调函数和 .user_data 保存下来。若 .task_func 不为空(实际上是 .task_stack > 0),则创建内部任务。
  4. 若有需要,xxx_app.c 调用 audio_service_set_callback() 设置事件回调函数 .callback_func
  5. audio_service_set_data() 此函数有缺陷,且实际上没有调用过。
  1. xxx_app.c 调用 audio_service_connect()
  2. .service_connect 不为空,则会被执行。
  1. xxx_app.c 调用 audio_service_start()
  2. .service_start 不为空,则会被执行。
  1. 内部任务 xxx_service_task() 收到外部事件。
  2. 内部任务 xxx_service_task() 调用 audio_service_callback()
  3. .callback_func 不为空, 则会被执行。
  1. xxx_app.c 调用 audio_service_stop()
  2. .service_stop 不为空,则会被执行。
  1. xxx_app.c 调用 audio_service_discconect()
  2. .service_discconect 不为空,则会被执行。
  1. xxx_app.c 调用 audio_service_destroy(), 销毁某个音频子服务。

  2. .service_destroy 不为空, 则会被 audio_service.c 调用。

  3. xxx_service.c 中止内部任务 xxx_service_task() 。

    DuerOS Service 是 60, 61, 62 流程。

注解

上述流程只表示一般做法。各音频子服务的实现,可能与上述流程并不完全一致。

API

  • audio_service_create()

    ../_images/a7607c9e111db3c8b69266bc45fb0609db2d9384eb2f54d413e51d96731e83b3.svg
  • audio_service_destroy()

  • audio_service_start()

  • audio_service_stop()

  • audio_service_connect()

  • audio_service_disconnect()

  • audio_service_set_callback()

  • audio_service_callback()

  • audio_service_set_data()

  • audio_service_get_data()

与音频子服务的映射

完全映射

同时包括了 回调函数映射API映射

audio service full map

Audio Service 与 各音频子服务的映射

说明:

  • BlueTooth Service 不是基于 Audio Servcie 实现的,与相差甚远,无法列出对应关系
  • 黑色粗体与紫色粗体文字 :用户可调用的 API 函数。
  • 无调用 :提供了API, 但在 ESP_ADF 中没有调用过。
  • 内部API,用户不可调用 :供音频子服务调用的API。
  • 空函数:内部实现为空,或基本为空。
  • .task_func : 这不是 callback, 只是 audio_service_create() 的参数的一个字段。若这个字段非空,则会创建一个音频子服务的内部任务。
  • audio_service_set_data() :没有任何地方调用。实际上也 不能被调用 ,该函数修改的 .user_data 字段,在 audio_service_create() 中已经被赋值了。
  • audio_service_get_data() :为各音频子服务提供的内部 API,用户不应该调用。

回调函数映射

audio service callback map

Audio Service 与 各音频子服务的回调函数映射

API 映射

audio service api map

Audio Service 与 各音频子服务的 API 映射

上表进一步说明了如下原则: 除了创建 Create 与特殊 API 要调用音频子服务的API;一般都调用音频服务的 API