audio_digital_vol.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754
  1. #include "audio_digital_vol.h"
  2. #define DIGITAL_FADE_EN 1
  3. #define DIGITAL_FADE_STEP 4
  4. #define BG_DVOL_MAX 14
  5. #define BG_DVOL_MID 10
  6. #define BG_DVOL_MIN 6
  7. #define BG_DVOL_MAX_FADE 5 /*>= BG_DVOL_MAX:自动淡出BG_DVOL_MAX_FADE*/
  8. #define BG_DVOL_MID_FADE 3 /*>= BG_DVOL_MID:自动淡出BG_DVOL_MID_FADE*/
  9. #define BG_DVOL_MIN_FADE 1 /*>= BG_DVOL_MIN:自动淡出BG_DVOL_MIN_FADE*/
  10. #define ASM_ENABLE 1
  11. #define L_sat(b,a) __asm__ volatile("%0=sat16(%1)(s)":"=&r"(b) : "r"(a));
  12. #define L_sat32(b,a,n) __asm__ volatile("%0=%1>>%2(s)":"=&r"(b) : "r"(a),"r"(n));
  13. typedef struct {
  14. u8 bg_dvol_fade_out;
  15. struct list_head dvol_head;
  16. } dvol_t;
  17. static dvol_t dvol_attr;
  18. //static struct digital_volume d_volume;
  19. /*
  20. *数字音量级数 DIGITAL_VOL_MAX
  21. *数组长度 DIGITAL_VOL_MAX + 1
  22. */
  23. #define DIGITAL_VOL_MAX 31
  24. const u16 dig_vol_table[DIGITAL_VOL_MAX + 1] = {
  25. 0 , //0
  26. 93 , //1
  27. 111 , //2
  28. 132 , //3
  29. 158 , //4
  30. 189 , //5
  31. 226 , //6
  32. 270 , //7
  33. 323 , //8
  34. 386 , //9
  35. 462 , //10
  36. 552 , //11
  37. 660 , //12
  38. 789 , //13
  39. 943 , //14
  40. 1127, //15
  41. 1347, //16
  42. 1610, //17
  43. 1925, //18
  44. 2301, //19
  45. 2751, //20
  46. 3288, //21
  47. 3930, //22
  48. 4698, //23
  49. 5616, //24
  50. 6713, //25
  51. 8025, //26
  52. 9592, //27
  53. 11466,//28
  54. 15200,//29
  55. 16000,//30
  56. 16384 //31
  57. };
  58. int audio_digital_vol_init(void)
  59. {
  60. INIT_LIST_HEAD(&dvol_attr.dvol_head);
  61. return 0;
  62. }
  63. /*背景音乐淡出使能*/
  64. void audio_digital_vol_bg_fade(u8 fade_out)
  65. {
  66. printf("audio_digital_vol_bg_fade:%d", fade_out);
  67. dvol_attr.bg_dvol_fade_out = fade_out;
  68. }
  69. /*
  70. *fade_step一般不超过两级数字音量的最小差值
  71. *(1)通话如果用数字音量,一般步进小一点,音量调节的时候不会有杂音
  72. *(2)淡出的时候可以快一点,尽快淡出到0
  73. */
  74. dvol_handle *audio_digital_vol_open(u8 vol, u8 vol_max, u16 fade_step)
  75. {
  76. dvol_handle *dvol = NULL;
  77. dvol = zalloc(sizeof(dvol_handle));
  78. if (dvol) {
  79. u8 vol_level;
  80. dvol->fade = DIGITAL_FADE_EN;
  81. dvol->vol = (vol > vol_max) ? vol_max : vol;
  82. if (vol > vol_max) {
  83. printf("[warning]cur digital_vol(%d) > digital_vol_max(%d)!!", vol, vol_max);
  84. }
  85. dvol->vol_max = vol_max;
  86. vol_level = dvol->vol * DIGITAL_VOL_MAX / vol_max;
  87. dvol->vol_target = dig_vol_table[vol_level];
  88. dvol->vol_fade = dvol->vol_target;
  89. dvol->fade_step = fade_step;
  90. dvol->toggle = 1;
  91. #if BG_DVOL_FADE_ENABLE
  92. dvol->vol_bk = -1;
  93. local_irq_disable();
  94. list_add(&dvol->entry, &dvol_attr.dvol_head);
  95. if (dvol_attr.bg_dvol_fade_out) {
  96. dvol_handle *hdl;
  97. list_for_each_entry(hdl, &dvol_attr.dvol_head, entry) {
  98. if (hdl != dvol) {
  99. hdl->vol_bk = hdl->vol;
  100. if (hdl->vol >= BG_DVOL_MAX) {
  101. hdl->vol -= BG_DVOL_MAX_FADE;
  102. } else if (hdl->vol >= BG_DVOL_MID) {
  103. hdl->vol -= BG_DVOL_MID_FADE;
  104. } else if (hdl->vol >= BG_DVOL_MIN) {
  105. hdl->vol -= BG_DVOL_MIN_FADE;
  106. } else {
  107. hdl->vol_bk = -1;
  108. continue;
  109. }
  110. u8 vol_level = hdl->vol * DIGITAL_VOL_MAX / hdl->vol_max;
  111. hdl->vol_target = dig_vol_table[vol_level];
  112. //y_printf("bg_dvol fade_out:%x,vol_bk:%d,vol_set:%d,tartget:%d",hdl,hdl->vol_bk,hdl->vol,hdl->vol_target);
  113. }
  114. }
  115. }
  116. local_irq_enable();
  117. #endif
  118. printf("digital_vol_open:%x-%d-%d-%d\n", dvol, dvol->vol, dvol->vol_max, fade_step);
  119. }
  120. return dvol;
  121. }
  122. void audio_digital_vol_close(dvol_handle *dvol)
  123. {
  124. printf("digital_vol_close:%x\n", dvol);
  125. if (dvol) {
  126. #if BG_DVOL_FADE_ENABLE
  127. local_irq_disable();
  128. list_del(&dvol->entry);
  129. dvol_handle *hdl;
  130. list_for_each_entry(hdl, &dvol_attr.dvol_head, entry) {
  131. if ((hdl != dvol) && (hdl->vol_bk >= 0)) {
  132. //y_printf("bg_dvol fade_in:%x,%d",hdl,hdl->vol_bk);
  133. hdl->vol = hdl->vol_bk;
  134. u8 vol_level = hdl->vol_bk * DIGITAL_VOL_MAX / hdl->vol_max;
  135. hdl->vol_target = dig_vol_table[vol_level];
  136. hdl->vol_bk = -1;
  137. }
  138. }
  139. local_irq_enable();
  140. #endif
  141. free(dvol);
  142. dvol = NULL;
  143. }
  144. }
  145. /* u8 audio_digital_vol_get(void)
  146. {
  147. return d_volume.vol;
  148. } */
  149. void audio_digital_vol_set(dvol_handle *dvol, u8 vol)
  150. {
  151. if (dvol == NULL) {
  152. return;
  153. }
  154. if (dvol->toggle == 0) {
  155. return;
  156. }
  157. dvol->vol = (vol > dvol->vol_max) ? dvol->vol_max : vol;
  158. #if BG_DVOL_FADE_ENABLE
  159. if (dvol->vol_bk != -1) {
  160. dvol->vol_bk = vol;
  161. }
  162. #endif
  163. dvol->fade = DIGITAL_FADE_EN;
  164. u8 vol_level = dvol->vol * DIGITAL_VOL_MAX / dvol->vol_max;
  165. dvol->vol_target = dig_vol_table[vol_level];
  166. printf("digital_vol:%d-%d-%d-%d\n", vol, vol_level, dvol->vol_fade, dvol->vol_target);
  167. }
  168. void audio_digital_vol_reset_fade(dvol_handle *dvol)
  169. {
  170. if (dvol) {
  171. dvol->vol_fade = 0;
  172. }
  173. }
  174. int audio_digital_vol_run(dvol_handle *dvol, void *data, u32 len)
  175. {
  176. s32 valuetemp;
  177. s16 *buf;
  178. if (dvol->toggle == 0) {
  179. return -1;
  180. }
  181. buf = data;
  182. len >>= 1; //byte to point
  183. for (u32 i = 0; i < len; i += 2) {
  184. ///left channel
  185. if (dvol->fade) {
  186. if (dvol->vol_fade > dvol->vol_target) {
  187. dvol->vol_fade -= dvol->fade_step;
  188. if (dvol->vol_fade < dvol->vol_target) {
  189. dvol->vol_fade = dvol->vol_target;
  190. }
  191. } else if (dvol->vol_fade < dvol->vol_target) {
  192. dvol->vol_fade += dvol->fade_step;
  193. if (dvol->vol_fade > dvol->vol_target) {
  194. dvol->vol_fade = dvol->vol_target;
  195. }
  196. }
  197. } else {
  198. dvol->vol_fade = dvol->vol_target;
  199. }
  200. valuetemp = buf[i];
  201. if (valuetemp < 0) {
  202. valuetemp = -valuetemp;
  203. valuetemp = (valuetemp * dvol->vol_fade) >> 14 ;
  204. valuetemp = -valuetemp;
  205. } else {
  206. valuetemp = (valuetemp * dvol->vol_fade) >> 14 ;
  207. }
  208. if (valuetemp < -32768) {
  209. valuetemp = -32768;
  210. } else if (valuetemp > 32767) {
  211. valuetemp = 32767;
  212. }
  213. buf[i] = (s16)valuetemp;
  214. ///right channel
  215. valuetemp = buf[i + 1];
  216. if (valuetemp < 0) {
  217. valuetemp = -valuetemp;
  218. valuetemp = (valuetemp * dvol->vol_fade) >> 14 ;
  219. valuetemp = -valuetemp;
  220. } else {
  221. valuetemp = (valuetemp * dvol->vol_fade) >> 14 ;
  222. }
  223. if (valuetemp < -32768) {
  224. valuetemp = -32768;
  225. } else if (valuetemp > 32767) {
  226. valuetemp = 32767;
  227. }
  228. buf[i + 1] = (s16)valuetemp;
  229. }
  230. return 0;
  231. }
  232. /*************************支持重入的数字音量调节****************************/
  233. /*
  234. *fade_step一般不超过两级数字音量的最小差值
  235. *(1)通话如果用数字音量,一般步进小一点,音量调节的时候不会有杂音
  236. *(2)淡出的时候可以快一点,尽快淡出到0
  237. */
  238. void *user_audio_digital_volume_open(u8 vol, u8 vol_max, u16 fade_step)
  239. {
  240. struct digital_volume *d_volume = zalloc(sizeof(struct digital_volume));
  241. if (!d_volume) {
  242. log_e("d_volume NULL\n");
  243. return NULL;
  244. }
  245. u8 vol_level;
  246. d_volume->fade = 0;
  247. d_volume->vol = vol;
  248. d_volume->vol_max = vol_max;
  249. vol_level = vol * DIGITAL_VOL_MAX / vol_max;
  250. d_volume->vol_target = dig_vol_table[vol_level];
  251. //d_volume->vol_fade = 0;//d_volume->vol_target;//打开时,从0开始淡入
  252. d_volume->vol_fade = d_volume->vol_target;
  253. d_volume->fade_step = fade_step;
  254. d_volume->toggle = 1;
  255. d_volume->ch_num = 2;//默认双声道
  256. d_volume->user_vol_tab = NULL;
  257. d_volume->user_vol_max = 0;
  258. os_mutex_create(&d_volume->mutex);
  259. printf("digital_vol_open:%d-%d-%d\n", vol, vol_max, fade_step);
  260. return d_volume;
  261. }
  262. int user_audio_digital_volume_close(void *_d_volume)
  263. {
  264. struct digital_volume *d_volume = (struct digital_volume *)_d_volume;
  265. if (!d_volume) {
  266. log_e("d_volume NULL\n");
  267. return -1;
  268. }
  269. /* os_mutex_pend(&d_volume->mutex, 0); */
  270. d_volume->toggle = 0;
  271. d_volume->user_vol_tab = NULL;
  272. d_volume->user_vol_max = 0;
  273. if (d_volume) {
  274. free(d_volume);
  275. d_volume = NULL;
  276. }
  277. /* os_mutex_post(&d_volume->mutex); */
  278. printf("digital_vol_close\n");
  279. return 0;
  280. }
  281. u8 user_audio_digital_volume_get(void *_d_volume)
  282. {
  283. struct digital_volume *d_volume = (struct digital_volume *)_d_volume;
  284. if (!d_volume) {
  285. log_e("d_volume NULL\n");
  286. return 0;
  287. }
  288. /* os_mutex_pend(&d_volume->mutex, 0); */
  289. u8 vol = d_volume->vol;
  290. /* os_mutex_post(&d_volume->mutex); */
  291. return vol;
  292. }
  293. int user_audio_digital_volume_set(void *_d_volume, u8 vol)
  294. {
  295. struct digital_volume *d_volume = (struct digital_volume *)_d_volume;
  296. if (!d_volume) {
  297. log_e("d_volume NULL\n");
  298. return -1;
  299. }
  300. u8 vol_level;
  301. if (d_volume->toggle == 0) {
  302. return 0;
  303. }
  304. /* os_mutex_pend(&d_volume->mutex, 0); */
  305. d_volume->vol = vol;
  306. d_volume->fade = DIGITAL_FADE_EN;
  307. if (!d_volume->user_vol_tab) {
  308. vol_level = d_volume->vol * DIGITAL_VOL_MAX / d_volume->vol_max;
  309. d_volume->vol_target = dig_vol_table[vol_level];
  310. } else {
  311. u8 d_vol_max = d_volume->user_vol_max - 1;
  312. vol_level = d_volume->vol * d_vol_max / d_volume->vol_max;
  313. d_volume->vol_target = d_volume->user_vol_tab[vol_level];
  314. }
  315. /* os_mutex_post(&d_volume->mutex); */
  316. /* printf("digital_vol:%d-%d-%d-%d\n", vol, vol_level, d_volume->vol_fade, d_volume->vol_target); */
  317. return 0;
  318. }
  319. int user_audio_digital_volume_reset_fade(void *_d_volume)
  320. {
  321. struct digital_volume *d_volume = (struct digital_volume *)_d_volume;
  322. if (!d_volume) {
  323. log_e("d_volume NULL\n");
  324. return -1;
  325. }
  326. os_mutex_pend(&d_volume->mutex, 0);
  327. d_volume->vol_fade = 0;
  328. os_mutex_post(&d_volume->mutex);
  329. return 0;
  330. }
  331. #if ASM_ENABLE
  332. #define audio_vol_mix(data,len, ch_num,volumeNOW,volumeDest,step){ \
  333. int i, j; \
  334. int fade = 0; \
  335. if (volumeNOW != volumeDest) \
  336. { \
  337. fade = 1; \
  338. } \
  339. if(d_volume->fade == 0)\
  340. {\
  341. fade = 0;\
  342. d_volume->vol_fade = d_volume->vol_target;\
  343. }\
  344. if (ch_num == 2) \
  345. { \
  346. len = len >> 1; \
  347. } \
  348. else if (ch_num == 3) \
  349. { \
  350. len = (len*5462)>>14; /*等效除3,因为5462向上取整得到的*/\
  351. } \
  352. else if(ch_num == 4) \
  353. { \
  354. len = len >> 2; \
  355. } \
  356. if (fade) \
  357. { \
  358. short *in_ptr = data; \
  359. for (i = 0; i < len; i++) \
  360. { \
  361. if (volumeNOW < volumeDest) \
  362. { \
  363. volumeNOW = volumeNOW + step; \
  364. if (volumeNOW > volumeDest) \
  365. { \
  366. volumeNOW = volumeDest; \
  367. } \
  368. } \
  369. else if (volumeNOW > volumeDest) \
  370. { \
  371. volumeNOW = volumeNOW - step; \
  372. if (volumeNOW < volumeDest) \
  373. { \
  374. volumeNOW = volumeDest; \
  375. } \
  376. } \
  377. { \
  378. int tmp; \
  379. int reptime = ch_num; \
  380. __asm__ volatile( \
  381. " 1 : \n\t" \
  382. " rep %0 { \n\t" \
  383. " %1 = h[%2](s) \n\t" \
  384. " %1 =%1* %3 \n\t "\
  385. " %1 =%1 >>>14 \n\t"\
  386. " h[%2++=2]= %1 \n\t"\
  387. " }\n\t" \
  388. " if(%0!=0 )goto 1b \n\t" \
  389. : "=&r"(reptime), \
  390. "=&r"(tmp), \
  391. "=&r"(in_ptr) \
  392. :"r"(volumeNOW), \
  393. "0"(reptime),\
  394. "2"(in_ptr)\
  395. : "cc", "memory"); \
  396. } \
  397. } \
  398. } \
  399. else \
  400. { \
  401. for (i = 0; i < ch_num; i++) \
  402. { \
  403. short *in_ptr = &data[i]; \
  404. { \
  405. int tmp; \
  406. int chnumv=ch_num*2;\
  407. int reptime = len;\
  408. __asm__ volatile(\
  409. " 1 : \n\t"\
  410. " rep %0 { \n\t"\
  411. " %1 = h[%2](s) \n\t"\
  412. " %1 = %1 *%3 \n\t "\
  413. " %1= %1 >>>14 \n\t"\
  414. " h[%2++=%4]= %1 \n\t"\
  415. " }\n\t"\
  416. " if(%0!=0 )goto 1b \n\t"\
  417. : "=&r"(reptime),\
  418. "=&r"(tmp),\
  419. "=&r"(in_ptr) \
  420. :"r"(volumeNOW), \
  421. "r"(chnumv),\
  422. "0"(reptime),\
  423. "2"(in_ptr)\
  424. : "cc", "memory");\
  425. } \
  426. }\
  427. }\
  428. }
  429. #else
  430. #define audio_vol_mix(data,len, ch_num,volumeNOW,volumeDest,step){ \
  431. int i, j; \
  432. int fade = 0; \
  433. if (volumeNOW != volumeDest) \
  434. { \
  435. fade = 1; \
  436. } \
  437. if(d_volume->fade == 0)\
  438. {\
  439. fade = 0;\
  440. d_volume->vol_fade = d_volume->vol_target;\
  441. }\
  442. if (ch_num == 2) \
  443. { \
  444. len = len >> 1; \
  445. } \
  446. else if (ch_num == 3) \
  447. { \
  448. len = (len*5462)>>14; /*等效除3,因为5462向上取整得到的*/\
  449. } \
  450. else if(ch_num == 4) \
  451. { \
  452. len = len >> 2; \
  453. } \
  454. if (fade) \
  455. { \
  456. short *in_ptr = data; \
  457. for (i = 0; i < len; i++) \
  458. { \
  459. if (volumeNOW < volumeDest) \
  460. { \
  461. volumeNOW = volumeNOW + step; \
  462. if (volumeNOW > volumeDest) \
  463. { \
  464. volumeNOW = volumeDest; \
  465. } \
  466. } \
  467. else if (volumeNOW > volumeDest) \
  468. { \
  469. volumeNOW = volumeNOW - step; \
  470. if (volumeNOW < volumeDest) \
  471. { \
  472. volumeNOW = volumeDest; \
  473. } \
  474. } \
  475. for (j = 0; j < ch_num; j++) \
  476. { \
  477. int tmp = (*in_ptr*volumeNOW) >> 14; \
  478. L_sat(tmp, tmp); \
  479. *in_ptr = tmp; \
  480. in_ptr++; \
  481. } \
  482. } \
  483. } \
  484. else \
  485. { \
  486. for (i = 0; i < ch_num; i++) \
  487. { \
  488. short *in_ptr = &data[i]; \
  489. for (j = 0; j < len; j++)\
  490. {\
  491. int tmp= (*in_ptr*volumeNOW) >> 14; \
  492. L_sat(tmp, tmp); \
  493. *in_ptr = tmp;\
  494. in_ptr += ch_num;\
  495. }\
  496. }\
  497. }\
  498. }
  499. #endif
  500. int user_audio_digital_volume_run(void *_d_volume, void *data, u32 len, u8 ch_num)
  501. {
  502. struct digital_volume *d_volume = (struct digital_volume *)_d_volume;
  503. if (!d_volume) {
  504. log_e("d_volume NULL\n");
  505. return -1;
  506. }
  507. s32 valuetemp;
  508. s16 *buf;
  509. if (d_volume->toggle == 0) {
  510. return -1;
  511. }
  512. if (ch_num > 4) {
  513. return -1;
  514. }
  515. os_mutex_pend(&d_volume->mutex, 0);
  516. if (ch_num) {
  517. d_volume->ch_num = ch_num;
  518. }
  519. buf = data;
  520. len >>= 1; //byte to point
  521. /* printf("d_volume->vol_target %d %d %d %d\n", d_volume->vol_target, ch_num, d_volume->vol_fade, d_volume->fade_step); */
  522. #if 1
  523. audio_vol_mix(buf, len, ch_num, d_volume->vol_fade, d_volume->vol_target, d_volume->fade_step);
  524. #else
  525. /* printf("d_volume->vol_target %d %d\n", d_volume->vol_target, ch_num); */
  526. for (u32 i = 0; i < len; i += d_volume->ch_num) {//ch_num 1/2/3/4
  527. ///FL channel
  528. if (d_volume->fade) {
  529. if (d_volume->vol_fade > d_volume->vol_target) {
  530. d_volume->vol_fade -= d_volume->fade_step;
  531. if (d_volume->vol_fade < d_volume->vol_target) {
  532. d_volume->vol_fade = d_volume->vol_target;
  533. }
  534. } else if (d_volume->vol_fade < d_volume->vol_target) {
  535. d_volume->vol_fade += d_volume->fade_step;
  536. if (d_volume->vol_fade > d_volume->vol_target) {
  537. d_volume->vol_fade = d_volume->vol_target;
  538. }
  539. }
  540. } else {
  541. d_volume->vol_fade = d_volume->vol_target;
  542. }
  543. valuetemp = buf[i];
  544. if (valuetemp < 0) {
  545. valuetemp = -valuetemp;
  546. valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
  547. valuetemp = -valuetemp;
  548. } else {
  549. valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
  550. }
  551. if (valuetemp < -32768) {
  552. valuetemp = -32768;
  553. } else if (valuetemp > 32767) {
  554. valuetemp = 32767;
  555. }
  556. buf[i] = (s16)valuetemp;
  557. if (d_volume->ch_num > 1) { //双声道
  558. ///FR channel
  559. valuetemp = buf[i + 1];
  560. if (valuetemp < 0) {
  561. valuetemp = -valuetemp;
  562. valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
  563. valuetemp = -valuetemp;
  564. } else {
  565. valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
  566. }
  567. if (valuetemp < -32768) {
  568. valuetemp = -32768;
  569. } else if (valuetemp > 32767) {
  570. valuetemp = 32767;
  571. }
  572. buf[i + 1] = (s16)valuetemp;
  573. if (d_volume->ch_num > 2) { //三声道
  574. //RL channel
  575. valuetemp = buf[i + 2];
  576. if (valuetemp < 0) {
  577. valuetemp = -valuetemp;
  578. valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
  579. valuetemp = -valuetemp;
  580. } else {
  581. valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
  582. }
  583. if (valuetemp < -32768) {
  584. valuetemp = -32768;
  585. } else if (valuetemp > 32767) {
  586. valuetemp = 32767;
  587. }
  588. buf[i + 2] = (s16)valuetemp;
  589. if (d_volume->ch_num > 3) { //四声道
  590. ///RR channel
  591. valuetemp = buf[i + 3];
  592. if (valuetemp < 0) {
  593. valuetemp = -valuetemp;
  594. valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
  595. valuetemp = -valuetemp;
  596. } else {
  597. valuetemp = (valuetemp * d_volume->vol_fade) >> 14 ;
  598. }
  599. if (valuetemp < -32768) {
  600. valuetemp = -32768;
  601. } else if (valuetemp > 32767) {
  602. valuetemp = 32767;
  603. }
  604. buf[i + 3] = (s16)valuetemp;
  605. }
  606. }
  607. }
  608. }
  609. #endif
  610. os_mutex_post(&d_volume->mutex);
  611. return 0;
  612. }
  613. /*
  614. *user_vol_max:音量级数
  615. *user_vol_tab:自定义音量表,自定义表长user_vol_max+1
  616. */
  617. void user_audio_digital_set_volume_tab(void *_d_volume, u16 *user_vol_tab, u8 user_vol_max)
  618. {
  619. struct digital_volume *d_volume = (struct digital_volume *)_d_volume;
  620. if (!d_volume) {
  621. log_e("d_volume NULL\n");
  622. return ;
  623. }
  624. os_mutex_pend(&d_volume->mutex, 0);
  625. if (user_vol_tab) {
  626. d_volume->user_vol_tab = user_vol_tab;
  627. d_volume->user_vol_max = user_vol_max;
  628. }
  629. os_mutex_post(&d_volume->mutex);
  630. }
  631. /*
  632. *priv:用户自定义指针
  633. *void (*handler)(void *priv, void *data, int len, u8 ch_num):用户自定义回调
  634. * */
  635. void *user_audio_process_open(void *parm, void *priv, void (*handler)(void *priv, void *data, int len, u8 ch_num))
  636. {
  637. struct user_audio_parm *user_hdl = zalloc(sizeof(struct user_audio_parm));
  638. if (!user_hdl) {
  639. log_e("user_hdl NULL\n");
  640. return NULL;
  641. }
  642. user_hdl->priv = priv;
  643. user_hdl->handler = handler;
  644. struct user_audio_digital_parm *dvol_parm = (struct user_audio_digital_parm *)parm;
  645. if (dvol_parm->en) {
  646. log_i("vol :%d vol_max:%d fade_step:%d\n", dvol_parm->vol, dvol_parm->vol_max, dvol_parm->fade_step);
  647. user_hdl->dvol_hdl = user_audio_digital_volume_open(dvol_parm->vol, dvol_parm->vol_max, dvol_parm->fade_step);
  648. }
  649. log_i("%s ok\n", __FUNCTION__);
  650. return user_hdl;
  651. }
  652. int user_audio_process_close(void *_uparm_hdl)
  653. {
  654. struct user_audio_parm *user_hdl = (struct user_audio_parm *)_uparm_hdl;
  655. if (!user_hdl) {
  656. log_e("user_hdl NULL\n");
  657. return -1;
  658. }
  659. if (user_hdl->dvol_hdl) {
  660. user_audio_digital_volume_close(user_hdl->dvol_hdl);
  661. user_hdl->dvol_hdl = NULL;
  662. }
  663. free(user_hdl);
  664. user_hdl = NULL;
  665. log_i("%s ok\n", __FUNCTION__);
  666. return 0;
  667. }
  668. void user_audio_process_handler_run(void *_uparm_hdl, void *data, u32 len, u8 ch_num)
  669. {
  670. struct user_audio_parm *user_hdl = (struct user_audio_parm *)_uparm_hdl;
  671. if (!user_hdl) {
  672. log_e("user_hdl NULL\n");
  673. return;
  674. }
  675. if (user_hdl->handler) {
  676. user_hdl->handler(user_hdl->priv, data, len, ch_num);
  677. }
  678. if (user_hdl->dvol_hdl) {
  679. user_audio_digital_volume_run(user_hdl->dvol_hdl, data, len, ch_num);
  680. }
  681. }