This is the source for the afm_ctl utility.
/* * Copyright 2016, QNX Software Systems Ltd. All Rights Reserved. * * This source code may contain confidential information of QNX Software * Systems Ltd. (QSSL) and its licensors. Any use, reproduction, * modification, disclosure, distribution or transfer of this software, * or any software which includes or is based upon any of this code, is * prohibited unless expressly authorized by QSSL by written agreement. For * more information (including whether this source code file has been * published) please email licensing@qnx.com. */ #include <stdio.h> #include <stdlib.h> #include <sys/asoundlib.h> #include <string.h> #include <devctl.h> #include <errno.h> #include <ctype.h> #include <ioctl.h> //***************************************************************************** /* *INDENT-OFF* */ #ifdef __USAGE %C [Options] Options: -a [card#:]<dev#> the AFM card & device number to start/issue command OR -a [name] the AFM card name (e.g. voice, icc) to start/issue command -f <filename> set wav file (full path) (recorder/player AFMs only) -m <mode> set audio mode -c reset audio mode -t <dataset> load runtime acoustic processing dataset -l <ms_offset> start microphone latency test -r <ms_offset> start reference latency test -v <rpm> set rpm vin -s stop AFM #endif /* *INDENT-ON* */ //***************************************************************************** int main(int argc, char *argv[]) { int c; int card = 0; int dev = 0; int rtn = 0; int reset_mode = 0; int stop = 0; int latencyTest = 0; int ms_offset = 0; int rpm = -1; char *filename = NULL; char *mode = NULL; char *dataset = NULL; snd_afm_t *afm_handle; char name[_POSIX_PATH_MAX] = { 0 }; optind = 1; while ((c = getopt(argc, argv, "a:f:m:sl:r:cv:t:")) != EOF) { switch (c) { case 'a': if (strchr(optarg, ':')) { card = atoi(optarg); dev = atoi(strchr(optarg, ':') + 1); } else if (isalpha(optarg[0])) strlcpy(name, optarg, sizeof(name)); else dev = atoi(optarg); break; case 's': stop = 1; break; case 'l': ms_offset = atoi(optarg); latencyTest = 1; break; case 'r': ms_offset = atoi(optarg); latencyTest = 2; break; case 'f': filename = strdup(optarg); break; case 'm': mode = strdup(optarg); break; case 'c': reset_mode = 1; break; case 't': dataset = strdup(optarg); break; case 'v': rpm = strtoul(optarg, NULL, 0); break; default: printf("Invalid option '%c'", c); return EINVAL; } } if (name[0] != '\0') { card = snd_card_name(name); printf("Using %s - card %d\n", name, card); } else { printf("Using card %d device %d \n", card, dev); } if ((rtn = snd_afm_open(&afm_handle, card, dev)) != EOK) { fprintf(stderr, "snd_afm_open failed: (%d) %s\n", rtn, snd_strerror(rtn)); free(filename); free(mode); return -rtn; } if (filename != NULL) { printf("Setting filename %s, len = %zu\n", filename, strlen(filename)); if ((rtn = snd_afm_set_path(afm_handle, SND_AFM_WAV_FILE, filename)) != EOK) printf("Failed to set filename: (%d) %s\n", rtn, snd_strerror(rtn)); } if (reset_mode) { printf("Clearing mode\n"); if ((rtn = snd_afm_set_audio_mode(afm_handle, "")) != EOK) printf("Failed to clear mode: (%d) %s\n", rtn, snd_strerror(rtn)); } else if (mode != NULL) { char str[64]; printf("Setting mode to %s\n", mode); if ((rtn = snd_afm_set_audio_mode(afm_handle, mode)) != EOK) printf("Failed to set mode: (%d) %s\n", rtn, snd_strerror(rtn)); if ((rtn = snd_afm_get_audio_mode(afm_handle, str, sizeof(str))) != EOK) printf("Failed to get mode: (%d) %s\n", rtn, snd_strerror(rtn)); else printf("Audio Mode = %s\n", str); } else if (dataset != NULL) { int ap_status = 0; printf("Loading dataset %s\n", dataset); if ((rtn = snd_afm_load_ap_dataset(afm_handle, dataset, &ap_status)) != EOK) printf("Failed to load dataset: (%d) %s\n", rtn, snd_strerror(rtn)); if (ap_status != 0) { printf("Acoustic processing returned status=0x%04X\n", ap_status); } } else if (latencyTest) { int fd; snd_afm_latency_test_t test; if ((fd = snd_afm_file_descriptor(afm_handle)) > 0) { test.input_device = latencyTest-1; /* 0 = mic, 1 = ref */ test.input_voice = 0; test.ms_offset = ms_offset; if (ioctl(fd, SND_AFM_IOCTL_START_LATENCY_TEST, &test) < 0) { printf("Failed to start latency test: (%d) %s\n", errno, strerror(errno)); return errno; } } else { printf("Failed to get AFM descriptor for latency test (%d) %s\n", errno, strerror(errno)); return errno; } } else if (rpm >= 0) { int vinCount = 0; if ((rtn = snd_afm_get_vin_list_count(afm_handle, &vinCount)) == EOK) { snd_afm_vin_list_item_t* vin_items = alloca( sizeof(snd_afm_vin_list_item_t) * vinCount); snd_afm_vin_pair_t* vin_pairs = alloca( sizeof(snd_afm_vin_pair_t) * vinCount); if (vin_items && vin_pairs) { memset(vin_pairs, 0, sizeof(snd_afm_vin_pair_t) * vinCount); if ((rtn = snd_afm_get_vin_list(afm_handle, vin_items, vinCount)) == EOK) { int i; for (i=0; i<vinCount; i++) { vin_pairs[i].key = vin_items[i].key; if (vin_items[i].is_rpm) { vin_pairs[i].value = rpm; printf("Vin 0x%X set to %d\n", vin_pairs[i].key, vin_pairs[i].value); } } rtn = snd_afm_set_vin_stream(afm_handle, vin_pairs, vinCount); } } else { rtn = -errno; } } if (rtn != EOK) { printf("Failed to set RPM (%d) %s\n", rtn, snd_strerror(rtn)); } } else if (stop) { printf("Stopping AFM \n"); if ((rtn = snd_afm_stop(afm_handle)) != EOK) printf("Failed to stop AFM: (%d) %s\n", rtn, snd_strerror(rtn)); } else { printf("Starting AFM \n"); if ((rtn = snd_afm_start(afm_handle)) != EOK) printf("Failed to start AFM: (%d) %s\n", rtn, snd_strerror(rtn)); } snd_afm_close(afm_handle); free(filename); free(mode); return -rtn; } #if defined(__QNXNTO__) && defined(__USESRCVERSION) #include <sys/srcversion.h> __SRCVERSION("$URL$ $Rev$") #endif