luat_audio.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. /*
  2. * Copyright (c) 2022 OpenLuat & AirM2M
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. * this software and associated documentation files (the "Software"), to deal in
  6. * the Software without restriction, including without limitation the rights to
  7. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  8. * the Software, and to permit persons to whom the Software is furnished to do so,
  9. * subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in all
  12. * copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  16. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  17. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  18. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  19. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  20. */
  21. #ifndef __LUAT_AUDIO_H__
  22. #define __LUAT_AUDIO_H__
  23. #include "luat_base.h"
  24. #include "luat_rtos.h"
  25. #include"luat_audio_codec.h"
  26. #include"luat_multimedia_codec.h"
  27. #ifndef __BSP_COMMON_H__
  28. #include "c_common.h"
  29. #endif
  30. typedef struct luat_audio_conf {
  31. luat_multimedia_codec_t multimedia_codec;
  32. uint64_t last_wakeup_time_ms;
  33. luat_audio_codec_conf_t codec_conf;
  34. void *hardware_data;
  35. luat_rtos_timer_t pa_delay_timer;
  36. uint32_t after_sleep_ready_time; //
  37. uint16_t pa_delay_time;
  38. uint16_t power_off_delay_time; // 电源关闭后延时时间
  39. uint16_t soft_vol;
  40. uint16_t speech_downlink_type;
  41. uint16_t speech_uplink_type;
  42. uint16_t i2s_rx_cb_save;
  43. uint16_t last_vol;
  44. uint16_t last_mic_vol;
  45. uint8_t bus_type;
  46. uint8_t raw_mode;
  47. uint8_t debug_on_off;
  48. uint8_t sleep_mode;
  49. uint8_t wakeup_ready;
  50. uint8_t pa_on_enable;
  51. uint8_t record_mode;
  52. uint8_t pa_pin; // pa pin
  53. uint8_t pa_on_level; // pa 使能电平
  54. uint8_t power_pin; // 电源控制
  55. uint8_t power_on_level; // 电源使能电平
  56. uint8_t pa_is_control_enable;
  57. uint8_t voltage;
  58. } luat_audio_conf_t;
  59. typedef enum{
  60. LUAT_AUDIO_PM_RESUME = 0, /* 工作模式 */
  61. LUAT_AUDIO_PM_STANDBY, /* 待机模式 */
  62. LUAT_AUDIO_PM_SHUTDOWN, /* 关断模式 */
  63. LUAT_AUDIO_PM_POWER_OFF, /* 完全断电模式 */
  64. }luat_audio_pm_mode_t;
  65. typedef enum{
  66. LUAT_AUDIO_VOLTAGE_3300 = 0, /* 工作在3.3V */
  67. LUAT_AUDIO_VOLTAGE_1800, /* 工作在1.8V */
  68. }luat_audio_voltage_t;
  69. typedef enum{
  70. LUAT_RECORD_MONO = 1, /* 工作在3.3V */
  71. LUAT_RECORD_STEREO = 2, /* 工作在1.8V */
  72. }luat_record_channel_t;
  73. typedef enum{
  74. LUAT_AUDIO_BUS_DAC=0,
  75. LUAT_AUDIO_BUS_I2S,
  76. LUAT_AUDIO_BUS_SOFT_DAC
  77. }luat_audio_bus_type_t;
  78. #ifdef LUAT_USE_RECORD
  79. #include "luat_i2s.h"
  80. typedef struct{
  81. // luat_rtos_task_handle task_handle;
  82. FILE* fd;
  83. uint32_t record_time;
  84. uint32_t record_time_tmp;
  85. void* encoder_handler;
  86. luat_zbuff_t * record_buffer[2];
  87. uint32_t bak_sample_rate; // i2s采样率
  88. uint32_t bak_cb_rx_len; // 接收触发回调数据长度
  89. int (*bak_luat_i2s_event_callback)(uint8_t id ,luat_i2s_event_t event, uint8_t *rx_data, uint32_t rx_len, void *param); // i2s回调函数
  90. uint32_t type; // LUAT_MULTIMEDIA_DATA_TYPE 或者具体采样率
  91. uint32_t record_callback_level;
  92. uint8_t bak_is_full_duplex; // 是否全双工
  93. uint8_t record_buffer_index;
  94. uint8_t multimedia_id;
  95. uint8_t quailty;
  96. uint8_t is_run;
  97. luat_record_channel_t channelCnt;
  98. }luat_record_ctrl_t;
  99. #endif
  100. /**
  101. * @brief 设置音频硬件输出类型,后续初始化都会根据类型做不同处理,所以要首先使用此函数设置类型!!!
  102. *
  103. * @param bus_type 见MULTIMEDIA_AUDIO_BUS,目前只有0=DAC 1=I2S 2=SOFT_DAC
  104. */
  105. int luat_audio_set_bus_type(uint8_t multimedia_id,uint8_t bus_type);
  106. //此函数可获取multimedia_id对应的audio结构体,用于动态修改,如果有无法直接设置的函数可自行通过此方法修改结构体,一般不需要使用此函数
  107. luat_audio_conf_t *luat_audio_get_config(uint8_t multimedia_id);
  108. /**
  109. * @brief audio和codec绑定
  110. *
  111. * @param multimedia_id 多媒体通道,目前只有0
  112. * @param codec_conf codec信息
  113. * @return int =0成功,其他失败
  114. */
  115. int luat_audio_setup_codec(uint8_t multimedia_id, const luat_audio_codec_conf_t *codec_conf);
  116. /**
  117. * @brief 初始化audio
  118. *
  119. * @param multimedia_id 多媒体通道,目前只有0
  120. * @param init_vol 默认硬件音量
  121. * @param init_mic_vol 默认MIC音量
  122. * @return int =0成功,其他失败
  123. */
  124. int luat_audio_init(uint8_t multimedia_id, uint16_t init_vol, uint16_t init_mic_vol);
  125. /**
  126. * @brief audio休眠控制,注意,pm各个模式下功耗由具体audio硬件决定
  127. *
  128. * @param multimedia_id 多媒体通道
  129. * @param mode
  130. * @return int =0成功,其他失败
  131. */
  132. int luat_audio_pm_request(uint8_t multimedia_id,luat_audio_pm_mode_t mode);
  133. /**
  134. * @brief 播放空白音,一般不需要主动调用
  135. *
  136. * @param multimedia_id 多媒体通道
  137. * @param on_off 1打开空白,0关闭
  138. * @return int =0成功,其他失败
  139. */
  140. int luat_audio_play_blank(uint8_t multimedia_id, uint8_t on_off);
  141. #ifdef __LUATOS__
  142. /**
  143. * @brief 播放指定数量的文件或者ROM数组(文件数据直接写成数组形式)
  144. *
  145. * @param multimedia_id 多媒体通道,目前只有0
  146. * @param info 文件信息,文件路径信息
  147. * @param files_num 文件数量
  148. * @return int =0成功,其他失败
  149. */
  150. int luat_audio_play_multi_files(uint8_t multimedia_id, uData_t *info, uint32_t files_num, uint8_t error_stop);
  151. #endif
  152. /**
  153. * @brief 播放指定的文件或
  154. *
  155. * @param multimedia_id 多媒体通道,目前只有0
  156. * @param path 文件路径
  157. * @return int =0成功,其他失败
  158. */
  159. int luat_audio_play_file(uint8_t multimedia_id, const char *path);
  160. /**
  161. * @brief 是否播放完全部数据
  162. *
  163. * @param multimedia_id multimedia_id 多媒体通道,目前只有0
  164. * @return uint8_t =1是,=0没有
  165. */
  166. uint8_t luat_audio_is_finish(uint8_t multimedia_id);
  167. /**
  168. * @brief 强制停止播放文件,但是不会停止已经输出到底层驱动的数据播放
  169. *
  170. * @param multimedia_id multimedia_id 多媒体通道,目前只有0
  171. * @return int =0成功,其他失败
  172. */
  173. int luat_audio_play_stop(uint8_t multimedia_id);
  174. /**
  175. * @brief 获取上一次播放结果,在MULTIMEDIA_CB_AUDIO_DONE回调时调用最佳
  176. *
  177. * @param multimedia_id multimedia_id 多媒体通道,目前只有0
  178. * @return int =0完整的播放完成,<0被用户停止了,>0 TTS失败,或者第几个音频文件解码失败(用户在play_info未设置了解码失败后继续,文件位置+1)
  179. */
  180. int luat_audio_play_get_last_error(uint8_t multimedia_id);
  181. /**
  182. * @brief 立刻初始化播放未编码的原始音频数据流
  183. *
  184. * @param multimedia_id multimedia_id 多媒体通道,目前只有0
  185. * @param audio_format 音频数据格式,目前只支持PCM,即需要手动解码
  186. * @param num_channels 声道数,目前只能1或2
  187. * @param sample_rate 采样率,注意只有8K,16K,32K,48K,96K,22.05K,44.1K这些能被支持
  188. * @param bits_per_sample 量化bit,只能是16
  189. * @param is_signed 量化数据是否带符号,只能是1
  190. * @return int =0成功,其他失败
  191. */
  192. int luat_audio_start_raw(uint8_t multimedia_id, uint8_t audio_format, uint8_t num_channels, uint32_t sample_rate, uint8_t bits_per_sample, uint8_t is_signed);
  193. /**
  194. * @brief 向底层驱动传入一段原始音频数据
  195. *
  196. * @param multimedia_id multimedia_id 多媒体通道,目前只有0
  197. * @param data 原始音频数据
  198. * @param len 原始音频数据长度
  199. * @return int =0成功,其他失败
  200. */
  201. int luat_audio_write_raw(uint8_t multimedia_id, uint8_t *data, uint32_t len);
  202. /**
  203. * @brief 强制停止所有播放,同时底层驱动也会停止输出,不要用于播放文件的结束
  204. *
  205. * @param multimedia_id multimedia_id 多媒体通道,目前只有0
  206. * @return int =0成功,其他失败
  207. */
  208. int luat_audio_stop_raw(uint8_t multimedia_id);
  209. /**
  210. * @brief 暂停/恢复播放
  211. *
  212. * @param multimedia_id multimedia_id 多媒体通道,目前只有0
  213. * @param is_pause 0恢复,其他暂停
  214. * @return int =0成功,其他失败
  215. */
  216. int luat_audio_pause_raw(uint8_t multimedia_id, uint8_t is_pause);
  217. /**
  218. * @brief 编码并播放一段文字
  219. *
  220. * @param multimedia_id multimedia_id 多媒体通道,目前只有0
  221. * @param text 文字数据
  222. * @param text_bytes 文字数据长度
  223. * @return int =0成功,其他失败
  224. */
  225. int luat_audio_play_tts_text(uint8_t multimedia_id, void *text, uint32_t text_bytes);
  226. /**
  227. * @brief 在收到MULTIMEDIA_CB_TTS_INIT回调时,可以设置TTS参数,等同于ivTTS_SetParam
  228. *
  229. * @param multimedia_id multimedia_id 多媒体通道,目前只有0
  230. * @param param_id 见ivTTS_PARAM_XXX
  231. * @param param_value param_id对应的value
  232. * @return int =0成功,其他失败
  233. */
  234. int luat_audio_play_tts_set_param(uint8_t multimedia_id, uint32_t param_id, uint32_t param_value);
  235. /**
  236. * @brief pa引脚配置
  237. *
  238. * @param multimedia_id multimedia_id 多媒体通道
  239. * @param pin pa pin
  240. * @param level pa使能电平
  241. * @param dummy_time_len
  242. * @param pa_delay_time
  243. */
  244. void luat_audio_config_pa(uint8_t multimedia_id, uint32_t pin, int level, uint32_t dummy_time_len, uint32_t pa_delay_time);
  245. /**
  246. * @brief power引脚配置
  247. *
  248. * @param multimedia_id 多媒体通道
  249. * @param pin power pin
  250. * @param level 使能电平
  251. * @param dac_off_delay_time
  252. */
  253. void luat_audio_config_dac(uint8_t multimedia_id, int pin, int level, uint32_t dac_off_delay_time);
  254. /**
  255. * @brief 音量控制
  256. *
  257. * @param multimedia_id 多媒体通道
  258. * @param vol 音量,0-1000 0-100为硬件 100-1000为软件缩放,实际根据不同bsp不同硬件底层实现
  259. * @return uint16_t 音量,0-1000
  260. */
  261. uint16_t luat_audio_vol(uint8_t multimedia_id, uint16_t vol);
  262. /**
  263. * @brief mic音量控制
  264. *
  265. * @param multimedia_id 多媒体通道
  266. * @param vol 音量,0-100
  267. * @return uint8_t 音量 0-100
  268. */
  269. uint8_t luat_audio_mic_vol(uint8_t multimedia_id, uint16_t vol);
  270. /**
  271. * @brief 静音
  272. *
  273. * @param multimedia_id 多媒体通道
  274. * @param on 1 静音,0 取消静音
  275. * @return uint8_t 1 静音,0 取消静音
  276. */
  277. uint8_t luat_audio_mute(uint8_t multimedia_id, uint8_t on);
  278. /**
  279. * @brief 音频调试开关
  280. *
  281. * @param multimedia_id 多媒体通道
  282. * @param onoff 0关闭,1打开
  283. */
  284. void luat_audio_play_debug_onoff(uint8_t multimedia_id, uint8_t onoff);
  285. /**
  286. * @brief 检测音频是否准备就绪
  287. *
  288. * @param multimedia_id 多媒体通道
  289. * @return int -1未就绪,0就绪
  290. */
  291. int luat_audio_check_ready(uint8_t multimedia_id);
  292. /**
  293. * @brief 录音并播放
  294. *
  295. * @param multimedia_id 多媒体通道
  296. * @param sample_rate 采样率
  297. * @param play_buffer buffer
  298. * @param one_trunk_len 一次传输长度
  299. * @param total_trunk_cnt 传输次数
  300. * @return int 成功返回0,失败返回-1
  301. */
  302. int luat_audio_record_and_play(uint8_t multimedia_id, uint32_t sample_rate, const uint8_t *play_buffer, uint32_t one_trunk_len, uint32_t total_trunk_cnt);
  303. /**
  304. * @brief 录音停止
  305. *
  306. * @param multimedia_id 多媒体通道
  307. * @return int 成功返回0,失败返回-1
  308. */
  309. int luat_audio_record_stop(uint8_t multimedia_id);
  310. /**
  311. * @brief 开始通话输出
  312. *
  313. * @param multimedia_id 多媒体通道
  314. * @param is_downlink 通话是否连接
  315. * @param type 类型
  316. * @param downlink_buffer buffer
  317. * @param buffer_len buffer 长度
  318. * @param channel_num 通道
  319. * @return int 成功返回0,失败返回-1
  320. */
  321. int luat_audio_speech(uint8_t multimedia_id, uint8_t is_downlink, uint8_t type, const uint8_t *downlink_buffer, uint32_t buffer_len, uint8_t channel_num);
  322. /**
  323. * @brief 通话输出停止
  324. *
  325. * @param multimedia_id 多媒体通道
  326. * @return int 成功返回0,失败返回-1
  327. */
  328. int luat_audio_speech_stop(uint8_t multimedia_id);
  329. /**
  330. * @brief pa控制函数,一般不需要使用,底层会自动调用
  331. *
  332. * @param multimedia_id multimedia_id 多媒体通道
  333. * @param on 1开,0关
  334. * @param delay 延迟时间,非阻塞,不延迟写0
  335. */
  336. void luat_audio_pa(uint8_t multimedia_id,uint8_t on, uint32_t delay);
  337. /**
  338. * @brief power控制函数,一般不需要使用,底层会自动调用
  339. *
  340. * @param multimedia_id 多媒体通道
  341. * @param on 1开,0关
  342. */
  343. void luat_audio_power(uint8_t multimedia_id,uint8_t on);
  344. /**
  345. * @brief power保持控制,部分平台休眠时部分GPIO断电,因此需要控制是否进入休眠来
  346. *
  347. * @param on_off 1保持,0不保持
  348. */
  349. void luat_audio_power_keep_ctrl_by_bsp(uint8_t on_off);
  350. /**
  351. * @brief 把api投放到audio task运行
  352. *
  353. * @param api 需要运行的api
  354. * @param data api输入数据
  355. * @param len api输入数据长度
  356. */
  357. void luat_audio_run_callback_in_task(void *api, uint8_t *data, uint32_t len);
  358. typedef void (*luat_audio_record_callback)(uint8_t multimedia_id, uint8_t *rx_data, uint32_t rx_len, void *param); // 非i2s录音回调函数
  359. void luat_audio_setup_record_callback(uint8_t multimedia_id, luat_audio_record_callback callback, void *param);
  360. void *luat_audio_inter_amr_coder_init(uint8_t is_wb, uint8_t quality);
  361. int luat_audio_inter_amr_coder_encode(void *handle, const uint16_t *pcm_buf, uint8_t *amr_buf, uint8_t *amr_len);
  362. int luat_audio_inter_amr_coder_decode(void *handle, uint16_t *pcm_buf, const uint8_t *amr_buf, uint8_t *amr_len);
  363. void luat_audio_inter_amr_coder_deinit(void *handle);
  364. #endif