main.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>
  4. #include <pthread.h>
  5. #include <stdbool.h>
  6. #include <alsa/asoundlib.h>
  7. //#include <sys/time.h>
  8. //#include <sys/socket.h>
  9. //#include <sys/un.h>
  10. #include <hiredis/hiredis.h>
  11. #include <cjson/cJSON.h>
  12. #include <iniparser/iniparser.h>
  13. #define SAMPLE_RATE 48000
  14. #define CHANNEL 2
  15. #define REC_DEVICE_NAME "fake_record"
  16. #define WRITE_DEVICE_NAME "fake_play"
  17. //#define WRITE_DEVICE_NAME "default"
  18. #define JACK_DEVICE_NAME "fake_jack"
  19. #define READ_FRAME 1024 //(768)
  20. #define PERIOD_SIZE (1024) //(SAMPLE_RATE/8)
  21. #define PERIOD_counts (2) //double of delay 200ms
  22. #define BUFFER_SIZE (PERIOD_SIZE * PERIOD_counts)
  23. // #define MUTE_TIME_THRESHOD (4)//seconds
  24. // #define MUTE_FRAME_THRESHOD (SAMPLE_RATE * MUTE_TIME_THRESHOD / READ_FRAME)//30 seconds
  25. //#define ALSA_READ_FORMAT SND_PCM_FORMAT_S32_LE
  26. #define ALSA_READ_FORMAT SND_PCM_FORMAT_S16_LE
  27. #define ALSA_WRITE_FORMAT SND_PCM_FORMAT_S16_LE
  28. #define paging_channel "volume-event-channel"
  29. // #define volume_channel "volume-value-channel"
  30. // #define volume_temp_channel "volume-temp-channel"
  31. #define VOL_CONF "/oem/etc/volctrl.conf"
  32. #define unix_socket_path "/tmp/redis.sock"
  33. /*
  34. * Select different alsa pathways based on device type.
  35. * LINE_OUT: LR-Mix(fake_play)->EqDrcProcess(ladspa)->Speaker(real_playback)
  36. * HEAD_SET: fake_jack -> Headset(real_playback)
  37. * BLUETOOTH: device as bluetooth source.
  38. */
  39. // #define DEVICE_FLAG_LINE_OUT 0x01
  40. // #define DEVICE_FLAG_HEAD_SET 0x02
  41. // #define DEVICE_FLAG_BLUETOOTH 0x04
  42. #define AULEVEL_MIN -96.0
  43. #define AULEVEL_MAX 0.0
  44. //current session
  45. #define IDLE 0
  46. #define SIP 1
  47. #define BROADCAST 2
  48. #define MULTICAST 3
  49. #define ONVIF 4
  50. typedef struct _vumeter_play {
  51. int16_t *ch1_sampv;
  52. int16_t *ch2_sampv;
  53. size_t au_sampc;
  54. double ch1_avg_play;
  55. double ch2_avg_play;
  56. } vumeter_play;
  57. typedef struct {
  58. redisContext *context;
  59. const char *socket_path;
  60. time_t last_activity;
  61. } redis_client_t;
  62. static bool set_volume = false;
  63. static int volume = 100;
  64. static int en_threshold = false;
  65. static int vol_threshold;
  66. static int current_sess = IDLE;
  67. static int ctrl_sess = IDLE;
  68. static int sip_active = false;
  69. static int mc_active = false;
  70. static int onvif_active = false;
  71. static int bc_active = false;
  72. static bool DEBUG = false;
  73. //struct timeval tv_begin, tv_end;
  74. //gettimeofday(&tv_begin, NULL);
  75. extern int set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t buffer_size,
  76. snd_pcm_uframes_t period_size, char **msg);
  77. redis_client_t* create_redis_client(const char *socket_path) {
  78. redis_client_t *client = (redis_client_t *) malloc(sizeof(redis_client_t));
  79. client->socket_path = socket_path;
  80. client->context = redisConnectUnix(socket_path);
  81. client->last_activity = time(NULL);
  82. return client;
  83. }
  84. int ensure_connected(redis_client_t *client) {
  85. if (client->context == NULL || client->context->err) {
  86. if (client->context) {
  87. redisFree(client->context);
  88. }
  89. client->context = redisConnectUnix(client->socket_path);
  90. if (client->context == NULL || client->context->err) {
  91. return -1; // 连接失败
  92. }
  93. }
  94. client->last_activity = time(NULL);
  95. return 0;
  96. }
  97. void redis_command_safe(redis_client_t *client, const char *command) {
  98. if (ensure_connected(client) == 0) {
  99. redisReply *reply = (redisReply *) redisCommand(client->context, command);
  100. if (reply) {
  101. // 处理回复
  102. freeReplyObject(reply);
  103. }
  104. }
  105. }
  106. void alsa_fake_device_record_open(snd_pcm_t** capture_handle,int channels,uint32_t rate)
  107. {
  108. snd_pcm_hw_params_t *hw_params;
  109. snd_pcm_uframes_t periodSize = PERIOD_SIZE;
  110. snd_pcm_uframes_t bufferSize = BUFFER_SIZE;
  111. int dir = 0;
  112. int err;
  113. err = snd_pcm_open(capture_handle, REC_DEVICE_NAME, SND_PCM_STREAM_CAPTURE, 0);
  114. if (err)
  115. {
  116. printf( "Unable to open capture PCM device: \n");
  117. exit(1);
  118. }
  119. printf("snd_pcm_open\n");
  120. //err = snd_pcm_hw_params_alloca(&hw_params);
  121. err = snd_pcm_hw_params_malloc(&hw_params);
  122. if(err)
  123. {
  124. fprintf(stderr, "cannot allocate hardware parameter structure (%s)\n",snd_strerror(err));
  125. exit(1);
  126. }
  127. printf("snd_pcm_hw_params_malloc\n");
  128. err = snd_pcm_hw_params_any(*capture_handle, hw_params);
  129. if(err)
  130. {
  131. fprintf(stderr, "cannot initialize hardware parameter structure (%s)\n",snd_strerror(err));
  132. exit(1);
  133. }
  134. printf("snd_pcm_hw_params_any!\n");
  135. err = snd_pcm_hw_params_set_access(*capture_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
  136. // err = snd_pcm_hw_params_set_access(*capture_handle, hw_params, SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
  137. if (err)
  138. {
  139. printf("Error setting interleaved mode\n");
  140. exit(1);
  141. }
  142. printf("snd_pcm_hw_params_set_access!\n");
  143. err = snd_pcm_hw_params_set_format(*capture_handle, hw_params, ALSA_READ_FORMAT);
  144. if (err)
  145. {
  146. printf("Error setting format: %s\n", snd_strerror(err));
  147. exit(1);
  148. }
  149. printf("snd_pcm_hw_params_set_format\n");
  150. err = snd_pcm_hw_params_set_channels(*capture_handle, hw_params, channels);
  151. if (err)
  152. {
  153. printf("channels = %d\n",channels);
  154. printf( "Error setting channels: %s\n", snd_strerror(err));
  155. exit(1);
  156. }
  157. printf("channels = %d\n",channels);
  158. err = snd_pcm_hw_params_set_buffer_size_near(*capture_handle, hw_params, &bufferSize);
  159. if (err)
  160. {
  161. printf("Error setting buffer size (%ld): %s\n", bufferSize, snd_strerror(err));
  162. exit(1);
  163. }
  164. printf("bufferSize = %ld\n",bufferSize);
  165. err = snd_pcm_hw_params_set_period_size_near(*capture_handle, hw_params, &periodSize, 0);
  166. if (err)
  167. {
  168. printf("Error setting period time (%ld): %s\n", periodSize, snd_strerror(err));
  169. exit(1);
  170. }
  171. printf("periodSize = %ld\n",periodSize);
  172. err = snd_pcm_hw_params_set_rate_near(*capture_handle, hw_params, &rate, 0/*&dir*/);
  173. if (err)
  174. {
  175. printf("Error setting sampling rate (%d): %s\n", rate, snd_strerror(err));
  176. //goto error;
  177. exit(1);
  178. }
  179. printf("Rate = %d\n", rate);
  180. /* Write the parameters to the driver */
  181. err = snd_pcm_hw_params(*capture_handle, hw_params);
  182. if (err < 0)
  183. {
  184. printf( "Unable to set HW parameters: %s\n", snd_strerror(err));
  185. //goto error;
  186. exit(1);
  187. }
  188. err = snd_pcm_prepare(*capture_handle);
  189. printf("Open record device done \n");
  190. //set_sw_params(*capture_handle,bufferSize,periodSize,NULL);
  191. if(hw_params)
  192. snd_pcm_hw_params_free(hw_params);
  193. }
  194. void alsa_fake_device_write_open(snd_pcm_t** write_handle, int channels,
  195. uint32_t write_sampleRate)
  196. {
  197. snd_pcm_hw_params_t *write_params;
  198. snd_pcm_uframes_t write_periodSize = PERIOD_SIZE;
  199. snd_pcm_uframes_t write_bufferSize = BUFFER_SIZE;
  200. int write_err;
  201. int write_dir;
  202. int i = 10;
  203. retry:
  204. write_err = snd_pcm_open(write_handle, WRITE_DEVICE_NAME,
  205. SND_PCM_STREAM_PLAYBACK, 0);
  206. // }
  207. if (write_err) {
  208. usleep(100*1000);
  209. i --;
  210. if(i > 0)
  211. goto retry;
  212. printf( "Unable to open playback PCM device: \n");
  213. exit(1);
  214. }
  215. //printf( "interleaved mode\n");
  216. // snd_pcm_hw_params_alloca(&write_params);
  217. snd_pcm_hw_params_malloc(&write_params);
  218. //printf("snd_pcm_hw_params_alloca\n");
  219. snd_pcm_hw_params_any(*write_handle, write_params);
  220. write_err = snd_pcm_hw_params_set_access(*write_handle, write_params, SND_PCM_ACCESS_RW_INTERLEAVED);
  221. //write_err = snd_pcm_hw_params_set_access(*write_handle, write_params, SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
  222. if (write_err)
  223. {
  224. printf("Error setting interleaved mode\n");
  225. exit(1);
  226. }
  227. //printf( "interleaved mode\n");
  228. write_err = snd_pcm_hw_params_set_format(*write_handle, write_params, ALSA_WRITE_FORMAT);
  229. if (write_err)
  230. {
  231. printf("Error setting format: %s\n", snd_strerror(write_err));
  232. exit(1);
  233. }
  234. //printf( "format successed\n");
  235. write_err = snd_pcm_hw_params_set_channels(*write_handle, write_params, channels);
  236. if (write_err)
  237. {
  238. printf( "Error setting channels: %s\n", snd_strerror(write_err));
  239. exit(1);
  240. }
  241. //printf("channels = %d\n",channels);
  242. write_err = snd_pcm_hw_params_set_rate_near(*write_handle, write_params, &write_sampleRate, 0/*&write_dir*/);
  243. if (write_err)
  244. {
  245. printf("Error setting sampling rate (%d): %s\n", write_sampleRate, snd_strerror(write_err));
  246. exit(1);
  247. }
  248. //printf("setting sampling rate (%d)\n", write_sampleRate);
  249. write_err = snd_pcm_hw_params_set_buffer_size_near(*write_handle, write_params, &write_bufferSize);
  250. if (write_err)
  251. {
  252. printf("Error setting buffer size (%ld): %s\n", write_bufferSize, snd_strerror(write_err));
  253. exit(1);
  254. }
  255. //printf("write_bufferSize = %ld\n",write_bufferSize);
  256. write_err = snd_pcm_hw_params_set_period_size_near(*write_handle, write_params, &write_periodSize, 0);
  257. if (write_err)
  258. {
  259. printf("Error setting period time (%ld): %s\n", write_periodSize, snd_strerror(write_err));
  260. exit(1);
  261. }
  262. //printf("write_periodSize = %ld\n",write_periodSize);
  263. #if 0
  264. snd_pcm_uframes_t write_final_buffer;
  265. write_err = snd_pcm_hw_params_get_buffer_size(write_params, &write_final_buffer);
  266. printf(" final buffer size %ld \n" , write_final_buffer);
  267. snd_pcm_uframes_t write_final_period;
  268. write_err = snd_pcm_hw_params_get_period_size(write_params, &write_final_period, &write_dir);
  269. printf(" final period size %ld \n" , write_final_period);
  270. #endif
  271. /* Write the parameters to the driver */
  272. write_err = snd_pcm_hw_params(*write_handle, write_params);
  273. if (write_err < 0)
  274. {
  275. printf( "Unable to set HW parameters: %s\n", snd_strerror(write_err));
  276. exit(1);
  277. }
  278. write_err = snd_pcm_prepare(*write_handle);
  279. if(DEBUG) printf("open write device is successful\n");
  280. set_sw_params(*write_handle, write_bufferSize, write_periodSize, NULL);
  281. if(write_params)
  282. snd_pcm_hw_params_free(write_params);
  283. }
  284. int set_sw_params(snd_pcm_t *pcm, snd_pcm_uframes_t buffer_size,
  285. snd_pcm_uframes_t period_size, char **msg) {
  286. snd_pcm_sw_params_t *params;
  287. char buf[256];
  288. int err;
  289. //snd_pcm_sw_params_alloca(&params);
  290. snd_pcm_sw_params_malloc(&params);
  291. if ((err = snd_pcm_sw_params_current(pcm, params)) != 0) {
  292. snprintf(buf, sizeof(buf), "Get current params: %s", snd_strerror(err));
  293. //goto fail;
  294. exit(1);
  295. }
  296. /* start the transfer when the buffer is full (or almost full) */
  297. snd_pcm_uframes_t threshold = (buffer_size / period_size) * period_size;
  298. if ((err = snd_pcm_sw_params_set_start_threshold(pcm, params, threshold)) != 0) {
  299. snprintf(buf, sizeof(buf), "Set start threshold: %s: %lu", snd_strerror(err), threshold);
  300. exit(1);
  301. }
  302. /* allow the transfer when at least period_size samples can be processed */
  303. if ((err = snd_pcm_sw_params_set_avail_min(pcm, params, period_size)) != 0) {
  304. snprintf(buf, sizeof(buf), "Set avail min: %s: %lu", snd_strerror(err), period_size);
  305. exit(1);
  306. }
  307. if ((err = snd_pcm_sw_params(pcm, params)) != 0) {
  308. snprintf(buf, sizeof(buf), "%s", snd_strerror(err));
  309. exit(1);
  310. }
  311. if(params)
  312. snd_pcm_sw_params_free(params);
  313. return 0;
  314. }
  315. //修改当前音量
  316. void *control_volume(void *)
  317. {
  318. char cmd[64];
  319. set_volume = true;
  320. volume -= 10;
  321. usleep(1000*1000);
  322. set_volume = false;
  323. return NULL;
  324. }
  325. void get_volume_threshold()
  326. {
  327. dictionary * ini ;
  328. ini = iniparser_load(VOL_CONF);
  329. if (ini==NULL) {
  330. fprintf(stderr, "cannot parse file: %s\n", VOL_CONF);
  331. return;
  332. }
  333. en_threshold = iniparser_getboolean(ini, "volume:enable_threshold", false);
  334. vol_threshold = iniparser_getint(ini, "volume:volume_threshold", -15);
  335. iniparser_freedict(ini);
  336. }
  337. /**
  338. * Generic routine to calculate RMS (Root-Mean-Square) from
  339. * a set of signed 16-bit values
  340. *
  341. * \verbatim
  342. .---------------
  343. | N-1
  344. | ----.
  345. | \
  346. | \ 2
  347. | | s[n]
  348. | /
  349. | /
  350. _ | ----'
  351. \ | n=0
  352. \ | ------------
  353. \| N
  354. \endverbatim
  355. *
  356. * @param data Array of signed 16-bit values
  357. * @param len Number of values
  358. *
  359. * @return RMS value from 0 to 32768
  360. */
  361. static double calc_rms_s16(const int16_t *data, size_t len)
  362. {
  363. int64_t sum = 0;
  364. size_t i;
  365. if (!data || !len)
  366. return .0;
  367. for (i = 0; i < len; i++) {
  368. sum += data[i] * data[i];
  369. }
  370. return sqrt(sum / (double)len);
  371. }
  372. double aout_Aulevel_dbov(const int16_t *sampv, size_t sampc)
  373. {
  374. static const double peak_s16 = 32767.0;
  375. double rms, dbov;
  376. if (!sampv || !sampc)
  377. return 0;
  378. rms = calc_rms_s16(sampv, sampc) / peak_s16;
  379. dbov = 20 * log10(rms);
  380. if (dbov < AULEVEL_MIN)
  381. dbov = AULEVEL_MIN;
  382. else if (dbov > AULEVEL_MAX)
  383. dbov = AULEVEL_MAX;
  384. return dbov;
  385. }
  386. static void *vumeter_decode(void *arg)
  387. {
  388. char redisCmd[128];
  389. int set_idle = false;
  390. vumeter_play *vu_p = (vumeter_play *) arg;
  391. redis_client_t *redisClient = create_redis_client(unix_socket_path);
  392. usleep(100*1000);
  393. while(1)
  394. {
  395. usleep(500*1000);
  396. if(sip_active || mc_active || onvif_active || bc_active)
  397. {
  398. vu_p->ch1_avg_play = aout_Aulevel_dbov(vu_p->ch1_sampv, vu_p->au_sampc);
  399. sprintf(redisCmd, "HSet volume audio_out_ch1 %d", (int) vu_p->ch1_avg_play);
  400. redis_command_safe(redisClient, redisCmd);
  401. vu_p->ch2_avg_play = aout_Aulevel_dbov(vu_p->ch2_sampv, vu_p->au_sampc);
  402. sprintf(redisCmd, "HSet volume audio_out_ch2 %d", (int) vu_p->ch2_avg_play);
  403. redis_command_safe(redisClient, redisCmd);
  404. set_idle = false;
  405. if(DEBUG) printf("vol1: %f, vol2: %f\n", vu_p->ch1_avg_play, vu_p->ch2_avg_play);
  406. }
  407. else if(!set_idle)
  408. {
  409. sprintf(redisCmd, "HSet volume audio_out_ch1 %d", (int) AULEVEL_MIN);
  410. redis_command_safe(redisClient, redisCmd);
  411. sprintf(redisCmd, "HSet volume audio_out_ch2 %d", (int) AULEVEL_MIN);
  412. redis_command_safe(redisClient, redisCmd);
  413. set_idle = true;
  414. }
  415. }
  416. return NULL;
  417. }
  418. //播放状态监控
  419. void ProcessReply( char * pReplyStr )
  420. {
  421. cJSON *pJson = NULL;
  422. if(DEBUG) printf( "Msg [%s]\n", pReplyStr );
  423. pJson = cJSON_Parse(pReplyStr);
  424. if ( pJson ) {
  425. if(strcmp(cJSON_GetObjectItem(pJson, "name")->valuestring, "SIP") == 0)
  426. {
  427. if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "on") == 0)
  428. {
  429. get_volume_threshold();
  430. current_sess = SIP;
  431. sip_active = true;
  432. }
  433. else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "off") == 0)
  434. {
  435. if(ctrl_sess == SIP)
  436. {
  437. volume = 100;
  438. ctrl_sess = IDLE;
  439. }
  440. sip_active = false;
  441. }
  442. }
  443. else if(strcmp(cJSON_GetObjectItem(pJson, "name")->valuestring, "BROADCAST") == 0)
  444. {
  445. if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "on") == 0)
  446. {
  447. get_volume_threshold();
  448. current_sess = BROADCAST;
  449. bc_active = true;
  450. }
  451. else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "off") == 0)
  452. {
  453. if(ctrl_sess == BROADCAST)
  454. {
  455. volume = 100;
  456. ctrl_sess = IDLE;
  457. }
  458. bc_active = false;
  459. }
  460. }
  461. else if(strcmp(cJSON_GetObjectItem(pJson, "name")->valuestring, "MULTICAST") == 0)
  462. {
  463. if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "on") == 0)
  464. {
  465. get_volume_threshold();
  466. current_sess = MULTICAST;
  467. mc_active = true;
  468. }
  469. else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "off") == 0)
  470. {
  471. if(ctrl_sess == MULTICAST)
  472. {
  473. volume = 100;
  474. ctrl_sess = IDLE;
  475. }
  476. mc_active = false;
  477. }
  478. }
  479. else if(strcmp(cJSON_GetObjectItem(pJson, "name")->valuestring, "ONVIF") == 0)
  480. {
  481. if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "on") == 0)
  482. {
  483. get_volume_threshold();
  484. current_sess = ONVIF;
  485. onvif_active = true;
  486. }
  487. else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "off") == 0)
  488. {
  489. if(ctrl_sess == ONVIF)
  490. {
  491. volume = 100;
  492. ctrl_sess = IDLE;
  493. }
  494. onvif_active = false;
  495. }
  496. }
  497. }
  498. if(pJson != NULL) cJSON_Delete(pJson);
  499. }
  500. void *service_status_listen(void *arg)
  501. {
  502. // redisContext * pContext = redisConnect( "127.0.0.1", 6379 );
  503. redisContext * pContext = redisConnectUnix(unix_socket_path);
  504. if ( NULL == pContext || pContext->err == 1 )
  505. {
  506. printf( "%s\n", pContext->errstr );
  507. exit( -1 );
  508. }
  509. void* replyPtr = redisCommand( pContext, "SUBSCRIBE %s", paging_channel );
  510. redisReply* pReply = static_cast<redisReply*>(replyPtr);
  511. freeReplyObject( pReply );
  512. while ( redisGetReply( pContext, (void **)&pReply ) == REDIS_OK )
  513. {
  514. if ( pReply->elements == 3 )
  515. {
  516. redisReply * pSubReply = pReply->element[2];
  517. ProcessReply( pSubReply->str );
  518. }
  519. if(pReply != NULL) freeReplyObject( pReply );
  520. }
  521. redisFree( pContext );
  522. return NULL;
  523. }
  524. void check_volume(int16_t *buffer, int count, vumeter_play *vu)
  525. {
  526. int i;
  527. pthread_t thread;
  528. if(vu->ch1_avg_play > vol_threshold || vu->ch2_avg_play > vol_threshold)
  529. {
  530. for(i=0; i<count; i++)
  531. {
  532. buffer[i*2] = 0x00; //ch1[i]*0.35;
  533. buffer[i*2+1] = 0x00; //ch2[i]*0.35;
  534. }
  535. if(!set_volume)
  536. {
  537. ctrl_sess = current_sess;
  538. pthread_create(&thread, NULL, control_volume, NULL);
  539. pthread_detach(thread);
  540. }
  541. }
  542. }
  543. static float get_volume(int vol)
  544. {
  545. float v = vol / 100.f;
  546. if (v < 0.f)
  547. v = 0.f;
  548. else if (v > 1.f)
  549. v = 1.f;
  550. return v;
  551. }
  552. void vol_uint16(int16_t *data, size_t n)
  553. {
  554. size_t i;
  555. for (i = 0; i < n; i++)
  556. {
  557. data[i*2] = (int16_t) (data[i*2] * get_volume(volume));
  558. data[i*2+1] = (int16_t) (data[i*2+1] * get_volume(volume));
  559. }
  560. }
  561. int main(int argc, char *argv[])
  562. {
  563. snd_pcm_t *capture_handle;
  564. snd_pcm_t *write_handle;
  565. vumeter_play *vu = ( vumeter_play *) malloc (sizeof (*vu));
  566. int err, i;
  567. int16_t buffer[READ_FRAME * 2];
  568. unsigned int sampleRate;
  569. unsigned int channels;
  570. pthread_t service_status_listen_thread, thread;
  571. // pthread_t volume_temp_value_listen_thread;
  572. if(argc == 2 && strcmp(argv[1], "debug") == 0)
  573. DEBUG = true;
  574. repeat:
  575. //capture_handle = NULL;
  576. write_handle = NULL;
  577. err = 0;
  578. memset(buffer, 0, sizeof(buffer));
  579. sampleRate = SAMPLE_RATE;
  580. channels = CHANNEL;
  581. printf("\n==========EQ/DRC process release version 1.23===============\n");
  582. alsa_fake_device_record_open(&capture_handle, channels, sampleRate);
  583. alsa_fake_device_write_open(&write_handle, channels, sampleRate);
  584. vu->ch1_sampv = (int16_t *) malloc(READ_FRAME*2*sizeof(int16_t));
  585. vu->ch2_sampv = (int16_t *) malloc(READ_FRAME*2*sizeof(int16_t));
  586. vu->au_sampc = READ_FRAME;
  587. //RK_acquire_wake_lock(wake_lock);
  588. pthread_create(&thread, NULL, vumeter_decode, vu);
  589. pthread_detach(thread);
  590. pthread_create(&service_status_listen_thread, NULL, service_status_listen, NULL);
  591. pthread_detach(service_status_listen_thread);
  592. while (1) {
  593. err = snd_pcm_readi(capture_handle, buffer , READ_FRAME);
  594. if (err != READ_FRAME)
  595. printf("====read frame error = %d===\n",err);
  596. if (err < 0) {
  597. if (err == -EPIPE)
  598. printf( "Overrun occurred: %d\n", err);
  599. err = snd_pcm_recover(capture_handle, err, 0);
  600. // Still an error, need to exit.
  601. if (err < 0) {
  602. printf( "Error occured while recording: %s\n", snd_strerror(err));
  603. usleep(200 * 1000);
  604. if (capture_handle)
  605. snd_pcm_close(capture_handle);
  606. if (write_handle)
  607. snd_pcm_close(write_handle);
  608. goto repeat;
  609. }
  610. }
  611. if(en_threshold)
  612. {
  613. vol_uint16(buffer, READ_FRAME);
  614. check_volume(buffer, READ_FRAME, vu);
  615. }
  616. for(i=0; i<READ_FRAME; i++)
  617. {
  618. vu->ch1_sampv[i] = buffer[i*2];
  619. vu->ch2_sampv[i] = buffer[i*2+1];
  620. }
  621. err = snd_pcm_writei(write_handle, buffer, READ_FRAME);
  622. if (-EPIPE == err) {
  623. snd_pcm_prepare(write_handle);
  624. err = snd_pcm_writei(write_handle, buffer, READ_FRAME);
  625. if (err < 0) {
  626. printf("alsa: write error: %s\n",
  627. snd_strerror((int) err));
  628. }
  629. }
  630. else if (err < 0) {
  631. printf("alsa: write error: %s\n",
  632. snd_strerror((int) err));
  633. }
  634. else if (err != READ_FRAME) {
  635. printf("alsa: write: wrote %d of %d samples\n",
  636. (int) err, READ_FRAME);
  637. }
  638. }
  639. error:
  640. if (capture_handle)
  641. snd_pcm_close(capture_handle);
  642. if (write_handle)
  643. snd_pcm_close(write_handle);
  644. return 0;
  645. }