linuxrec.cpp
Go to the documentation of this file.
1 #include "linuxrec.h"
2 #include <alsa/asoundlib.h>
3 #include <fcntl.h>
4 #include <file_operation.h>
5 #include <pthread.h>
6 #include <signal.h>
7 #include <sys/stat.h>
8 #include <cmath>
9 #include <cstdio>
10 #include <cstdlib>
11 #include <ctime>
12 #include <fstream>
13 #include "common_config.h"
14 #include "formats.h"
15 #define DBG_ON 1
16 #if DBG_ON
17 #define dbg printf
18 #else
19 #define dbg
20 #endif
21 
22 /* Do not change the sequence */
23 
24 #define SAMPLE_RATE 16000
25 
26 #define SAMPLE_BIT_SIZE 16
27 
28 #define FRAME_CNT 10
29 
30 //#define BUF_COUNT 1
31 
32 #define DEF_BUFF_TIME 500000
33 
34 #define DEF_PERIOD_TIME 100000
35 
36 float VDADetection::levelEnergy(struct DataBuff pcm_data, const int count_sum)
37 {
38  call_count_++;
39  bool is_speech = false;
40  is_speech_count_ = 0;
41  float current_energy = energyPerSample(pcm_data);
42  if (call_count_ <= count_sum)
43  {
44  temp_energy_ += current_energy;
45  }
46  // 每count_sum组数据求一个平均值,根据这个值调整背景噪声能量值
47  if (call_count_ == count_sum)
48  {
49  temp_energy_ += current_energy;
50  mean_energy_ = temp_energy_ / (float)count_sum;
51  temp_energy_ = 0.0;
52  call_count_ = 0;
53  }
54  return mean_energy_;
55 }
56 
58 {
59  float energy = 0;
60  for (int i = 0; i < pcm_data.size; i++)
61  {
62  energy += pcm_data.data[i] * pcm_data.data[i];
63  }
64  energy = 10 * log(energy);
65 
66  return energy;
67 }
68 
69 static int format_ms_to_alsa(const WAVEFORMATEX* wavfmt, snd_pcm_format_t* format)
70 {
71  snd_pcm_format_t tmp;
72  tmp = snd_pcm_build_linear_format(wavfmt->wBitsPerSample, wavfmt->wBitsPerSample, wavfmt->wBitsPerSample == 8 ? 1 : 0,
73  0);
74  if (tmp == SND_PCM_FORMAT_UNKNOWN)
75  return -EINVAL;
76  *format = tmp;
77  return 0;
78 }
79 
81 {
82  record_ = rec;
83  int error_code = 0;
84  //创建一个句柄并打开与声卡号和音频设备号设备的音频接口的连接。成功返回零,失败返回负的错误码。
85  error_code = snd_pcm_open((snd_pcm_t**)&record_->wavein_hdl, dev.u.name, SND_PCM_STREAM_CAPTURE, 0);
86  if (error_code < 0)
87  {
88  std::cout << "unable to open pcm device: " << snd_strerror(error_code) << std::endl;
90  }
91  /* 分配硬件参数对象. */
92  snd_pcm_hw_params_alloca(&params_);
93  handle_ = (snd_pcm_t*)record_->wavein_hdl;
94  /* 用默认值填写. */
95  error_code = snd_pcm_hw_params_any(handle_, params_);
96  if (error_code < 0)
97  {
98  std::cout << "Broken configuration for this PCM: " << snd_strerror(error_code) << std::endl;
100  }
101 
102  /* 设置所需的硬件参数. */
103 
104  error_code = snd_pcm_hw_params_set_access(handle_, params_, SND_PCM_ACCESS_RW_INTERLEAVED);
105  if (error_code < 0)
106  {
107  std::cout << "Access type not available: " << snd_strerror(error_code) << std::endl;
109  }
110 
111  /* 判断定义的wave格式是否正确 */
112  error_code = format_ms_to_alsa(wavfmt, &format_);
113  if (error_code)
114  {
115  std::cout << "Invalid format";
117  }
118  error_code = snd_pcm_hw_params_set_format(handle_, params_, format_);
119  if (error_code < 0)
120  {
121  std::cout << "Sample format not available: " << snd_strerror(error_code) << std::endl;
123  }
124 
125  /* One channels (stereo) */
126  error_code = snd_pcm_hw_params_set_channels(handle_, params_, wavfmt->nChannels);
127  if (error_code < 0)
128  {
129  std::cout << "Channels count not available: " << snd_strerror(error_code) << std::endl;
131  }
132 
133  /* 16000 bits/second sampling rate */
134  record_rate_ = wavfmt->nSamplesPerSec;
135  error_code = snd_pcm_hw_params_set_rate_near(handle_, params_, &record_rate_, 0);
136  if (error_code < 0)
137  {
138  std::cout << "Set rate failed: " << snd_strerror(error_code) << std::endl;
140  }
141 
142  /* 周期长度(帧数). */
143  frames_ = 16;
144  error_code = snd_pcm_hw_params_set_period_size_near(handle_, params_, &frames_, 0);
145  if (error_code < 0)
146  {
147  std::cout << "set period time fail: " << snd_strerror(error_code) << std::endl;
149  }
150 
151  /*将配置写入驱动程序中 */
152  error_code = snd_pcm_hw_params(handle_, params_);
153  if (error_code < 0)
154  {
155  std::cout << "Unable to install hw params: " << snd_strerror(error_code) << std::endl;
157  }
158 
159  error_code = snd_pcm_hw_params_get_period_size(params_, &frames_, 0);
160  if (error_code < 0)
161  {
162  std::cout << "\n get_period_size failed !!!\n" << snd_strerror(error_code) << std::endl;
164  }
165  audiobuf_size_ = frames_ * wavfmt->nChannels * wavfmt->wBitsPerSample / 8;
166  record_->audiobuf = (char*)malloc(audiobuf_size_);
167  if (record_->audiobuf == NULL)
168  {
169  std::cout << "\n Malloc failed in rec->audiobuf !!!\n";
171  }
172 
173  error_code = snd_pcm_hw_params_get_period_time(params_, &record_rate_, 0);
174  if (error_code < 0)
175  {
176  std::cout << "\n get_period_time failed !!!\n" << snd_strerror(error_code) << std::endl;
178  }
179 }
180 // 输入duration_time:单位s
181 int RecordAlsaAPI::setRecordDuration(const float duration_time)
182 {
183  duration_time_ = (int)(duration_time * pow(10, 6));
184  record_loop_ = duration_time_ / record_rate_;
185  return record_loop_;
186 }
187 
189 {
190  int error_code;
191  audio_pcm_ = { NULL, 0 };
192  error_code = snd_pcm_readi(handle_, record_->audiobuf, frames_);
193  if (error_code == -EPIPE)
194  {
195  /* EPIPE means overrun */
196  std::cout << "overrun occurred\n";
197  snd_pcm_prepare(handle_);
198  exit(RECORD_ERROR_OVERRUN);
199  }
200  else if (error_code < 0)
201  {
202  std::cout << "error from read: " << snd_strerror(error_code) << std::endl;
204  }
205  else if (error_code != (int)frames_)
206  {
207  std::cout << "short read, read " << error_code << " frames\n";
209  }
210  audio_pcm_.data = record_->audiobuf;
211  audio_pcm_.size = audiobuf_size_;
212  return audio_pcm_;
213 }
214 
216 {
217  snd_pcm_drop(handle_);
218  snd_pcm_drain(handle_);
219  snd_pcm_close(handle_);
220  handle_ = NULL;
221  free(record_);
222 }
223 
224 static int g_show_xrun = 1;
225 static int startRecordInternal(snd_pcm_t* pcm)
226 {
227  return snd_pcm_start(pcm);
228 }
229 
230 static int stopRecordInternal(snd_pcm_t* pcm)
231 {
232  return snd_pcm_drop(pcm);
233 }
234 
235 static int isStoppedInternal(struct recorder* rec)
236 {
237  snd_pcm_state_t state;
238  state = snd_pcm_state((snd_pcm_t*)rec->wavein_hdl);
239  switch (state)
240  {
241  case SND_PCM_STATE_RUNNING:
242  case SND_PCM_STATE_DRAINING:
243  return 0;
244  default:
245  break;
246  }
247  return 1;
248 }
249 
250 /* set hardware and software params */
251 static int set_hwparams(struct recorder* rec, const WAVEFORMATEX* wavfmt, unsigned int buffertime,
252  unsigned int periodtime)
253 {
254  snd_pcm_hw_params_t* params;
255  int err;
256  unsigned int rate;
257  snd_pcm_format_t format;
258  snd_pcm_uframes_t size;
259  snd_pcm_t* handle = (snd_pcm_t*)rec->wavein_hdl;
260  rec->buffer_time = buffertime;
261  rec->period_time = periodtime;
262  snd_pcm_hw_params_alloca(&params);
263  err = snd_pcm_hw_params_any(handle, params);
264  if (err < 0)
265  {
266  dbg("Broken configuration for this PCM");
267  return err;
268  }
269 
270  err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
271 
272  if (err < 0)
273  {
274  dbg("Access type not available");
275  return err;
276  }
277 
278  err = format_ms_to_alsa(wavfmt, &format);
279 
280  if (err)
281  {
282  dbg("Invalid format");
283  return -EINVAL;
284  }
285 
286  err = snd_pcm_hw_params_set_format(handle, params, format);
287 
288  if (err < 0)
289  {
290  dbg("Sample format non available");
291  return err;
292  }
293 
294  err = snd_pcm_hw_params_set_channels(handle, params, wavfmt->nChannels);
295 
296  if (err < 0)
297  {
298  dbg("Channels count non available");
299  return err;
300  }
301 
302  rate = wavfmt->nSamplesPerSec;
303 
304  err = snd_pcm_hw_params_set_rate_near(handle, params, &rate, 0);
305 
306  if (err < 0)
307  {
308  dbg("Set rate failed");
309  return err;
310  }
311 
312  if (rate != wavfmt->nSamplesPerSec)
313  {
314  dbg("Rate mismatch");
315  return -EINVAL;
316  }
317 
318  if (rec->buffer_time == 0 || rec->period_time == 0)
319  {
320  err = snd_pcm_hw_params_get_buffer_time_max(params, &rec->buffer_time, 0);
321  assert(err >= 0);
322 
323  if (rec->buffer_time > 500000)
324  rec->buffer_time = 500000;
325  rec->period_time = rec->buffer_time / 4;
326  }
327 
328  err = snd_pcm_hw_params_set_period_time_near(handle, params, &rec->period_time, 0);
329  if (err < 0)
330  {
331  dbg("set period time fail");
332  return err;
333  }
334 
335  err = snd_pcm_hw_params_set_buffer_time_near(handle, params, &rec->buffer_time, 0);
336  if (err < 0)
337  {
338  dbg("set buffer time failed");
339  return err;
340  }
341 
342  err = snd_pcm_hw_params_get_period_size(params, &size, 0);
343  if (err < 0)
344  {
345  dbg("get period size fail");
346  return err;
347  }
348 
349  rec->period_frames = size;
350 
351  err = snd_pcm_hw_params_get_buffer_size(params, &size);
352  if (size == rec->period_frames)
353  {
354  dbg("Can't use period equal to buffer size (%lu == %lu)", size, rec->period_frames);
355  return -EINVAL;
356  }
357 
358  rec->buffer_frames = size;
359  rec->bits_per_frame = wavfmt->wBitsPerSample;
360 
361  /* set to driver */
362  err = snd_pcm_hw_params(handle, params);
363  if (err < 0)
364  {
365  dbg("Unable to install hw params:");
366  return err;
367  }
368  return 0;
369 }
370 
371 static int set_swparams(struct recorder* rec)
372 {
373  int err;
374  snd_pcm_sw_params_t* swparams;
375  snd_pcm_t* handle = (snd_pcm_t*)(rec->wavein_hdl);
376 
377  /* sw para */
378  snd_pcm_sw_params_alloca(&swparams);
379  err = snd_pcm_sw_params_current(handle, swparams);
380  if (err < 0)
381  {
382  dbg("get current sw para fail");
383  return err;
384  }
385 
386  err = snd_pcm_sw_params_set_avail_min(handle, swparams, rec->period_frames);
387  if (err < 0)
388  {
389  dbg("set avail min failed");
390  return err;
391  }
392 
393  /* set a value bigger than the buffer frames to prevent the auto start.
394  * we use the snd_pcm_start to explicit start the pcm */
395 
396  err = snd_pcm_sw_params_set_start_threshold(handle, swparams, rec->buffer_frames * 2);
397 
398  if (err < 0)
399  {
400  dbg("set start threshold fail");
401  return err;
402  }
403 
404  if ((err = snd_pcm_sw_params(handle, swparams)) < 0)
405  {
406  dbg("unable to install sw params:");
407  return err;
408  }
409 
410  return 0;
411 }
412 
413 static int set_params(struct recorder* rec, WAVEFORMATEX* fmt, unsigned int buffertime, unsigned int periodtime)
414 {
415  int err;
416  WAVEFORMATEX defmt = { WAVE_FORMAT_PCM, 1, 16000, 32000, 2, 16, sizeof(WAVEFORMATEX) };
417 
418  if (fmt == NULL)
419  {
420  fmt = &defmt;
421  }
422 
423  err = set_hwparams(rec, fmt, buffertime, periodtime);
424 
425  if (err)
426  return err;
427 
428  err = set_swparams(rec);
429 
430  if (err)
431  return err;
432 
433  return 0;
434 }
435 
436 /*
437 
438  * Underrun and suspend recovery
439 
440  */
441 
442 static int xrun_recovery(snd_pcm_t* handle, int err)
443 {
444  if (err == -EPIPE)
445  { /* over-run */
446  if (g_show_xrun)
447  dbg("!!!!!!overrun happend!!!!!!");
448  err = snd_pcm_prepare(handle);
449  if (err < 0)
450  {
451  if (g_show_xrun)
452  dbg("Can't recovery from overrun,"
453  "prepare failed: %s\n",
454  snd_strerror(err));
455  return err;
456  }
457  return 0;
458  }
459  else if (err == -ESTRPIPE)
460  {
461  while ((err = snd_pcm_resume(handle)) == -EAGAIN)
462  usleep(200000); /* wait until the suspend flag is released */
463  if (err < 0)
464  {
465  err = snd_pcm_prepare(handle);
466  if (err < 0)
467  {
468  if (g_show_xrun)
469  dbg("Can't recovery from suspend,"
470  "prepare failed: %s\n",
471  snd_strerror(err));
472  return err;
473  }
474  }
475  return 0;
476  }
477  return err;
478 }
479 
480 static ssize_t pcm_read(struct recorder* rec, size_t rcount)
481 {
482  ssize_t r;
483  size_t count = rcount;
484  char* data;
485 
486  snd_pcm_t* handle = (snd_pcm_t*)rec->wavein_hdl;
487 
488  if (!handle)
489  return -EINVAL;
490 
491  data = rec->audiobuf;
492 
493  while (count > 0)
494  {
495  r = snd_pcm_readi(handle, data, count);
496  if (r == -EAGAIN || (r >= 0 && (size_t)r < count))
497  {
498  snd_pcm_wait(handle, 100);
499  }
500  else if (r < 0)
501  {
502  if (xrun_recovery(handle, r) < 0)
503  {
504  return -1;
505  }
506  }
507  if (r > 0)
508  {
509  count -= r;
510  data += r * rec->bits_per_frame / 8;
511  }
512  }
513 
514  return rcount;
515 }
516 
517 static void* recordThreadProc(void* para)
518 {
519  struct recorder* rec = (struct recorder*)para;
520  size_t frames, bytes;
521  sigset_t mask, oldmask;
522 
523  sigemptyset(&mask);
524  sigaddset(&mask, SIGINT);
525  sigaddset(&mask, SIGTERM);
526  pthread_sigmask(SIG_BLOCK, &mask, &oldmask);
527 
528  // 当语音识别结束需要释放资源关闭录音设备的时候(closeRecorder()),跳出循环。
529  while (true)
530  {
531  frames = rec->period_frames;
532  bytes = frames * rec->bits_per_frame / 8;
533  /* closing, exit the thread */
534  if (rec->state == RECORD_STATE_CLOSING)
535  {
536  std::cout << "RECORD_STATE_CLOSING and break!!!\n";
537  break;
538  }
539  if (rec->state < RECORD_STATE_RECORDING)
540  {
541  std::cout << "rec->state < RECORD_STATE_RECORDING and usleep!!!\n";
542  usleep(100000);
543  }
544  if (pcm_read(rec, frames) != frames)
545  {
546  return NULL;
547  }
548  if (rec->on_data_ind)
549  {
550  rec->on_data_ind(rec->audiobuf, bytes, rec->user_cb_para);
551  }
552  }
553  return rec;
554 }
555 
556 static int createRecordThread(void* para, pthread_t* tidp, std::string base_path)
557 {
558  int err;
559  struct recorder* rec = (struct recorder*)para;
560  rec->pcm_file_path = base_path;
561  err = pthread_create(tidp, NULL, recordThreadProc, (void*)rec);
562 
563  if (err != 0)
564  return err;
565  return 0;
566 }
567 
568 static void free_rec_buffer(struct recorder* rec)
569 {
570  if (rec->audiobuf)
571  {
572  free(rec->audiobuf);
573  rec->audiobuf = NULL;
574  }
575 }
576 
577 static int prepareRecBuffer(struct recorder* rec)
578 {
579  /* the read and QISRWrite is blocked, currently only support one buffer,
580  * if overrun too much, need more buffer and another new thread
581  * to write the audio to network */
582  size_t sz = (rec->period_frames * rec->bits_per_frame / 8);
583  rec->audiobuf = (char*)malloc(sz);
584  if (!rec->audiobuf)
585  return -ENOMEM;
586  return 0;
587 }
588 
589 static int openRecorderInternal(struct recorder* rec, record_dev_id dev, WAVEFORMATEX* fmt, std::string base_path)
590 {
591  int err = 0;
592  err = snd_pcm_open((snd_pcm_t**)&rec->wavein_hdl, dev.u.name, SND_PCM_STREAM_CAPTURE, 0);
593  if (err < 0)
594  goto fail;
595 
596  err = set_params(rec, fmt, DEF_BUFF_TIME, DEF_PERIOD_TIME);
597  if (err)
598  goto fail;
599  assert(rec->bufheader == NULL);
600 
601  err = prepareRecBuffer(rec);
602  if (err)
603  goto fail;
604 
605  err = createRecordThread((void*)rec, &rec->rec_thread, base_path);
606  if (err)
607  goto fail;
608 
609  return 0;
610 
611 fail:
612  if (rec->wavein_hdl)
613  snd_pcm_close((snd_pcm_t*)rec->wavein_hdl);
614  rec->wavein_hdl = NULL;
615 
616  free_rec_buffer(rec);
617 
618  return err;
619 }
620 
621 static void closeRecorderInternal(struct recorder* rec)
622 {
623  snd_pcm_t* handle;
624  handle = (snd_pcm_t*)rec->wavein_hdl;
625  /* may be the thread is blocked at read, cancel it */
626  pthread_cancel(rec->rec_thread);
627 
628  /* wait for the pcm thread quit first */
629  pthread_join(rec->rec_thread, NULL);
630  if (handle)
631  {
632  snd_pcm_close(handle);
633  rec->wavein_hdl = NULL;
634  }
635 
636  free_rec_buffer(rec);
637 }
638 
639 /* return the count of pcm device */
640 
641 /* list all cards */
642 
643 static int getPcmDeviceCount(snd_pcm_stream_t stream)
644 {
645  void **hints, **n;
646  char *io, *filter, *name;
647 
648  int cnt = 0;
649  if (snd_device_name_hint(-1, "pcm", &hints) < 0)
650  return 0;
651 
652  n = hints;
653  filter = stream == SND_PCM_STREAM_CAPTURE ? (char*)"Input" : (char*)"Output";
654  while (*n != NULL)
655  {
656  io = snd_device_name_get_hint(*n, "IOID");
657  name = snd_device_name_get_hint(*n, "NAME");
658  if (name && (io == NULL || strcmp(io, filter) == 0))
659  cnt++;
660 
661  if (io != NULL)
662  free(io);
663 
664  if (name != NULL)
665  free(name);
666  n++;
667  }
668  snd_device_name_free_hint(hints);
669  return cnt;
670 }
671 
672 /* -------------------------------------
673 
674  * Interfaces
675 
676  --------------------------------------*/
677 
678 /* the device id is a pcm string name in linux */
679 
681 {
682  record_dev_id id;
683  id.u.name = (char*)"default";
684  return id;
685 }
686 
688 {
689  // TODO: unimplemented
690  return NULL;
691 }
692 
694 {
695  return getPcmDeviceCount(SND_PCM_STREAM_CAPTURE);
696 }
697 
698 /* callback will be run on a new thread */
699 int createRecorder(struct recorder** out_rec, void (*on_data_ind)(char* data, unsigned long len, void* user_cb_para),
700  void* user_cb_para)
701 {
702  struct recorder* myrec;
703  myrec = (struct recorder*)malloc(sizeof(struct recorder));
704 
705  if (!myrec)
707 
708  memset(myrec, 0, sizeof(struct recorder));
709  myrec->on_data_ind = on_data_ind;
710  myrec->user_cb_para = user_cb_para;
711  myrec->state = RECORD_STATE_CREATED;
712 
713  *out_rec = myrec;
714  return RECORD_SUCCESS;
715 }
716 
717 void destroyRecorder(struct recorder* rec)
718 {
719  if (!rec)
720  return;
721  free(rec);
722 }
723 
724 int openRecorder(struct recorder* rec, record_dev_id dev, WAVEFORMATEX* fmt, std::string base_path)
725 {
726  std::cout << "rec->state is : " << rec->state << std::endl;
727  int ret = 0;
728  if (!rec)
729  return -RECORD_ERROR_INVAL;
730  if (rec->state >= RECORD_STATE_READY)
731  return RECORD_SUCCESS;
732  ret = openRecorderInternal(rec, dev, fmt, base_path);
733  if (ret == 0)
734  rec->state = RECORD_STATE_READY;
735  return RECORD_SUCCESS;
736 }
737 
738 void closeRecorder(struct recorder* rec)
739 {
740  if (rec == NULL || rec->state < RECORD_STATE_READY)
741  return;
742  if (rec->state == RECORD_STATE_RECORDING)
743  stopRecord(rec);
747 }
748 
749 int startRecord(struct recorder* rec)
750 {
751  int ret;
752  if (rec == NULL)
753  return -RECORD_ERROR_INVAL;
754  if (rec->state < RECORD_STATE_READY)
755  return -RECORD_ERROR_NOT_READY;
756 
757  if (rec->state == RECORD_STATE_RECORDING)
758  return 0;
759  ret = startRecordInternal((snd_pcm_t*)rec->wavein_hdl);
760 
761  if (ret == 0)
763  return ret;
764 }
765 
766 int stopRecord(struct recorder* rec)
767 {
768  int ret;
769  if (rec == NULL)
770  return -RECORD_ERROR_INVAL;
771 
772  if (rec->state < RECORD_STATE_RECORDING)
773  return 0;
774 
776  ret = stopRecordInternal((snd_pcm_t*)rec->wavein_hdl);
777 
778  if (ret == 0)
779  {
780  rec->state = RECORD_STATE_READY;
781  }
782 
783  return ret;
784 }
785 
786 int isRecordStopped(struct recorder* rec)
787 {
788  if (rec->state == RECORD_STATE_RECORDING)
789  return 0;
790  return isStoppedInternal(rec);
791 }
static ssize_t pcm_read(struct recorder *rec, size_t rcount)
Definition: linuxrec.cpp:480
static int getPcmDeviceCount(snd_pcm_stream_t stream)
Definition: linuxrec.cpp:643
int isRecordStopped(struct recorder *rec)
Definition: linuxrec.cpp:786
static int g_show_xrun
Definition: linuxrec.cpp:224
void * bufheader
Definition: linuxrec.h:52
static int stopRecordInternal(snd_pcm_t *pcm)
Definition: linuxrec.cpp:230
volatile int state
Definition: linuxrec.h:46
unsigned short wBitsPerSample
Definition: formats.h:15
void closeRecord()
Definition: linuxrec.cpp:215
static int openRecorderInternal(struct recorder *rec, record_dev_id dev, WAVEFORMATEX *fmt, std::string base_path)
Definition: linuxrec.cpp:589
static int format_ms_to_alsa(const WAVEFORMATEX *wavfmt, snd_pcm_format_t *format)
Definition: linuxrec.cpp:69
int getInputDeviceNum()
Definition: linuxrec.cpp:693
static int set_swparams(struct recorder *rec)
Definition: linuxrec.cpp:371
static void * recordThreadProc(void *para)
Definition: linuxrec.cpp:517
unsigned int nSamplesPerSec
Definition: formats.h:12
char * audiobuf
Definition: linuxrec.h:54
#define DEF_BUFF_TIME
Definition: linuxrec.cpp:32
float energyPerSample(struct DataBuff pcm_data)
Definition: linuxrec.cpp:57
void * wavein_hdl
Definition: linuxrec.h:47
#define DEF_PERIOD_TIME
Definition: linuxrec.cpp:34
size_t buffer_frames
Definition: linuxrec.h:59
static int isStoppedInternal(struct recorder *rec)
Definition: linuxrec.cpp:235
int createRecorder(struct recorder **out_rec, void(*on_data_ind)(char *data, unsigned long len, void *user_cb_para), void *user_cb_para)
Definition: linuxrec.cpp:699
int setRecordDuration(const float duration_time)
Definition: linuxrec.cpp:181
static void free_rec_buffer(struct recorder *rec)
Definition: linuxrec.cpp:568
static int startRecordInternal(snd_pcm_t *pcm)
Definition: linuxrec.cpp:225
unsigned int period_time
Definition: linuxrec.h:57
record_dev_id * listInputDevice()
Definition: linuxrec.cpp:687
void * user_cb_para
Definition: linuxrec.h:45
static int set_params(struct recorder *rec, WAVEFORMATEX *fmt, unsigned int buffertime, unsigned int periodtime)
Definition: linuxrec.cpp:413
void initRecord(struct recorder *rec, record_dev_id dev, WAVEFORMATEX *fmt)
Definition: linuxrec.cpp:80
char * data
Definition: file_operation.h:8
float levelEnergy(struct DataBuff pcm_data, const int call_count)
Definition: linuxrec.cpp:36
static void closeRecorderInternal(struct recorder *rec)
Definition: linuxrec.cpp:621
int openRecorder(struct recorder *rec, record_dev_id dev, WAVEFORMATEX *fmt, std::string base_path)
Definition: linuxrec.cpp:724
union record_dev_id::@9 u
const std::string base_path
int is_speech_count_
Definition: linuxrec.h:102
void closeRecorder(struct recorder *rec)
Definition: linuxrec.cpp:738
int startRecord(struct recorder *rec)
Definition: linuxrec.cpp:749
void destroyRecorder(struct recorder *rec)
Definition: linuxrec.cpp:717
static int createRecordThread(void *para, pthread_t *tidp, std::string base_path)
Definition: linuxrec.cpp:556
int call_count_
Definition: linuxrec.h:95
pthread_t rec_thread
Definition: linuxrec.h:50
int stopRecord(struct recorder *rec)
Definition: linuxrec.cpp:766
static int set_hwparams(struct recorder *rec, const WAVEFORMATEX *wavfmt, unsigned int buffertime, unsigned int periodtime)
Definition: linuxrec.cpp:251
int bits_per_frame
Definition: linuxrec.h:55
#define WAVE_FORMAT_PCM
Definition: formats.h:5
struct tWAVEFORMATEX WAVEFORMATEX
unsigned short nChannels
Definition: formats.h:11
char * name
Definition: linuxrec.h:35
float mean_energy_
Definition: linuxrec.h:98
void(* on_data_ind)(char *data, unsigned long len, void *user_para)
Definition: linuxrec.h:44
static int prepareRecBuffer(struct recorder *rec)
Definition: linuxrec.cpp:577
#define dbg
Definition: linuxrec.cpp:17
record_dev_id getDefaultInputDevice()
Definition: linuxrec.cpp:680
float temp_energy_
Definition: linuxrec.h:97
std::string pcm_file_path
Definition: linuxrec.h:60
static int xrun_recovery(snd_pcm_t *handle, int err)
Definition: linuxrec.cpp:442
unsigned int buffer_time
Definition: linuxrec.h:56
size_t period_frames
Definition: linuxrec.h:58


xbot_talker
Author(s): wangxiaoyun
autogenerated on Sat Oct 10 2020 03:27:53