From 66a7be5e7bb440769250e4186ccff84fef0e1b74 Mon Sep 17 00:00:00 2001 From: wangzijiao Date: Wed, 15 Aug 2018 20:45:00 +0800 Subject: [PATCH] add && fix voice capture, add record wave,raw orig data and final data; add adc codec voice capture; format combine dmic and adc; --- package/netease/netease_voice/src/base.c | 8 + .../netease/netease_voice/src/include/base.h | 7 + .../netease_voice/src/include/record.h | 8 +- package/netease/netease_voice/src/main.c | 245 +++++++++----- package/netease/netease_voice/src/nduilite.c | 5 +- package/netease/netease_voice/src/record.c | 307 ++++++++++++++++-- 6 files changed, 455 insertions(+), 125 deletions(-) diff --git a/package/netease/netease_voice/src/base.c b/package/netease/netease_voice/src/base.c index f8fcc048a..ef3d97b16 100644 --- a/package/netease/netease_voice/src/base.c +++ b/package/netease/netease_voice/src/base.c @@ -57,10 +57,18 @@ static int voice_major; static int voice_status; static double voice_confidence; static VoiceSessionStatus vss = VoiceSession_Init; +static WorkMode wm = WorkMode_R311_PV1; /* ------------------------------------------------------------------------ ** Function Definitions ** ------------------------------------------------------------------------ */ +void setWorkMode(WorkMode mode) { + wm = mode; +} + +WorkMode getWorkMode() { + return wm; +} void setVss(VoiceSessionStatus st) { vss = st; } VoiceSessionStatus getVss() { return vss; } diff --git a/package/netease/netease_voice/src/include/base.h b/package/netease/netease_voice/src/include/base.h index 94dc2a782..ee92ef654 100644 --- a/package/netease/netease_voice/src/include/base.h +++ b/package/netease/netease_voice/src/include/base.h @@ -57,6 +57,10 @@ typedef enum { VoiceSession_Created = 2 } VoiceSessionStatus; +typedef enum { + WorkMode_R311_PV1 = 0 +} WorkMode; + void setVss(VoiceSessionStatus st); VoiceSessionStatus getVss(); @@ -92,6 +96,9 @@ void setVoiceConfidence(double voiceConfidence); double getVoiceConfidence(); void resetAdc(); +void setWorkMode(WorkMode mode); +WorkMode getWorkMode(); + #ifdef __cplusplus } /* extern "C" */ #endif /* C++ */ diff --git a/package/netease/netease_voice/src/include/record.h b/package/netease/netease_voice/src/include/record.h index ee3548456..79642afa3 100644 --- a/package/netease/netease_voice/src/include/record.h +++ b/package/netease/netease_voice/src/include/record.h @@ -47,7 +47,9 @@ typedef struct _RecordData{ pthread_t tid_queue_read; int runing; int backupfilefd; + int finalfilefd; struct pcm_config *pcm_cfg; + struct pcm_config *adc; size_t significant_bits_per_sample; size_t bits_per_sample; size_t bits_per_frame; @@ -61,7 +63,6 @@ typedef struct _RecordData{ size_t buffer_frames; size_t period_frames; - snd_output_t *log; }RecordData; struct pcm_config { @@ -72,14 +73,17 @@ struct pcm_config { unsigned int period_count; record_audio_fn audio_cb; RecordData *recordata; + RecordData *adc; char *format; char *backupfilename; + char *finalfilename; int backupfile_waveformat; }; int Neteasae_record_start(struct pcm_config *pcm_cfg); void Netease_record_stop(struct pcm_config *pcm_cfg); - +void device_list(void); +void pcm_list(void); #ifdef __cplusplus } /* extern "C" */ diff --git a/package/netease/netease_voice/src/main.c b/package/netease/netease_voice/src/main.c index 8fe27d5a9..e4ee4f324 100644 --- a/package/netease/netease_voice/src/main.c +++ b/package/netease/netease_voice/src/main.c @@ -29,10 +29,12 @@ when who why #include "srcwsapi.h" #include "uvdbus/smart_sound.h" #include "yunxin.h" +#include #include #include #include #include +#include #include #include @@ -46,21 +48,10 @@ when who why /* ------------------------------------------------------------------------ ** Macros ** ------------------------------------------------------------------------ */ -//#define BACKUP_ORIG_AUDIO -#define BACKUP_FINAL_AUDIO /* ------------------------------------------------------------------------ ** Defines ** ------------------------------------------------------------------------ */ -#ifdef BACKUP_ORIG_AUDIO -#define ORIG_AUDIO_FILENAME "/mnt/UDISK/origaudio.pcm" -static int fd_audio_orig; -char *BACKUP_PATH; -#endif - -#ifdef BACKUP_FINAL_AUDIO -static int fd_audio_final; -#endif //#define ENABLE_OEM_DBUS @@ -75,6 +66,7 @@ static int fd_audio_final; ** ------------------------------------------------------------------------ */ // unsigned int g_bIsUsedTestServer; static int in_aborting = 0; +static int justrecord = 0; /* ------------------------------------------------------------------------ ** Functions ** ------------------------------------------------------------------------ */ @@ -88,10 +80,26 @@ const char *g_fmaeCfgPath = "/usr/share/fmae_res/config.ini"; CAEDATA *caeconfig = NULL; #endif -struct pcm_config recordconfig; +struct pcm_config recordconfig = {0}; struct audio_bypass *audiobypassconfig = NULL; static char been_wakedup = 0; +static long parse_long(const char *str, int *err) +{ + long val; + char *endptr; + + errno = 0; + val = strtol(str, &endptr, 0); + + if (errno != 0 || *endptr != '\0') + *err = -1; + else + *err = 0; + + return val; +} + #if USED_NETEASE_DC static struct kfifo g_AudioCacheBuf; // static DECLARE_KFIFO(g_AudioCacheBuf, unsigned char, WAKE_CACHE_DATA_SIZE); @@ -226,17 +234,9 @@ int Duilite_beforming_cb(void *userdata, int type, char *msg, int len) { size_t hasWritten; if (type == DUILITE_MSG_TYPE_BINARY) { -#ifdef BACKUP_FINAL_AUDIO - fd = open("/tmp/finalaudio", O_CREAT | O_APPEND | O_RDWR); - if (fd > 0) { - hasWritten = write(fd, msg, len); - close(fd); - - n_debug("Has written:%d\n", hasWritten); - } else { - n_error("open file(%s) error: %d", "/tmp/finalaudio", fd); + if (recordconfig.recordata && recordconfig.recordata->finalfilefd > 0) { + write(recordconfig.recordata->finalfilefd, msg, len); } -#endif if (!!audiobypassconfig) { Netease_audiobypass_write(audiobypassconfig, msg, len); } @@ -283,9 +283,6 @@ static void CAEAudioCb(const void *audioData, unsigned int audioLen, int param1, static void record_audio_cb(const void *audio, unsigned int audio_len, int err_code) { unsigned long long cachetime; -#ifdef BACKUP_ORIG_AUDIO - return; -#endif #ifdef DEBUG_WASTE_TIME Netease_caltime(&cachetime, 1); @@ -509,46 +506,153 @@ void LogFunc(int logLevel, const char *log, void *userData) { IHW_LogRawString(logLevel, (char *)log); } -static void signal_handler(int sig) -{ - if (in_aborting) - return; +static void signal_handler(int sig) { + if (in_aborting) + return; - in_aborting = 1; + in_aborting = 1; n_debug("Aborted by signal:%d, %s\n", sig, strsignal(sig)); Netease_record_stop(&recordconfig); - signal(sig, SIG_DFL); + signal(sig, SIG_DFL); } +static void usage() { + printf( + "Usage:\n" + "-h, --help help\n" + "-l, --list-devices list all soundcards and digital audio " + "devices\n" + "-L, --list-pcms list device names\n" + "-w, --work-mode=# work mode: 0: r311_pv1\n" + "-f, --list-format list all format in alsa\n" + "-r, --just-record Only record voice to file\n" + "-t, --type=# sample format (case insensitive): raw,wav\n" + "--rawfile=# record raw data to filepath\n" + "--finalfile=# record duilite output to filepath\n"); +} +enum { + OPT_RAW_FILE = 1, + OPT_FINAL_FILE +}; + void main(int argc, char **argv) { - int ret; + int ret, c, option_index, err,tmp; + char *rawfile = "/dev/null"; + char *finalfile = "/dev/null"; + static const char short_options[] = "hlt:w:Lfr"; + static const struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"list-devices", 0, 0, 'l'}, + {"list-pcms", 0, 0, 'L'}, + {"list-format", 0, 0, 'f'}, + {"just-record", 0, 0, 'r'}, + {"rawfile", 1, 0, OPT_RAW_FILE}, + {"finalfile", 1, 0, OPT_FINAL_FILE}, + {"type", 1, 0, 't'}, + {"work-mode", 1, 0, 'w'}, + {0, 0, 0, 0}}; -#ifdef BOARD_DMIC - unsigned int channels = 8; - unsigned int rate = 16000; - unsigned int card = 1; - unsigned int device = 0; -#else - unsigned int card = 2; - unsigned int device = 0; - unsigned int channels = 2; - unsigned int rate = 96000; -#endif - // unsigned int frames; - unsigned int period_size = 1535; - unsigned int period_count = 4; + recordconfig.backupfile_waveformat = 1; + recordconfig.audio_cb = record_audio_cb; + setWorkMode(WorkMode_R311_PV1); - char sound_device_name[30]; + if (argc == 1) { + printf("Not enough arg!\n"); + usage(); + return; + } + + while ((c = getopt_long(argc, argv, short_options, long_options, + &option_index)) != -1) { + switch (c) { + case 'h': + usage(); + return; + + case 'l': + device_list(); + return; + + case 'L': + pcm_list(); + return; + + case 'r': + justrecord = 1; + break; + + case 't': + if (strcasecmp(optarg, "wav") == 0) { + recordconfig.backupfile_waveformat = 1; + } else if (strcasecmp(optarg, "raw") == 0) { + recordconfig.backupfile_waveformat = 0; + } + printf("Wave format:%d\n", recordconfig.backupfile_waveformat); + break; + + case 'w': + tmp = parse_long(optarg, &err); + if (err < 0) { + printf("invalid work mode!%s\n", optarg); + return; + } else { + setWorkMode((WorkMode)tmp); + } + break; + + case OPT_RAW_FILE: + rawfile = optarg; + printf("Raw file:%s\n", optarg); + break; + + case OPT_FINAL_FILE: + finalfile = optarg; + printf("Final file:%s\n", optarg); + break; + + default: + printf("Unknow cmd!(%d)\n", c); + usage(); + exit(0); + } + } + printf("parse arg end!\n"); signal(SIGINT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGABRT, signal_handler); + signal(SIGTERM, signal_handler); + signal(SIGABRT, signal_handler); + // Base module init + BaseInit(); + + printf("Work mode:%d\n", getWorkMode()); + + // resetAdc(); + + if (justrecord == 1) { + if (rawfile == NULL && finalfile == NULL) { + printf("Must input rawfile or finalfile!\n"); + return; + } + if (rawfile != NULL) { + recordconfig.backupfilename = rawfile; + printf("Will record raw to file:%s\n", rawfile); + } + if (finalfile != NULL) { + recordconfig.finalfilename = finalfile; + printf("Will record final data to file:%s\n", finalfile); + } + + recordconfig.audio_cb = NULL; + Neteasae_record_start(&recordconfig); + while (1) + usleep(1000000); + } #ifdef ENABLE_OEM_DBUS ret = Netease_dbus_oem_init(DBusMessageCb); #else - // ret = Netease_Dbus_Init(DBusMessageCb); + ret = Netease_Dbus_Init(DBusMessageCb); #endif if (NETEASE_SUCCESS == ret) { n_debug("Dbus init success\n"); @@ -579,39 +683,6 @@ void main(int argc, char **argv) { } #endif - snprintf(sound_device_name, sizeof(sound_device_name), "hw:%u,%u", card, - device); - - recordconfig.device_name = sound_device_name; - recordconfig.channels = channels; - recordconfig.rate = rate; - recordconfig.period_size = period_size; - recordconfig.period_count = period_count; - recordconfig.audio_cb = record_audio_cb; - recordconfig.format = "S16_LE"; - recordconfig.backupfilename = NULL; - recordconfig.backupfile_waveformat = 0; - // todo write something - printf("++++++++++++++++++++++++++\n"); - printf("device name is %s\n", recordconfig.device_name); - printf("Channle is %d\n", recordconfig.channels); - printf("rate name is %d\n", recordconfig.rate); - printf("period_size name is %d\n", recordconfig.period_size); - printf("++++++++++++++++++++++++++\n"); - n_debug("Begin to init netease_voice modules!\n"); - - resetAdc(); -#ifdef BACKUP_ORIG_AUDIO - recordconfig.audio_cb = NULL; - recordconfig.backupfilename = argv[1]; - Neteasae_record_start(&recordconfig); - while (1) - usleep(1000000); -#endif - - // Base module init - BaseInit(); - #if USED_NETEASE_FMAE ret = Netease_audiobypass_init(&audiobypassconfig, NULL, AUDIO_BYPASS_CHANNEL_MSC_IAT); @@ -696,12 +767,12 @@ void main(int argc, char **argv) { #ifdef ENABLE_OEM_DBUS pthread_create(&tid, NULL, Netease_dbus_oem_start, NULL); #else - // pthread_create(&tid, NULL, Netease_Dbus_Start_Sync, NULL); + pthread_create(&tid, NULL, Netease_Dbus_Start_Sync, NULL); #endif // Netease_yunxin_test(); - #if 1 - while (1) { +#if 0 + while (1) { if (1 == Netease_nduilite_init(Duilite_wakeup_cb, Duilite_doa_cb, Duilite_beforming_cb, Duilite_vad_cb)) { n_toast("Nduilite init success, exit!\n"); @@ -715,7 +786,7 @@ void main(int argc, char **argv) { while (1) usleep(1000000); - #endif +#endif while (1) { if (strlen(getUuid()) == 0 || strlen(getYxToken()) == 0) { diff --git a/package/netease/netease_voice/src/nduilite.c b/package/netease/netease_voice/src/nduilite.c index aff743bad..de08fe703 100644 --- a/package/netease/netease_voice/src/nduilite.c +++ b/package/netease/netease_voice/src/nduilite.c @@ -395,11 +395,10 @@ void Netease_nduilite_writeaudio(const void *audioData, return; } -#ifdef BOARD_DMIC //n_debug("Write nduilite data, len:%d\n", audio_len); - Dmic_data_convert(audioData, audio_len); ret = duilite_fespa_feed(fespa, audioData, audio_len); -#else + +#if 0 newbuf = (char *)malloc(audio_len + 60); if (newbuf == NULL) { diff --git a/package/netease/netease_voice/src/record.c b/package/netease/netease_voice/src/record.c index 4fe35b4ed..6d8ae5db2 100644 --- a/package/netease/netease_voice/src/record.c +++ b/package/netease/netease_voice/src/record.c @@ -28,6 +28,7 @@ when who why #include #include +#include "base.h" #include "formats.h" #include "record.h" @@ -44,7 +45,7 @@ when who why #define ALSA_PCM_NEW_HW_PARAMS_API #define AUDIO_QUEUE_BUFF_LEN (1024 * 10) -#define QUEUE_BUFF_MULTIPLE 500 +#define QUEUE_BUFF_MULTIPLE 100 /* ------------------------------------------------------------------------ ** Types @@ -67,6 +68,7 @@ static Proc_CAESetShowLog api_cae_set_show_log; static Proc_CAEDestroy api_cae_destroy; static off64_t fdcount = 0; +static snd_output_t *sndlog; /* ------------------------------------------------------------------------ ** Function Definitions @@ -80,6 +82,7 @@ void _record_stop(void *record_hd); static void end_wave(int fd); static void begin_wave(RecordData *record, int fd, size_t cnt); void _record_stop(void *record_hd); +static int init_params(struct pcm_config *pcm_cfg, int init_queue); /* * make sure we write all bytes or return an error @@ -312,33 +315,98 @@ static void begin_wave(RecordData *record, int fd, size_t cnt) { static void *RecordThread(void *param) { RecordData *record = (RecordData *)param; int ret = 0; + int i = 0; long long max_file_size = 2147483648LL; // cpu_set_t mask; n_toast("RecordThread record:%p, running:%d\n", record, record->runing); + n_toast("record->pcm_cfg:%p\n", record->pcm_cfg); + n_toast("record->pcm_cfg->adc:%p\n", record->pcm_cfg->adc); // CPU_ZERO(&mask); // CPU_SET(0,&mask); // ret = sched_setaffinity(0, sizeof(mask), &mask); // printf("sched_setaffinity return = %d\n", ret); - if (record->backupfilefd > 0 && record->pcm_cfg->backupfile_waveformat > 0) { + if (record->backupfilefd > 0 && + record->pcm_cfg->backupfile_waveformat > 0) { begin_wave(record, record->backupfilefd, (size_t)max_file_size); fdcount = 0; } + if (record->finalfilefd > 0 && record->pcm_cfg->backupfile_waveformat > 0) { + begin_wave(record, record->backupfilefd, (size_t)max_file_size); + } while (!!record->runing) { - if (pcm_read(record) == record->chunk_size) { - if (record->backupfilefd > 0) { - xwrite(record->backupfilefd, record->buffer, - record->chunk_bytes); - fdcount += record->chunk_bytes; + if (getWorkMode() == WorkMode_R311_PV1) { + if (pcm_read(record->pcm_cfg->adc) == + record->pcm_cfg->adc->chunk_size) { + if (pcm_read(record) == record->chunk_size) { + // Write adc data to dmic data, in first two channel + for (i = 0; i < record->chunk_size; i++) { + // printf("copy from %p to %p, size:%d, frame:%d\n", + // (record->pcm_cfg->adc->buffer + + // i * + // record->pcm_cfg->adc->bits_per_frame + // / 8), (record->buffer + i * + // record->bits_per_frame / 8), 2 * + // record->significant_bits_per_sample / + // 8, i); + // ch:1-6 dmic + // ch:7-8 adc + memmove( + (void *)(record->buffer + + i * record->bits_per_frame / 8), + (void *)(record->buffer + + i * record->bits_per_frame / 8 + + 2 * record->significant_bits_per_sample / + 8), + 6 * record->significant_bits_per_sample / 8); + + // printf("copy to 0x%p, size:%d\n", (record->buffer + + // i * record->bits_per_frame / 8 + + // 6 * record->significant_bits_per_sample / + // 8), 2 * record->significant_bits_per_sample / 8); + memcpy( + (void *)(record->buffer + + i * record->bits_per_frame / 8 + + 6 * record->significant_bits_per_sample / + 8), + (void *)(record->pcm_cfg->adc->buffer + + i * record->pcm_cfg->adc->bits_per_frame / + 8), + record->pcm_cfg->adc->bits_per_frame / 8); + // memcpy((void *)(record->buffer + + // i * record->bits_per_frame / 8), + // (void *)(record->pcm_cfg->adc->buffer + + // i * + // record->pcm_cfg->adc->bits_per_frame + // / 8), + // 2 * record->significant_bits_per_sample / 8); + } + + if (record->backupfilefd > 0) { + xwrite(record->backupfilefd, record->buffer, + record->chunk_bytes); + fdcount += record->chunk_bytes; + } + queue_write(record->queue, record->buffer, + record->chunk_bytes); + } else { + fprintf(stderr, "short read, read %d frames/n", ret); + LOG_EX(LOG_Error, "ALSA Short Read, Read %d Frames: %d\n", + ret); + } + } else { + // read dmic data and throw + pcm_read(record); + printf("Read adc codec error!\n"); } - queue_write(record->queue, record->buffer, record->chunk_bytes); } else { - fprintf(stderr, "short read, read %d frames/n", ret); - LOG_EX(LOG_Error, "ALSA Short Read, Read %d Frames: %d\n", ret); + printf("Unknow work mode!\n"); + exit(0); } } - - if (record->backupfilefd > 0 && record->pcm_cfg->backupfile_waveformat > 0) { + + if (record->backupfilefd > 0 && + record->pcm_cfg->backupfile_waveformat > 0) { end_wave(record->backupfilefd); record->backupfilefd = 0; n_debug("Write backup file end finish!\n"); @@ -359,11 +427,61 @@ static void show_available_sample_formats(snd_pcm_t *handle, } int Neteasae_record_start(struct pcm_config *pcm_cfg) { + pthread_attr_t thread_attr; + struct sched_param thread_param; + struct pcm_config *tmp; + + printf("Begin to init netease record!\n"); + snd_output_stdio_attach(&sndlog, stderr, 0); + switch (getWorkMode()) { + case WorkMode_R311_PV1: + // dmic codec + pcm_cfg->device_name = "hw:1,0"; + pcm_cfg->channels = 8; + pcm_cfg->rate = 16000; + pcm_cfg->period_size = 1535; + pcm_cfg->format = "S16_LE"; + + printf("Begin to init dmic!\n"); + init_params(pcm_cfg, 1); + tmp = (struct pcm_config *)calloc(1, sizeof(struct pcm_config)); + if (tmp == NULL) { + printf("alloc fail!\n"); + exit(0); + } else { + printf("Begin to init adc codec!\n"); + // adc codec + tmp->device_name = "hw:2,0"; + tmp->channels = 2; + tmp->rate = 16000; + tmp->period_size = 1535; + tmp->format = "S16_LE"; + init_params(tmp, 0); + } + pcm_cfg->adc = tmp->recordata; + pcm_cfg->recordata->adc = tmp; + + pthread_attr_init(&thread_attr); + pthread_attr_setschedpolicy(&thread_attr, SCHED_RR); + thread_param.sched_priority = sched_get_priority_max(SCHED_RR); + pthread_attr_setschedparam(&thread_attr, &thread_param); + + pthread_create(&pcm_cfg->recordata->tid_pcm_read, &thread_attr, + RecordThread, (void *)pcm_cfg->recordata); + pthread_create(&pcm_cfg->recordata->tid_queue_read, NULL, + QueueReadThread, (void *)pcm_cfg->recordata); + + break; + + default: + printf("Unknow mode!\n"); + exit(0); + } +} +static int init_params(struct pcm_config *pcm_cfg, int init_queue) { int rc; int size; int ret = NETEASE_SUCCESS; - pthread_attr_t thread_attr; - struct sched_param thread_param; snd_pcm_hw_params_t *params; snd_pcm_sw_params_t *swparams; unsigned int val, val2; @@ -374,6 +492,7 @@ int Neteasae_record_start(struct pcm_config *pcm_cfg) { RecordData *record = (RecordData *)malloc(sizeof(RecordData)); if (NULL == record) { + printf("Malloc fail for record data!\n"); return NETEASE_ERROR_OUT_OF_MEMORY; } memset(record, 0, sizeof(RecordData)); @@ -381,7 +500,6 @@ int Neteasae_record_start(struct pcm_config *pcm_cfg) { pcm_cfg->recordata = record; record->pcm_cfg = pcm_cfg; record->cb = pcm_cfg->audio_cb; - snd_output_stdio_attach(&record->log, stderr, 0); //设置录音参数参数 rc = snd_pcm_open(&record->handle, pcm_cfg->device_name, @@ -460,12 +578,12 @@ int Neteasae_record_start(struct pcm_config *pcm_cfg) { rc = snd_pcm_hw_params(record->handle, params); if (rc < 0) { n_error("unable to set hw parameters: %s/n", snd_strerror(rc)); - // snd_pcm_hw_dump(params, stdout); + // snd_pcm_hw_dump(params, sndlog); ret = NETEASE_ERROR_FAIL; goto error; } // snd_pcm_hw_params_dump(params, stdout); - snd_pcm_dump(record->handle, record->log); + snd_pcm_dump(record->handle, sndlog); /* Use a buffer large enough to hold one period */ record->bits_per_sample = snd_pcm_format_physical_width(record->format); record->significant_bits_per_sample = snd_pcm_format_width(record->format); @@ -484,14 +602,19 @@ int Neteasae_record_start(struct pcm_config *pcm_cfg) { goto error; } - record->queue_buff = (char *)malloc( - sizeof(audio_queue_t) + record->chunk_bytes * QUEUE_BUFF_MULTIPLE + 1); - if (NULL == record->queue_buff) { - ret = NETEASE_ERROR_OUT_OF_MEMORY; - goto error; + if (init_queue > 0) { + record->queue_buff = (char *)malloc( + sizeof(audio_queue_t) + record->chunk_bytes * QUEUE_BUFF_MULTIPLE + 1); + if (NULL == record->queue_buff) { + ret = NETEASE_ERROR_OUT_OF_MEMORY; + goto error; + } + record->queue = queue_init(record->queue_buff, + record->chunk_bytes * QUEUE_BUFF_MULTIPLE + 1); + } else { + record->queue_buff = NULL; + record->queue = NULL; } - record->queue = queue_init(record->queue_buff, - record->chunk_bytes * QUEUE_BUFF_MULTIPLE + 1); snd_pcm_sw_params_current(record->handle, swparams); snd_pcm_sw_params_set_avail_min(record->handle, swparams, @@ -505,11 +628,6 @@ int Neteasae_record_start(struct pcm_config *pcm_cfg) { goto error; } - pthread_attr_init(&thread_attr); - pthread_attr_setschedpolicy(&thread_attr, SCHED_RR); - thread_param.sched_priority = sched_get_priority_max(SCHED_RR); - pthread_attr_setschedparam(&thread_attr, &thread_param); - record->runing = 1; if (pcm_cfg->backupfilename != NULL) { @@ -523,11 +641,21 @@ int Neteasae_record_start(struct pcm_config *pcm_cfg) { n_debug("Create backup file:%s, fd:%d\n", pcm_cfg->backupfilename, record->backupfilefd); } + + if (pcm_cfg->finalfilename != NULL) { + if (!lstat(pcm_cfg->finalfilename, &statbuf)) { + if (S_ISREG(statbuf.st_mode)) + remove(pcm_cfg->finalfilename); + n_debug("Remove file:%s\n", pcm_cfg->finalfilename); + } + record->finalfilefd = + open(pcm_cfg->finalfilename, O_TRUNC | O_WRONLY | O_CREAT, 06444); + n_debug("Create final file:%s, fd:%d\n", pcm_cfg->finalfilename, + record->finalfilefd); + } + n_toast("Record_start record :%p\n", record); - pthread_create(&record->tid_pcm_read, &thread_attr, RecordThread, - (void *)record); - pthread_create(&record->tid_queue_read, NULL, QueueReadThread, - (void *)record); + goto exit; error: @@ -574,4 +702,117 @@ void Netease_record_stop(struct pcm_config *config) { if (config != NULL && config->recordata != NULL) { config->recordata->runing = 0; } +} + +void device_list(void) { + snd_ctl_t *handle; + int card, err, dev, idx; + snd_ctl_card_info_t *info; + snd_pcm_info_t *pcminfo; + snd_pcm_stream_t stream = SND_PCM_STREAM_CAPTURE; + + snd_ctl_card_info_alloca(&info); + snd_pcm_info_alloca(&pcminfo); + + card = -1; + if (snd_card_next(&card) < 0 || card < 0) { + n_error("no soundcards found..."); + return; + } + printf("**** List of %s Hardware Devices ****\n", + snd_pcm_stream_name(stream)); + while (card >= 0) { + char name[32]; + sprintf(name, "hw:%d", card); + if ((err = snd_ctl_open(&handle, name, 0)) < 0) { + n_error("control open (%i): %s", card, snd_strerror(err)); + goto next_card; + } + if ((err = snd_ctl_card_info(handle, info)) < 0) { + n_error("control hardware info (%i): %s", card, snd_strerror(err)); + snd_ctl_close(handle); + goto next_card; + } + dev = -1; + while (1) { + unsigned int count; + if (snd_ctl_pcm_next_device(handle, &dev) < 0) + n_error("snd_ctl_pcm_next_device"); + if (dev < 0) + break; + snd_pcm_info_set_device(pcminfo, dev); + snd_pcm_info_set_subdevice(pcminfo, 0); + snd_pcm_info_set_stream(pcminfo, stream); + if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) { + if (err != -ENOENT) + n_error("control digital audio info (%i): %s", card, + snd_strerror(err)); + continue; + } + printf(("card %i: %s [%s], device %i: %s [%s]\n"), card, + snd_ctl_card_info_get_id(info), + snd_ctl_card_info_get_name(info), dev, + snd_pcm_info_get_id(pcminfo), + snd_pcm_info_get_name(pcminfo)); + count = snd_pcm_info_get_subdevices_count(pcminfo); + printf((" Subdevices: %i/%i\n"), + snd_pcm_info_get_subdevices_avail(pcminfo), count); + for (idx = 0; idx < (int)count; idx++) { + snd_pcm_info_set_subdevice(pcminfo, idx); + if ((err = snd_ctl_pcm_info(handle, pcminfo)) < 0) { + n_error("control digital audio playback info (%i): %s", + card, snd_strerror(err)); + } else { + printf((" Subdevice #%i: %s\n"), idx, + snd_pcm_info_get_subdevice_name(pcminfo)); + } + } + } + snd_ctl_close(handle); + next_card: + if (snd_card_next(&card) < 0) { + n_error("snd_card_next"); + break; + } + } +} + +void pcm_list(void) { + void **hints, **n; + char *name, *descr, *descr1, *io; + const char *filter; + + if (snd_device_name_hint(-1, "pcm", &hints) < 0) + return; + n = hints; + // filter = stream == SND_PCM_STREAM_CAPTURE ? "Input" : "Output"; + filter = "Input"; + while (*n != NULL) { + name = snd_device_name_get_hint(*n, "NAME"); + descr = snd_device_name_get_hint(*n, "DESC"); + io = snd_device_name_get_hint(*n, "IOID"); + if (io != NULL && strcmp(io, filter) != 0) + goto __end; + printf("%s\n", name); + if ((descr1 = descr) != NULL) { + printf(" "); + while (*descr1) { + if (*descr1 == '\n') + printf("\n "); + else + putchar(*descr1); + descr1++; + } + putchar('\n'); + } + __end: + if (name != NULL) + free(name); + if (descr != NULL) + free(descr); + if (io != NULL) + free(io); + n++; + } + snd_device_name_free_hint(hints); } \ No newline at end of file