plugins: test: AGM test app enhancement.
- Remove hardcoding of all gkvs, add support to take stream kv,
device kv, device pp kv, instance kv from cmdline.
- Add support of passing device pp kv and instance kv as 0 for
graph which doesn't have device pp kv or instance kv.
- SSMD playback support.
- Remove array of backends from agmhostless and add support of
taking intf configuration from backend_conf.xml
- Support of loopback through application processor.
Change-Id: Ie5bef45f4670b5c99fa37bfcd8dab3ab54001866
diff --git a/plugins/tinyalsa/test/Android.mk b/plugins/tinyalsa/test/Android.mk
index 7990745..abca51c 100644
--- a/plugins/tinyalsa/test/Android.mk
+++ b/plugins/tinyalsa/test/Android.mk
@@ -88,6 +88,35 @@
include $(CLEAR_VARS)
+LOCAL_MODULE := agmhostless
+LOCAL_MODULE_OWNER := qti
+LOCAL_MODULE_TAGS := optional
+LOCAL_VENDOR_MODULE := true
+
+LOCAL_CFLAGS += -Wno-unused-parameter -Wno-unused-result
+LOCAL_CFLAGS += -DBACKEND_CONF_FILE=\"/vendor/etc/backend_conf.xml\"
+LOCAL_SRC_FILES := agmhostless.c
+
+LOCAL_HEADER_LIBRARIES := \
+ libagm_headers \
+ libacdb_headers
+
+#if android version is R, refer to qtitinyxx otherwise use upstream ones
+#This assumes we would be using AR code only for Android R and subsequent versions.
+ifneq ($(filter 11 R, $(PLATFORM_VERSION)),)
+LOCAL_C_INCLUDES += $(TOP)/vendor/qcom/opensource/tinyalsa/include
+LOCAL_SHARED_LIBRARIES += libqti-tinyalsa
+else
+LOCAL_SHARED_LIBRARIES += libtinyalsa
+endif
+
+LOCAL_SHARED_LIBRARIES += \
+ libagmmixer
+
+include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+
LOCAL_MODULE := agmcompressplay
LOCAL_MODULE_OWNER := qti
LOCAL_MODULE_TAGS := optional
@@ -125,6 +154,43 @@
include $(CLEAR_VARS)
+LOCAL_MODULE := agmcompresscap
+LOCAL_MODULE_OWNER := qti
+LOCAL_MODULE_TAGS := optional
+LOCAL_VENDOR_MODULE := true
+
+LOCAL_CFLAGS += -Wno-unused-parameter -Wno-unused-result
+LOCAL_CFLAGS += -DBACKEND_CONF_FILE=\"/vendor/etc/backend_conf.xml\"
+
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+
+LOCAL_SRC_FILES := agmcompresscap.c
+
+LOCAL_HEADER_LIBRARIES := \
+ libagm_headers \
+ libacdb_headers
+
+#if android version is R, refer to qtitinyxx otherwise use upstream ones
+#This assumes we would be using AR code only for Android R and subsequent versions.
+ifneq ($(filter 11 R, $(PLATFORM_VERSION)),)
+LOCAL_C_INCLUDES += $(TOP)/vendor/qcom/opensource/tinyalsa/include
+LOCAL_C_INCLUDES += $(TOP)/vendor/qcom/opensource/tinycompress/include
+LOCAL_SHARED_LIBRARIES += libqti-tinyalsa\
+ libqti-tinycompress
+else
+LOCAL_C_INCLUDES += $(TOP)/external/tinycompress/include
+LOCAL_SHARED_LIBRARIES += libtinyalsa\
+ libtinycompress
+endif
+
+LOCAL_SHARED_LIBRARIES += \
+ libagmmixer
+
+include $(BUILD_EXECUTABLE)
+
+include $(CLEAR_VARS)
+
LOCAL_MODULE := agmvoiceui
LOCAL_MODULE_OWNER := qti
LOCAL_MODULE_TAGS := optional
diff --git a/plugins/tinyalsa/test/agm_voiceui.c b/plugins/tinyalsa/test/agm_voiceui.c
index 552c876..f039be8 100644
--- a/plugins/tinyalsa/test/agm_voiceui.c
+++ b/plugins/tinyalsa/test/agm_voiceui.c
@@ -236,11 +236,12 @@
buf += size[i];
}
*sum = total_size;
- /* TODO : free memory */
+ /* TODO : free memory */
return payload;
}
-void voice_ui_test(unsigned int card, unsigned int device, unsigned int audio_intf, unsigned int cap_time, int ec_aif)
+void voice_ui_test(unsigned int card, unsigned int device, unsigned int audio_intf, unsigned int cap_time, int ec_aif,
+ unsigned int device_kv, unsigned int stream_kv, unsigned int instance_kv, unsigned int devicepp_kv)
{
struct mixer *mixer;
char *intf_name = audio_interface_name[audio_intf];
@@ -261,6 +262,7 @@
config.start_threshold = 0;
config.stop_threshold = 0;
config.silence_threshold = 0;
+ stream_kv = stream_kv ? stream_kv : VOICE_UI;
mixer = mixer_open(card);
if (!mixer) {
@@ -276,20 +278,25 @@
}
/* set audio interface metadata mixer control */
- if (set_agm_audio_intf_metadata(mixer, intf_name, 0, CAPTURE, config.rate, pcm_format_to_bits(format), VOICE_UI)) {
+ if (set_agm_audio_intf_metadata(mixer, intf_name, 0, CAPTURE, config.rate,
+ pcm_format_to_bits(format), stream_kv)) {
printf("Failed to set device metadata\n");
goto err_close_mixer;
}
/* set stream metadata mixer control */
- if (set_agm_stream_metadata(mixer, device, VOICE_UI, CAPTURE, STREAM_PCM, NULL)) {
+ if (set_agm_stream_metadata(mixer, device, stream_kv, CAPTURE, STREAM_PCM,
+ instance_kv)) {
printf("Failed to set pcm metadata\n");
goto err_close_mixer;
}
- if (set_agm_stream_metadata(mixer, device, VOICE_UI, CAPTURE, STREAM_PCM, intf_name)) {
- printf("Failed to set pcm metadata\n");
- goto err_close_mixer;
+ if (devicepp_kv != 0) {
+ if (set_agm_streamdevice_metadata(mixer, device, stream_kv, CAPTURE, STREAM_PCM,
+ intf_name, devicepp_kv)) {
+ printf("Failed to set pcm metadata\n");
+ goto err_close_mixer;
+ }
}
/* connect pcm stream to audio intf */
if (connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_PCM, true)) {
@@ -385,6 +392,10 @@
unsigned int audio_intf = 0;
int ec_aif = -1;
unsigned int cap_time = 5;
+ unsigned int device_kv = 0;
+ unsigned int devicepp_kv = DEVICEPP_TX_FLUENCE_FFECNS;
+ unsigned int stream_kv = 0;
+ unsigned int instance_kv = INSTANCE_1;
argv += 1;
while (*argv) {
@@ -420,12 +431,29 @@
argv++;
if (*argv)
cap_time = atoi(*argv);
+ } else if (strcmp(*argv, "-dkv") == 0) {
+ argv++;
+ if (*argv)
+ device_kv = convert_char_to_hex(*argv);
+ } else if (strcmp(*argv, "-skv") == 0) {
+ argv++;
+ if (*argv)
+ stream_kv = convert_char_to_hex(*argv);
+ } else if (strcmp(*argv, "-ikv") == 0) {
+ argv++;
+ if (*argv)
+ instance_kv = atoi(*argv);
+ } else if (strcmp(*argv, "-dppkv") == 0) {
+ argv++;
+ if (*argv)
+ devicepp_kv = convert_char_to_hex(*argv);
}
if (*argv)
argv++;
}
- voice_ui_test(card, device, audio_intf, cap_time, ec_aif);
+ voice_ui_test(card, device, audio_intf, cap_time, ec_aif, device_kv, stream_kv,
+ instance_kv, devicepp_kv);
return 0;
}
diff --git a/plugins/tinyalsa/test/agmcap.c b/plugins/tinyalsa/test/agmcap.c
index d0257e4..07a247d 100644
--- a/plugins/tinyalsa/test/agmcap.c
+++ b/plugins/tinyalsa/test/agmcap.c
@@ -64,16 +64,28 @@
int capturing = 1;
static unsigned int capture_sample(FILE *file, unsigned int card, unsigned int device,
- unsigned int dkv, unsigned int channels, unsigned int rate,
+ unsigned int channels, unsigned int rate,
enum pcm_format format, unsigned int period_size,
unsigned int period_count, unsigned int cap_time,
- struct device_config *dev_config);
+ struct device_config *dev_config, unsigned int stream_kv,
+ unsigned int device_kv, unsigned int instance_kv,
+ unsigned int devicepp_kv);
static void sigint_handler(int sig)
{
capturing = 0;
}
+static void usage(void)
+{
+ printf(" Usage: %s file.wav [-help print usage] [-D card] [-d device]\n"
+ " [-c channels] [-r rate] [-b bits] [-p period_size]\n"
+ " [-n n_periods] [-T capture time] [-i intf_name] [-dkv device_kv]\n"
+ " [-dppkv deviceppkv] : Assign 0 if no device pp in the graph\n"
+ " [-ikv instance_kv] : Assign 0 if no instance kv in the graph\n"
+ " [-skv stream_kv]\n");
+}
+
int main(int argc, char **argv)
{
FILE *file;
@@ -92,11 +104,13 @@
struct device_config config;
enum pcm_format format;
int ret = 0;
+ unsigned int devicepp_kv = DEVICEPP_TX_AUDIO_FLUENCE_SMECNS;
+ unsigned int stream_kv = 0;
+ unsigned int instance_kv = INSTANCE_1;
+
if (argc < 2) {
- printf("Usage: %s file.wav [-D card] [-d device]"
- " [-c channels] [-r rate] [-b bits] [-p period_size]"
- " [-n n_periods] [-T capture time] [-i intf_name] [-dkv device_kv]\n", argv[0]);
+ usage();
return 1;
}
@@ -149,8 +163,21 @@
argv++;
if (*argv)
device_kv = convert_char_to_hex(*argv);
+ } else if (strcmp(*argv, "-skv") == 0) {
+ argv++;
+ if (*argv)
+ stream_kv = convert_char_to_hex(*argv);
+ } else if (strcmp(*argv, "-ikv") == 0) {
+ argv++;
+ if (*argv)
+ instance_kv = atoi(*argv);
+ } else if (strcmp(*argv, "-dppkv") == 0) {
+ argv++;
+ if (*argv)
+ devicepp_kv = convert_char_to_hex(*argv);
+ } else if (strcmp(*argv, "-help") == 0) {
+ usage();
}
-
if (*argv)
argv++;
}
@@ -202,9 +229,10 @@
signal(SIGINT, sigint_handler);
signal(SIGHUP, sigint_handler);
signal(SIGTERM, sigint_handler);
- frames = capture_sample(file, card, device, device_kv, header.num_channels,
+ frames = capture_sample(file, card, device, header.num_channels,
header.sample_rate, format,
- period_size, period_count, cap_time, &config);
+ period_size, period_count, cap_time, &config,
+ stream_kv, device_kv, instance_kv, devicepp_kv);
printf("Captured %u frames\n", frames);
/* write header now all information is known */
@@ -219,10 +247,11 @@
}
unsigned int capture_sample(FILE *file, unsigned int card, unsigned int device,
- unsigned int dkv, unsigned int channels, unsigned int rate,
+ unsigned int channels, unsigned int rate,
enum pcm_format format, unsigned int period_size,
unsigned int period_count, unsigned int cap_time,
- struct device_config *dev_config)
+ struct device_config *dev_config, unsigned int stream_kv,
+ unsigned int device_kv, unsigned int instance_kv, unsigned int devicepp_kv)
{
struct pcm_config config;
struct pcm *pcm;
@@ -234,6 +263,9 @@
unsigned int frames = 0;
struct timespec end;
struct timespec now;
+ uint32_t miid = 0;
+ int ret = 0;
+ stream_kv = stream_kv ? stream_kv : PCM_RECORD;
memset(&config, 0, sizeof(config));
config.channels = channels;
@@ -259,21 +291,36 @@
}
/* set audio interface metadata mixer control */
- if (set_agm_audio_intf_metadata(mixer, intf_name, dkv, CAPTURE, dev_config->rate, dev_config->bits, PCM_RECORD)) {
+ if (set_agm_audio_intf_metadata(mixer, intf_name, device_kv, CAPTURE,
+ dev_config->rate, dev_config->bits, stream_kv)) {
printf("Failed to set device metadata\n");
goto err_close_mixer;
}
/* set stream metadata mixer control */
- if (set_agm_capture_stream_metadata(mixer, device, PCM_RECORD, CAPTURE, STREAM_PCM, dev_config->ch)) {
+ if (set_agm_capture_stream_metadata(mixer, device, stream_kv, CAPTURE, STREAM_PCM,
+ instance_kv)) {
printf("Failed to set pcm metadata\n");
goto err_close_mixer;
}
- if (configure_mfc(mixer, device, intf_name, TAG_STREAM_MFC,
- STREAM_PCM, rate, channels, pcm_format_to_bits(format))) {
- printf("Failed to configure pspd mfc\n");
- goto err_close_mixer;
+ if (devicepp_kv != 0) {
+ if (set_agm_streamdevice_metadata(mixer, device, stream_kv, CAPTURE, STREAM_PCM,
+ intf_name, devicepp_kv)) {
+ printf("Failed to set pcm metadata\n");
+ goto err_close_mixer;
+ }
+ }
+
+ ret = agm_mixer_get_miid (mixer, device, intf_name, STREAM_PCM, TAG_STREAM_MFC, &miid);
+ if (ret) {
+ printf("MFC not present for this graph\n");
+ } else {
+ if (configure_mfc(mixer, device, intf_name, TAG_STREAM_MFC,
+ STREAM_PCM, rate, channels, pcm_format_to_bits(format), miid)) {
+ printf("Failed to configure stream mfc\n");
+ goto err_close_mixer;
+ }
}
/* connect pcm stream to audio intf */
diff --git a/plugins/tinyalsa/test/agmcompresscap.c b/plugins/tinyalsa/test/agmcompresscap.c
index 7f20323..d5e1794 100644
--- a/plugins/tinyalsa/test/agmcompresscap.c
+++ b/plugins/tinyalsa/test/agmcompresscap.c
@@ -88,459 +88,503 @@
static const unsigned int DEFAULT_FORMAT = SNDRV_PCM_FORMAT_S16_LE;
struct riff_chunk {
- char desc[4];
- uint32_t size;
+ char desc[4];
+ uint32_t size;
} __attribute__((__packed__));
struct wave_header {
- struct {
- struct riff_chunk chunk;
- char format[4];
- } __attribute__((__packed__)) riff;
+ struct {
+ struct riff_chunk chunk;
+ char format[4];
+ } __attribute__((__packed__)) riff;
- struct {
- struct riff_chunk chunk;
- uint16_t type;
- uint16_t channels;
- uint32_t rate;
- uint32_t byterate;
- uint16_t blockalign;
- uint16_t samplebits;
- } __attribute__((__packed__)) fmt;
+ struct {
+ struct riff_chunk chunk;
+ uint16_t type;
+ uint16_t channels;
+ uint32_t rate;
+ uint32_t byterate;
+ uint16_t blockalign;
+ uint16_t samplebits;
+ } __attribute__((__packed__)) fmt;
- struct {
- struct riff_chunk chunk;
- } __attribute__((__packed__)) data;
+ struct {
+ struct riff_chunk chunk;
+ } __attribute__((__packed__)) data;
} __attribute__((__packed__));
static const struct wave_header blank_wave_header = {
- .riff = {
- .chunk = {
- .desc = "RIFF",
- },
- .format = "WAVE",
- },
- .fmt = {
- .chunk = {
- .desc = "fmt ", /* Note the space is important here */
- .size = sizeof(blank_wave_header.fmt) -
- sizeof(blank_wave_header.fmt.chunk),
- },
- .type = 0x01, /* PCM */
- },
- .data = {
- .chunk = {
- .desc = "data",
- },
- },
-};
-
-char *audio_interface_name[] = {
- "CODEC_DMA-LPAIF_VA-TX-0",
- "CODEC_DMA-LPAIF_VA-TX-1",
- "MI2S-LPAIF_AXI-TX-PRIMARY",
- "TDM-LPAIF_AXI-TX-PRIMARY",
- "AUXPCM-LPAIF_AXI-TX-PRIMARY",
- "SLIM-DEV1-TX-0",
- "USB_AUDIO-TX",
+ .riff = {
+ .chunk = {
+ .desc = "RIFF",
+ },
+ .format = "WAVE",
+ },
+ .fmt = {
+ .chunk = {
+ .desc = "fmt ", /* Note the space is important here */
+ .size = sizeof(blank_wave_header.fmt) -
+ sizeof(blank_wave_header.fmt.chunk),
+ },
+ .type = 0x01, /* PCM */
+ },
+ .data = {
+ .chunk = {
+ .desc = "data",
+ },
+ },
};
static void init_wave_header(struct wave_header *header, uint16_t channels,
- uint32_t rate, uint16_t samplebits)
+ uint32_t rate, uint16_t samplebits)
{
- memcpy(header, &blank_wave_header, sizeof(blank_wave_header));
+ memcpy(header, &blank_wave_header, sizeof(blank_wave_header));
- header->fmt.channels = channels;
- header->fmt.rate = rate;
- header->fmt.byterate = channels * rate * (samplebits / 8);
- header->fmt.blockalign = channels * (samplebits / 8);
- header->fmt.samplebits = samplebits;
+ header->fmt.channels = channels;
+ header->fmt.rate = rate;
+ header->fmt.byterate = channels * rate * (samplebits / 8);
+ header->fmt.blockalign = channels * (samplebits / 8);
+ header->fmt.samplebits = samplebits;
}
static void size_wave_header(struct wave_header *header, uint32_t size)
{
- header->riff.chunk.size = sizeof(*header) -
- sizeof(header->riff.chunk) + size;
- header->data.chunk.size = size;
+ header->riff.chunk.size = sizeof(*header) -
+ sizeof(header->riff.chunk) + size;
+ header->data.chunk.size = size;
}
static void usage(void)
{
- fprintf(stderr, "usage: crec [OPTIONS] [filename]\n"
- "-c\tcard number\n"
- "-d\tdevice node\n"
- "-b\tbuffer size\n"
- "-f\tfragments\n"
- "-v\tverbose mode\n"
- "-l\tlength of record in seconds\n"
- "-h\tPrints this help list\n\n"
- "-C\tSpecify the number of channels (default %u)\n"
- "-R\tSpecify the sample rate (default %u)\n"
- "-F\tSpecify the format: S16_LE, S32_LE (default S16_LE)\n\n"
- "If filename is not given the output is\n"
- "written to stdout\n\n"
- "Example:\n"
- "\tcrec -c 1 -d 2 test.wav\n"
- "\tcrec -f 5 test.wav\n",
- DEFAULT_CHANNELS, DEFAULT_RATE);
+ fprintf(stderr, "usage: crec [OPTIONS] [filename]\n"
+ "-D\tcard number\n"
+ "-d\tdevice node\n"
+ "-buf\tbuffer size\n"
+ "-f\tfragments\n"
+ "-v\tverbose mode\n"
+ "-l\tlength of record in seconds\n"
+ " [-help print usage]\n"
+ " [-c channels] [-r rate] [-b bits]\n"
+ " [-n n_periods] [-i intf_name] [-dkv device_kv]\n"
+ " [-dppkv deviceppkv] : Assign 0 if no device pp in the graph\n"
+ " [-ikv instance_kv] : Assign 0 if no instance kv in the graph\n"
+ " [-skv stream_kv]");
- exit(EXIT_FAILURE);
+ exit(EXIT_FAILURE);
}
static int print_time(struct compress *compress)
{
- unsigned int avail;
- struct timespec tstamp;
+ unsigned int avail;
+ struct timespec tstamp;
- if (compress_get_hpointer(compress, &avail, &tstamp) != 0) {
- fprintf(stderr, "Error querying timestamp\n");
- fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
- return -1;
- } else {
- fprintf(finfo, "DSP recorded %jd.%jd\n",
- (intmax_t)tstamp.tv_sec, (intmax_t)tstamp.tv_nsec*1000);
- }
- return 0;
+ if (compress_get_hpointer(compress, &avail, &tstamp) != 0) {
+ fprintf(stderr, "Error querying timestamp\n");
+ fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+ return -1;
+ } else {
+ fprintf(finfo, "DSP recorded %jd.%jd\n",
+ (intmax_t)tstamp.tv_sec, (intmax_t)tstamp.tv_nsec*1000);
+ }
+ return 0;
}
static int finish_record(void)
{
- struct wave_header header;
- int ret;
- size_t nread, written;
+ struct wave_header header;
+ int ret;
+ size_t nread, written;
- if (!file)
- return -ENOENT;
+ if (!file)
+ return -ENOENT;
- /* can't rewind if streaming to stdout */
- if (streamed)
- return 0;
+ /* can't rewind if streaming to stdout */
+ if (streamed)
+ return 0;
- /* Get amount of data written to file */
- ret = lseek(file, 0, SEEK_END);
- if (ret < 0)
- return -errno;
+ /* Get amount of data written to file */
+ ret = lseek(file, 0, SEEK_END);
+ if (ret < 0)
+ return -errno;
- written = ret;
- if (written < sizeof(header))
- return -ENOENT;
- written -= sizeof(header);
+ written = ret;
+ if (written < sizeof(header))
+ return -ENOENT;
+ written -= sizeof(header);
- /* Sync file header from file */
- ret = lseek(file, 0, SEEK_SET);
- if (ret < 0)
- return -errno;
+ /* Sync file header from file */
+ ret = lseek(file, 0, SEEK_SET);
+ if (ret < 0)
+ return -errno;
- nread = read(file, &header, sizeof(header));
- if (nread != sizeof(header))
- return -errno;
+ nread = read(file, &header, sizeof(header));
+ if (nread != sizeof(header))
+ return -errno;
- /* Update file header */
- ret = lseek(file, 0, SEEK_SET);
- if (ret < 0)
- return -errno;
+ /* Update file header */
+ ret = lseek(file, 0, SEEK_SET);
+ if (ret < 0)
+ return -errno;
- size_wave_header(&header, written);
+ size_wave_header(&header, written);
- written = write(file, &header, sizeof(header));
- if (written != sizeof(header))
- return -errno;
+ written = write(file, &header, sizeof(header));
+ if (written != sizeof(header))
+ return -errno;
- return 0;
+ return 0;
}
static void capture_samples(char *name, unsigned int card, unsigned int device,
- unsigned long buffer_size, unsigned int frag,
- unsigned int length, unsigned int rate,
- unsigned int channels, unsigned int format, unsigned int intf)
+ unsigned long buffer_size, unsigned int frag,
+ unsigned int length, unsigned int rate,
+ unsigned int channels, unsigned int format, struct device_config *dev_config, unsigned int stream_kv,
+ unsigned int device_kv, unsigned int instance_kv, unsigned int devicepp_kv)
{
- struct compr_config config;
- struct snd_codec codec;
- struct compress *compress;
- struct mixer *mixer;
- struct wave_header header;
- char *buffer;
- size_t written;
- int read, ret;
- unsigned int size, total_read = 0;
- unsigned int samplebits;
- char *intf_name = audio_interface_name[intf];
+ struct compr_config config;
+ struct snd_codec codec;
+ struct compress *compress;
+ struct mixer *mixer;
+ struct wave_header header;
+ char *buffer;
+ size_t written;
+ int read, ret;
+ unsigned int size, total_read = 0;
+ unsigned int samplebits;
+ uint32_t miid = 0;
+ char *intf_name = dev_config->name;
+ //TODO: Change default stream_kv to COMPRESS_RECORD later.
+ stream_kv = stream_kv ? stream_kv : PCM_RECORD;
- switch (format) {
- case SNDRV_PCM_FORMAT_S32_LE:
- samplebits = 32;
- break;
- default:
- samplebits = 16;
- break;
- }
+ switch (format) {
+ case SNDRV_PCM_FORMAT_S32_LE:
+ samplebits = 32;
+ break;
+ default:
+ samplebits = 16;
+ break;
+ }
- /* Convert length from seconds to bytes */
- length = length * rate * (samplebits / 8) * channels;
+ /* Convert length from seconds to bytes */
+ length = length * rate * (samplebits / 8) * channels;
- if (verbose)
- fprintf(finfo, "%s: entry, reading %u bytes\n", __func__, length);
+ if (verbose)
+ fprintf(finfo, "%s: entry, reading %u bytes\n", __func__, length);
if (!name) {
file = STDOUT_FILENO;
} else {
- file = open(name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
- if (file == -1) {
- fprintf(stderr, "Unable to open file '%s'\n", name);
- exit(EXIT_FAILURE);
- }
+ file = open(name, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
+ if (file == -1) {
+ fprintf(stderr, "Unable to open file '%s'\n", name);
+ exit(EXIT_FAILURE);
+ }
}
- /* Write a header, will update with size once record is complete */
- if (!streamed) {
- init_wave_header(&header, channels, rate, samplebits);
- written = write(file, &header, sizeof(header));
- if (written != sizeof(header)) {
- fprintf(stderr, "Error writing output file header: %s\n",
- strerror(errno));
- goto file_exit;
- }
+ /* Write a header, will update with size once record is complete */
+ if (!streamed) {
+ init_wave_header(&header, channels, rate, samplebits);
+ written = write(file, &header, sizeof(header));
+ if (written != sizeof(header)) {
+ fprintf(stderr, "Error writing output file header: %s\n",
+ strerror(errno));
+ goto file_exit;
}
+ }
- memset(&codec, 0, sizeof(codec));
- memset(&config, 0, sizeof(config));
- codec.id = SND_AUDIOCODEC_PCM;
- codec.ch_in = channels;
- codec.ch_out = channels;
- codec.sample_rate = rate;
- if (!codec.sample_rate) {
- fprintf(stderr, "invalid sample rate %d\n", rate);
- goto file_exit;
- }
- codec.format = format;
- if ((buffer_size != 0) && (frag != 0)) {
- config.fragment_size = buffer_size/frag;
- config.fragments = frag;
- }
- config.codec = &codec;
+ memset(&codec, 0, sizeof(codec));
+ memset(&config, 0, sizeof(config));
+ codec.id = SND_AUDIOCODEC_PCM;
+ codec.ch_in = channels;
+ codec.ch_out = channels;
+ codec.sample_rate = rate;
+ if (!codec.sample_rate) {
+ fprintf(stderr, "invalid sample rate %d\n", rate);
+ goto file_exit;
+ }
+ codec.format = format;
+ if ((buffer_size != 0) && (frag != 0)) {
+ config.fragment_size = buffer_size/frag;
+ config.fragments = frag;
+ }
+ config.codec = &codec;
- mixer = mixer_open(card);
- if (!mixer) {
- printf("Failed to open mixer\n");
- goto file_exit;
- }
+ mixer = mixer_open(card);
+ if (!mixer) {
+ printf("Failed to open mixer\n");
+ goto file_exit;
+ }
- /* set device/audio_intf media config mixer control */
- if (set_agm_device_media_config(mixer, channels, rate, samplebits, intf_name)) {
- printf("Failed to set device media config\n");
- goto mixer_exit;
- }
+ /* set device/audio_intf media config mixer control */
+ if (set_agm_device_media_config(mixer, dev_config->ch, dev_config->rate,
+ dev_config->bits, intf_name)) {
+ printf("Failed to set device media config\n");
+ goto mixer_exit;
+ }
- /* set audio interface metadata mixer control */
- if (set_agm_audio_intf_metadata(mixer, intf_name, 0, CAPTURE, rate, samplebits, PCM_RECORD)) {
- printf("Failed to set device metadata\n");
- goto mixer_exit;
- }
+ /* set audio interface metadata mixer control */
+ if (set_agm_audio_intf_metadata(mixer, intf_name, device_kv, CAPTURE,
+ dev_config->rate, dev_config->bits, stream_kv)) {
+ printf("Failed to set device metadata\n");
+ goto mixer_exit;
+ }
- /* set audio interface metadata mixer control */
+ /* set audio interface metadata mixer control */
/* Change pcm_record to compress_record */
- if (set_agm_stream_metadata(mixer, device, PCM_RECORD, CAPTURE, STREAM_COMPRESS, NULL)) {
- printf("Failed to set stream metadata\n");
- goto mixer_exit;
- }
+ if (set_agm_capture_stream_metadata(mixer, device, stream_kv, CAPTURE, STREAM_COMPRESS,
+ instance_kv)) {
+ printf("Failed to set pcm metadata\n");
+ goto mixer_exit;
+ }
- /* Note: No common metadata as of now*/
+ if (devicepp_kv != 0) {
+ if (set_agm_streamdevice_metadata(mixer, device, stream_kv, CAPTURE, STREAM_COMPRESS,
+ intf_name, devicepp_kv)) {
+ printf("Failed to set pcm metadata\n");
+ goto mixer_exit;
+ }
+ }
- /* connect stream to audio intf */
- if (connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_COMPRESS, true)) {
- printf("Failed to connect stream to audio interface\n");
- goto mixer_exit;
- }
+ ret = agm_mixer_get_miid (mixer, device, intf_name, STREAM_COMPRESS, TAG_STREAM_MFC, &miid);
+ if (ret) {
+ printf("MFC not present for this graph");
+ } else {
+ if (configure_mfc(mixer, device, intf_name, TAG_STREAM_MFC,
+ STREAM_COMPRESS, rate, channels, pcm_format_to_bits(format), miid)) {
+ printf("Failed to configure pspd mfc\n");
+ goto mixer_exit;
+ }
+ }
- compress = compress_open(card, device, COMPRESS_OUT, &config);
- if (!compress || !is_compress_ready(compress)) {
- fprintf(stderr, "Unable to open Compress device %d:%d\n",
- card, device);
- fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
- goto mixer_exit;
- };
+ /* Note: No common metadata as of now*/
- if (verbose)
- fprintf(finfo, "%s: Opened compress device\n", __func__);
+ /* connect stream to audio intf */
+ if (connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_COMPRESS, true)) {
+ printf("Failed to connect stream to audio interface\n");
+ goto mixer_exit;
+ }
- size = config.fragment_size;
- buffer = malloc(size * config.fragments);
- if (!buffer) {
- fprintf(stderr, "Unable to allocate %d bytes\n", size);
- goto comp_exit;
- }
+ compress = compress_open(card, device, COMPRESS_OUT, &config);
+ if (!compress || !is_compress_ready(compress)) {
+ fprintf(stderr, "Unable to open Compress device %d:%d\n",
+ card, device);
+ fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+ goto mixer_exit;
+ };
- fprintf(finfo, "Recording file %s On Card %u device %u, with buffer of %lu bytes\n",
- name, card, device, buffer_size);
- fprintf(finfo, "Codec %u Format %u Channels %u, %u Hz\n",
- codec.id, codec.format, codec.ch_out, rate);
+ if (verbose)
+ fprintf(finfo, "%s: Opened compress device\n", __func__);
- compress_start(compress);
+ size = config.fragment_size;
+ buffer = malloc(size * config.fragments);
+ if (!buffer) {
+ fprintf(stderr, "Unable to allocate %d bytes\n", size);
+ goto comp_exit;
+ }
- if (verbose)
- fprintf(finfo, "%s: Capturing audio NOW!!!\n", __func__);
+ fprintf(finfo, "Recording file %s On Card %u device %u, with buffer of %lu bytes\n",
+ name, card, device, buffer_size);
+ fprintf(finfo, "Codec %u Format %u Channels %u, %u Hz\n",
+ codec.id, codec.format, codec.ch_out, rate);
- do {
- read = compress_read(compress, buffer, size);
- if (read < 0) {
- fprintf(stderr, "Error reading sample\n");
- fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
- goto buf_exit;
- }
- if ((unsigned int)read != size) {
- fprintf(stderr, "We read %d, DSP sent %d\n",
- size, read);
- }
+ compress_start(compress);
- if (read > 0) {
- total_read += read;
+ if (verbose)
+ fprintf(finfo, "%s: Capturing audio NOW!!!\n", __func__);
- written = write(file, buffer, read);
- if (written != (size_t)read) {
- fprintf(stderr, "Error writing output file: %s\n",
- strerror(errno));
- goto buf_exit;
- }
- if (verbose) {
- print_time(compress);
- fprintf(finfo, "%s: read %d\n", __func__, read);
- }
- }
- } while (!length || total_read < length);
+ do {
+ read = compress_read(compress, buffer, size);
+ if (read < 0) {
+ fprintf(stderr, "Error reading sample\n");
+ fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+ goto buf_exit;
+ }
+ if ((unsigned int)read != size) {
+ fprintf(stderr, "We read %d, DSP sent %d\n",
+ size, read);
+ }
- ret = compress_stop(compress);
- if (ret < 0) {
- fprintf(stderr, "Error closing stream\n");
- fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
- }
+ if (read > 0) {
+ total_read += read;
- ret = finish_record();
- if (ret < 0) {
- fprintf(stderr, "Failed to finish header: %s\n", strerror(ret));
- goto buf_exit;
- }
+ written = write(file, buffer, read);
+ if (written != (size_t)read) {
+ fprintf(stderr, "Error writing output file: %s\n",
+ strerror(errno));
+ goto buf_exit;
+ }
+ if (verbose) {
+ print_time(compress);
+ fprintf(finfo, "%s: read %d\n", __func__, read);
+ }
+ }
+ } while (!length || total_read < length);
- if (verbose)
- fprintf(finfo, "%s: exit success\n", __func__);
+ ret = compress_stop(compress);
+ if (ret < 0) {
+ fprintf(stderr, "Error closing stream\n");
+ fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+ }
- free(buffer);
- close(file);
- file = 0;
+ ret = finish_record();
+ if (ret < 0) {
+ fprintf(stderr, "Failed to finish header: %s\n", strerror(ret));
+ goto buf_exit;
+ }
- compress_close(compress);
+ if (verbose)
+ fprintf(finfo, "%s: exit success\n", __func__);
- return;
+ free(buffer);
+ close(file);
+ file = 0;
+
+ compress_close(compress);
+
+ return;
buf_exit:
- free(buffer);
+ free(buffer);
comp_exit:
- compress_close(compress);
- connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_COMPRESS, false);
+ compress_close(compress);
+ connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_COMPRESS, false);
mixer_exit:
- mixer_close(mixer);
+ mixer_close(mixer);
file_exit:
- close(file);
+ close(file);
- if (verbose)
- fprintf(finfo, "%s: exit failure\n", __func__);
+ if (verbose)
+ fprintf(finfo, "%s: exit failure\n", __func__);
- exit(EXIT_FAILURE);
+ exit(EXIT_FAILURE);
}
static void sig_handler(int signum __attribute__ ((unused)))
{
- finish_record();
+ finish_record();
- if (file)
- close(file);
+ if (file)
+ close(file);
- _exit(EXIT_FAILURE);
+ _exit(EXIT_FAILURE);
}
int main(int argc, char **argv)
{
- char *file;
- unsigned long buffer_size = 0;
- int c;
- unsigned int card = 0, device = 0, frag = 0, length = 0;
- unsigned int rate = DEFAULT_RATE, channels = DEFAULT_CHANNELS;
- unsigned int format = DEFAULT_FORMAT;
- unsigned int audio_intf;
+ char *file = NULL;
+ unsigned long buffer_size = 0;
+ unsigned int card = 0, device = 0, frag = 0, length = 0;
+ unsigned int rate = DEFAULT_RATE, channels = DEFAULT_CHANNELS;
+ unsigned int bits = 16;
+ unsigned int format = DEFAULT_FORMAT;
+ char* intf_name;
+ int ret = 0;
+ unsigned int devicepp_kv = DEVICEPP_TX_AUDIO_FLUENCE_SMECNS;
+ unsigned int stream_kv = 0;
+ unsigned int instance_kv = INSTANCE_1;
+ struct device_config config;
+ unsigned int device_kv = 0;
- if (signal(SIGINT, sig_handler) == SIG_ERR) {
- fprintf(stderr, "Error registering signal handler\n");
- exit(EXIT_FAILURE);
- }
+ if (signal(SIGINT, sig_handler) == SIG_ERR) {
+ fprintf(stderr, "Error registering signal handler\n");
+ exit(EXIT_FAILURE);
+ }
- if (argc < 1)
- usage();
+ if (argc < 3)
+ usage();
- verbose = 0;
- while ((c = getopt(argc, argv, "hvl:R:C:F:b:f:c:d:i:")) != -1) {
- switch (c) {
- case 'h':
- usage();
- break;
- case 'b':
- buffer_size = strtol(optarg, NULL, 0);
- break;
- case 'f':
- frag = strtol(optarg, NULL, 10);
- break;
- case 'c':
- card = strtol(optarg, NULL, 10);
- break;
- case 'd':
- device = strtol(optarg, NULL, 10);
- break;
- case 'v':
- verbose = 1;
- break;
- case 'l':
- length = strtol(optarg, NULL, 10);
- break;
- case 'R':
- rate = strtol(optarg, NULL, 10);
- break;
- case 'C':
- channels = strtol(optarg, NULL, 10);
- break;
- case 'F':
- if (strcmp(optarg, "S16_LE") == 0) {
- format = SNDRV_PCM_FORMAT_S16_LE;
- } else if (strcmp(optarg, "S32_LE") == 0) {
- format = SNDRV_PCM_FORMAT_S32_LE;
- } else {
- fprintf(stderr, "Unrecognised format: %s\n",
- optarg);
- usage();
- }
- break;
- case 'i':
- audio_intf = strtol(optarg, NULL, 10);
- break;
- default:
- exit(EXIT_FAILURE);
- }
- }
- if (optind >= argc) {
- file = NULL;
- finfo = fopen("/dev/null", "w");
- streamed = true;
- } else {
- file = argv[optind];
- finfo = stdout;
- streamed = false;
- }
+ verbose = 0;
- if (audio_intf >= sizeof(audio_interface_name)/sizeof(char *)) {
- printf("Invalid audio interface index denoted by -i\n");
- exit(EXIT_FAILURE);
+ /* parse command line arguments */
+ argv += 2;
+ while (*argv) {
+ if (strcmp(*argv, "-d") == 0) {
+ argv++;
+ if (*argv)
+ device = atoi(*argv);
+ } else if (strcmp(*argv, "-c") == 0) {
+ argv++;
+ if (*argv)
+ channels = atoi(*argv);
+ } else if (strcmp(*argv, "-r") == 0) {
+ argv++;
+ if (*argv)
+ rate = atoi(*argv);
+ } else if (strcmp(*argv, "-b") == 0) {
+ argv++;
+ if (*argv)
+ bits = atoi(*argv);
+ } else if (strcmp(*argv, "-D") == 0) {
+ argv++;
+ if (*argv)
+ card = atoi(*argv);
+ } else if (strcmp(*argv, "-l") == 0) {
+ argv++;
+ if (*argv)
+ length = atoi(*argv);
+ } else if (strcmp(*argv, "-i") == 0) {
+ argv++;
+ if (*argv)
+ intf_name = *argv;
+ } else if (strcmp(*argv, "-dkv") == 0) {
+ argv++;
+ if (*argv)
+ device_kv = convert_char_to_hex(*argv);
+ } else if (strcmp(*argv, "-skv") == 0) {
+ argv++;
+ if (*argv)
+ stream_kv = convert_char_to_hex(*argv);
+ } else if (strcmp(*argv, "-ikv") == 0) {
+ argv++;
+ if (*argv)
+ instance_kv = atoi(*argv);
+ } else if (strcmp(*argv, "-dppkv") == 0) {
+ argv++;
+ if (*argv)
+ devicepp_kv = convert_char_to_hex(*argv);
+ } else if (strcmp(*argv, "-buf") == 0) {
+ argv++;
+ if (*argv)
+ buffer_size = atoi(*argv);
+ } else if (strcmp(*argv, "-f") == 0) {
+ argv++;
+ if (*argv)
+ frag = atoi(*argv);
+ } else if (strcmp(*argv, "-v") == 0) {
+ argv++;
+ if (*argv)
+ verbose = atoi(*argv);
+ } else if (strcmp(*argv, "-help") == 0) {
+ usage();
}
+ if (*argv)
+ argv++;
+ }
- capture_samples(file, card, device, buffer_size, frag, length,
- rate, channels, format, audio_intf);
+ if (intf_name == NULL) {
+ printf("Invalid audio interface index denoted by -i\n");
+ exit(EXIT_FAILURE);
+ }
- fprintf(finfo, "Finish capturing... Close Normally\n");
+ ret = get_device_media_config(BACKEND_CONF_FILE, intf_name, &config);
+ if (ret) {
+ printf("Invalid input, entry not found for %s\n", intf_name);
+ fclose(file);
+ return ret;
+ }
- exit(EXIT_SUCCESS);
+ switch (bits) {
+ case 32:
+ format = SNDRV_PCM_FORMAT_S32_LE;
+ break;
+ default:
+ format = SNDRV_PCM_FORMAT_S16_LE;
+ break;
+ }
+ capture_samples(file, card, device, buffer_size, frag, length,
+ rate, channels, format, &config, stream_kv, device_kv, instance_kv,
+ devicepp_kv);
+
+ fprintf(finfo, "Finish capturing... Close Normally\n");
+
+ exit(EXIT_SUCCESS);
}
diff --git a/plugins/tinyalsa/test/agmcompressplay.c b/plugins/tinyalsa/test/agmcompressplay.c
index 646645b..0e5018a 100644
--- a/plugins/tinyalsa/test/agmcompressplay.c
+++ b/plugins/tinyalsa/test/agmcompressplay.c
@@ -77,76 +77,79 @@
#define MP3_SYNC 0xe0ff
const int mp3_sample_rates[3][3] = {
- {44100, 48000, 32000}, /* MPEG-1 */
- {22050, 24000, 16000}, /* MPEG-2 */
- {11025, 12000, 8000}, /* MPEG-2.5 */
+ {44100, 48000, 32000}, /* MPEG-1 */
+ {22050, 24000, 16000}, /* MPEG-2 */
+ {11025, 12000, 8000}, /* MPEG-2.5 */
};
const int mp3_bit_rates[3][3][15] = {
- {
- /* MPEG-1 */
- { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448}, /* Layer 1 */
- { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384}, /* Layer 2 */
- { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320}, /* Layer 3 */
- },
- {
- /* MPEG-2 */
- { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, /* Layer 1 */
- { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 2 */
- { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 3 */
- },
- {
- /* MPEG-2.5 */
- { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, /* Layer 1 */
- { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 2 */
- { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 3 */
- },
+ {
+ /* MPEG-1 */
+ { 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448}, /* Layer 1 */
+ { 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384}, /* Layer 2 */
+ { 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320}, /* Layer 3 */
+ },
+ {
+ /* MPEG-2 */
+ { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, /* Layer 1 */
+ { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 2 */
+ { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 3 */
+ },
+ {
+ /* MPEG-2.5 */
+ { 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256}, /* Layer 1 */
+ { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 2 */
+ { 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}, /* Layer 3 */
+ },
};
enum mpeg_version {
- MPEG1 = 0,
- MPEG2 = 1,
- MPEG25 = 2
+ MPEG1 = 0,
+ MPEG2 = 1,
+ MPEG25 = 2
};
enum mp3_stereo_mode {
- STEREO = 0x00,
- JOINT = 0x01,
- DUAL = 0x02,
- MONO = 0x03
+ STEREO = 0x00,
+ JOINT = 0x01,
+ DUAL = 0x02,
+ MONO = 0x03
};
static int verbose;
static void usage(void)
{
- fprintf(stderr, "usage: cplay [OPTIONS] filename\n"
- "-c\tcard number\n"
- "-d\tdevice node\n"
- "-b\tbuffer size\n"
- "-f\tfragments\n\n"
- "-i\taudio_intf_id\n"
- "-v\tverbose mode\n"
- "-h\tPrints this help list\n\n"
- "-t\tcodec type\n\n"
- "1 : mp3"
- "2 : aac"
- "-p\tpause/resume with 2 secs sleep\n\n"
- "Example:\n"
- "\tagmcompressplay -c 1 -d 2 test.mp3\n"
- "\tagmcompressplay -f 5 test.mp3\n");
+ fprintf(stderr, "usage: cplay [OPTIONS] filename\n"
+ "-D\tcard number\n"
+ "-d\tdevice node\n"
+ "-b\tbuffer size\n"
+ "-f\tfragments\n\n"
+ "-v\tverbose mode\n"
+ "-help\tPrints this help list\n\n"
+ "-t\tcodec type\n\n"
+ "1 : mp3"
+ "2 : aac"
+ "-p\tpause/resume with 2 secs sleep\n\n"
+ " [-num_intf num of interfaces followed by interface name]\n"
+ " [-i intf_name] : Can be multiple if num_intf is more than 1\n"
+ " [-dkv device_kv] : Can be multiple if num_intf is more than 1\n"
+ " [-dppkv deviceppkv] : Assign 0 if no device pp in the graph\n"
+ " [-ikv instance_kv] : Assign 0 if no instance kv in the graph\n"
+ " [-skv stream_kv]");
- exit(EXIT_FAILURE);
+ exit(EXIT_FAILURE);
}
-void play_samples(char *name, unsigned int card, unsigned int device,
- unsigned long buffer_size, unsigned int frag, unsigned int audio_format,
- int pause, struct device_config *dev_config);
+void play_samples(char *name, unsigned int card, unsigned int device, unsigned int *device_kv,
+ unsigned int stream_kv, unsigned int instance_kv, unsigned int *devicepp_kv,
+ unsigned long buffer_size, unsigned int frag, unsigned int format,
+ int pause, char **intf_name, int intf_num);
struct mp3_header {
- uint16_t sync;
- uint8_t format1;
- uint8_t format2;
+ uint16_t sync;
+ uint8_t format1;
+ uint8_t format2;
};
#define ADTS_SYNC 0xF0FF
@@ -154,356 +157,471 @@
#define AAC_ADTS_FORMAT 2
struct adts_header {
- uint32_t sync;
- uint8_t format1;
- uint8_t format2;
- uint8_t format3;
+ uint32_t sync;
+ uint8_t format1;
+ uint8_t format2;
+ uint8_t format3;
};
uint aac_sample_rates[] = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350, 48000, 48000, 48000};
int parse_aac_header(struct adts_header *header, unsigned int *num_channels,
- unsigned int *sample_rate, unsigned int *protection_absent)
+ unsigned int *sample_rate, unsigned int *protection_absent)
{
- int profile, sample_rate_idx;
+ int profile, sample_rate_idx;
- /* check sync bits */
- if ((header->sync & 0xF0FF) != ADTS_SYNC) {
- fprintf(stderr, "Error: Can't find sync word: 0x%X\n", header->sync);
- return -1;
- }
- *protection_absent = (header->sync >> 8) & 0x01;
- profile = ((header->sync >> 22) & 0x03) - 1;
- sample_rate_idx = ((header->sync >> 18) & 0x0F);
-// channel_idx = ((header->format1 >> 7) & 0x07);
-// frame_length = ((header->format1 >> 14) & 0x1FFF);
+ /* check sync bits */
+ if ((header->sync & 0xF0FF) != ADTS_SYNC) {
+ fprintf(stderr, "Error: Can't find sync word: 0x%X\n", header->sync);
+ return -1;
+ }
+ *protection_absent = (header->sync >> 8) & 0x01;
+ profile = ((header->sync >> 22) & 0x03) - 1;
+ sample_rate_idx = ((header->sync >> 18) & 0x0F);
+// channel_idx = ((header->format1 >> 7) & 0x07);
+// frame_length = ((header->format1 >> 14) & 0x1FFF);
- *num_channels = 2;
- *sample_rate = aac_sample_rates[sample_rate_idx];
-// *size = frame_length - ((protection_absent == 1)? 7: 9));
+ *num_channels = 2;
+ *sample_rate = aac_sample_rates[sample_rate_idx];
+// *size = frame_length - ((protection_absent == 1)? 7: 9));
- if (verbose)
- printf("%s: exit sr %d\n", __func__, *sample_rate);
- return 0;
+ if (verbose)
+ printf("%s: exit sr %d\n", __func__, *sample_rate);
+ return 0;
}
int parse_mp3_header(struct mp3_header *header, unsigned int *num_channels,
- unsigned int *sample_rate, unsigned int *bit_rate)
+ unsigned int *sample_rate, unsigned int *bit_rate)
{
- int ver_idx, mp3_version, layer, bit_rate_idx, sample_rate_idx, channel_idx;
+ int ver_idx, mp3_version, layer, bit_rate_idx, sample_rate_idx, channel_idx;
- /* check sync bits */
- if ((header->sync & MP3_SYNC) != MP3_SYNC) {
- fprintf(stderr, "Error: Can't find sync word\n");
- return -1;
- }
- ver_idx = (header->sync >> 11) & 0x03;
- mp3_version = ver_idx == 0 ? MPEG25 : ((ver_idx & 0x1) ? MPEG1 : MPEG2);
- layer = 4 - ((header->sync >> 9) & 0x03);
- bit_rate_idx = ((header->format1 >> 4) & 0x0f);
- sample_rate_idx = ((header->format1 >> 2) & 0x03);
- channel_idx = ((header->format2 >> 6) & 0x03);
+ /* check sync bits */
+ if ((header->sync & MP3_SYNC) != MP3_SYNC) {
+ fprintf(stderr, "Error: Can't find sync word\n");
+ return -1;
+ }
+ ver_idx = (header->sync >> 11) & 0x03;
+ mp3_version = ver_idx == 0 ? MPEG25 : ((ver_idx & 0x1) ? MPEG1 : MPEG2);
+ layer = 4 - ((header->sync >> 9) & 0x03);
+ bit_rate_idx = ((header->format1 >> 4) & 0x0f);
+ sample_rate_idx = ((header->format1 >> 2) & 0x03);
+ channel_idx = ((header->format2 >> 6) & 0x03);
- if (sample_rate_idx == 3 || layer == 4 || bit_rate_idx == 15) {
- fprintf(stderr, "Error: Can't find valid header\n");
- return -1;
- }
- *num_channels = (channel_idx == MONO ? 1 : 2);
- *sample_rate = mp3_sample_rates[mp3_version][sample_rate_idx];
- *bit_rate = (mp3_bit_rates[mp3_version][layer - 1][bit_rate_idx]) * 1000;
- if (verbose)
- printf("%s: exit\n", __func__);
- return 0;
+ if (sample_rate_idx == 3 || layer == 4 || bit_rate_idx == 15) {
+ fprintf(stderr, "Error: Can't find valid header\n");
+ return -1;
+ }
+ *num_channels = (channel_idx == MONO ? 1 : 2);
+ *sample_rate = mp3_sample_rates[mp3_version][sample_rate_idx];
+ *bit_rate = (mp3_bit_rates[mp3_version][layer - 1][bit_rate_idx]) * 1000;
+ if (verbose)
+ printf("%s: exit\n", __func__);
+ return 0;
}
int check_codec_format_supported(unsigned int card, unsigned int device, struct snd_codec *codec)
{
- if (is_codec_supported(card, device, COMPRESS_IN, codec) == false) {
- fprintf(stderr, "Error: This codec or format is not supported by DSP\n");
- return -1;
- }
- return 0;
+ if (is_codec_supported(card, device, COMPRESS_IN, codec) == false) {
+ fprintf(stderr, "Error: This codec or format is not supported by DSP\n");
+ return -1;
+ }
+ return 0;
}
static int print_time(struct compress *compress)
{
- unsigned int avail;
- struct timespec tstamp;
+ unsigned int avail;
+ struct timespec tstamp;
- if (compress_get_hpointer(compress, &avail, &tstamp) != 0) {
- fprintf(stderr, "Error querying timestamp\n");
- fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
- return -1;
- } else
- fprintf(stderr, "DSP played %ld.%ld\n", tstamp.tv_sec, tstamp.tv_nsec*1000);
- return 0;
+ if (compress_get_hpointer(compress, &avail, &tstamp) != 0) {
+ fprintf(stderr, "Error querying timestamp\n");
+ fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+ return -1;
+ } else
+ fprintf(stderr, "DSP played %ld.%ld\n", tstamp.tv_sec, tstamp.tv_nsec*1000);
+ return 0;
}
int main(int argc, char **argv)
{
- char *file;
- unsigned long buffer_size = 0;
- char *intf_name = NULL;
- struct device_config config;
- int ret = 0;
- unsigned int card = 0, device = 0, frag = 0, audio_format = 0, pause = 0;
+ char *file;
+ unsigned long buffer_size = 0;
+ char **intf_name = NULL;
+ int ret = 0, i = 0;
+ unsigned int card = 0, device = 0, frag = 0, audio_format = 0, pause = 0;
+ int intf_num = 1;
+ unsigned int *device_kv = 0;
+ unsigned int stream_kv = 0;
+ unsigned int instance_kv = INSTANCE_1;
+ unsigned int *devicepp_kv = NULL;
+ if (argc < 3) {
+ usage();
+ return 1;
+ }
- if (argc < 2)
- usage();
+ file = argv[1];
+ /* parse command line arguments */
+ argv += 2;
+ while (*argv) {
+ if (strcmp(*argv, "-d") == 0) {
+ argv++;
+ if (*argv)
+ device = atoi(*argv);
+ } else if (strcmp(*argv, "-t") == 0) {
+ argv++;
+ if (*argv)
+ audio_format = atoi(*argv);
+ } else if (strcmp(*argv, "-D") == 0) {
+ argv++;
+ if (*argv)
+ card = atoi(*argv);
+ } else if (strcmp(*argv, "-p") == 0) {
+ argv++;
+ if (*argv)
+ pause = atoi(*argv);
+ } else if (strcmp(*argv, "-f") == 0) {
+ argv++;
+ if (*argv)
+ frag = atoi(*argv);
+ } else if (strcmp(*argv, "-v") == 0) {
+ argv++;
+ if (*argv)
+ verbose = atoi(*argv);
+ } else if (strcmp(*argv, "-num_intf") == 0) {
+ argv++;
+ if (*argv)
+ intf_num = atoi(*argv);
+ } else if (strcmp(*argv, "-i") == 0) {
+ intf_name = (char**) malloc(intf_num * sizeof(char*));
+ if (!intf_name) {
+ printf("invalid memory\n");
+ }
+ for (i = 0; i < intf_num ; i++){
+ argv++;
+ if (*argv)
+ intf_name[i] = *argv;
+ }
+ } else if (strcmp(*argv, "-dkv") == 0) {
+ device_kv = (unsigned int *) malloc(intf_num * sizeof(unsigned int));
+ if (!device_kv) {
+ printf(" insufficient memory\n");
+ }
+ for (i = 0; i < intf_num ; i++) {
+ argv++;
+ if (*argv) {
+ device_kv[i] = convert_char_to_hex(*argv);
+ }
+ }
+ } else if (strcmp(*argv, "-skv") == 0) {
+ argv++;
+ if (*argv)
+ stream_kv = convert_char_to_hex(*argv);
+ } else if (strcmp(*argv, "-ikv") == 0) {
+ argv++;
+ if (*argv) {
+ instance_kv = atoi(*argv);
+ }
+ } else if (strcmp(*argv, "-dppkv") == 0) {
+ devicepp_kv = (unsigned int *) malloc(intf_num * sizeof(unsigned int));
+ if (!devicepp_kv) {
+ printf(" insufficient memory\n");
+ }
+ for (i = 0; i < intf_num ; i++) {
+ devicepp_kv[i] = DEVICEPP_RX_AUDIO_MBDRC;
+ }
+ for (i = 0; i < intf_num ; i++)
+ {
+ argv++;
+ if(*argv) {
+ devicepp_kv[i] = convert_char_to_hex(*argv);
+ }
+ }
+ } else if (strcmp(*argv, "-help") == 0) {
+ usage();
+ }
- file = argv[1];
- /* parse command line arguments */
- argv += 2;
- while (*argv) {
- if (strcmp(*argv, "-d") == 0) {
- argv++;
- if (*argv)
- device = atoi(*argv);
- } else if (strcmp(*argv, "-t") == 0) {
- argv++;
- if (*argv)
- audio_format = atoi(*argv);
- } else if (strcmp(*argv, "-c") == 0) {
- argv++;
- if (*argv)
- card = atoi(*argv);
- } else if (strcmp(*argv, "-p") == 0) {
- argv++;
- if (*argv)
- pause = atoi(*argv);
- } else if (strcmp(*argv, "-i") == 0) {
- argv++;
- if (*argv)
- intf_name = *argv;
- }
- if (*argv)
- argv++;
- }
+ if (*argv)
+ argv++;
+ }
- if (intf_name == NULL)
- return 1;
+ if (intf_name == NULL)
+ return 1;
- ret = get_device_media_config(BACKEND_CONF_FILE, intf_name, &config);
- if (ret) {
- printf("Invalid input, entry not found for : %s\n", intf_name);
- return ret;
- }
+ play_samples(file, card, device, device_kv, stream_kv, instance_kv, devicepp_kv,
+ buffer_size, frag, audio_format, pause,
+ intf_name, intf_num);
- play_samples(file, card, device, buffer_size, frag, audio_format, pause, &config);
-
- fprintf(stderr, "Finish Playing.... Close Normally\n");
- exit(EXIT_SUCCESS);
+ fprintf(stderr, "Finish Playing.... Close Normally\n");
+ if (device_kv)
+ free(device_kv);
+ if (devicepp_kv)
+ free(devicepp_kv);
+ if (intf_name)
+ free(intf_name);
+ exit(EXIT_SUCCESS);
}
-void play_samples(char *name, unsigned int card, unsigned int device,
- unsigned long buffer_size, unsigned int frag, unsigned int format,
- int pause, struct device_config *dev_config)
+void play_samples(char *name, unsigned int card, unsigned int device, unsigned int *device_kv,
+ unsigned int stream_kv, unsigned int instance_kv, unsigned int *devicepp_kv,
+ unsigned long buffer_size, unsigned int frag, unsigned int format,
+ int pause, char **intf_name, int intf_num)
{
- struct compr_config config;
- struct snd_codec codec;
- struct compress *compress;
- struct mp3_header header;
- struct adts_header adts_header;
- struct mixer *mixer;
- FILE *file;
- char *buffer;
- int size, num_read, wrote;
- unsigned int channels = 0, rate = 0, bits = 0;
- char *intf_name = dev_config->name;
+ struct compr_config config;
+ struct snd_codec codec;
+ struct compress *compress;
+ struct mp3_header header;
+ struct adts_header adts_header;
+ struct mixer *mixer;
+ FILE *file;
+ char *buffer;
+ int num_read, wrote;
+ unsigned int channels = 0, rate = 0, bits = 0;
+ struct device_config *dev_config = (struct device_config *)malloc(intf_num*sizeof(struct device_config *));
+ struct group_config *grp_config = (struct group_config *)malloc(intf_num*sizeof(struct group_config *));
+ int size, index, ret = 0;
+ uint32_t miid = 0;
- if (verbose)
- printf("%s: entry\n", __func__);
- file = fopen(name, "rb");
- if (!file) {
- fprintf(stderr, "Unable to open file '%s'\n", name);
- exit(EXIT_FAILURE);
- }
+ stream_kv = stream_kv ? stream_kv : COMPRESSED_OFFLOAD_PLAYBACK;
- if (format == MP3_FORMAT) {
- fread(&header, sizeof(header), 1, file);
+ if (verbose)
+ printf("%s: entry\n", __func__);
+ file = fopen(name, "rb");
+ if (!file) {
+ fprintf(stderr, "Unable to open file '%s'\n", name);
+ exit(EXIT_FAILURE);
+ }
- if (parse_mp3_header(&header, &channels, &rate, &bits) == -1) {
- fclose(file);
- exit(EXIT_FAILURE);
- }
+ if (format == MP3_FORMAT) {
+ fread(&header, sizeof(header), 1, file);
- codec.id = SND_AUDIOCODEC_MP3;
+ if (parse_mp3_header(&header, &channels, &rate, &bits) == -1) {
+ fclose(file);
+ exit(EXIT_FAILURE);
+ }
+
+ codec.id = SND_AUDIOCODEC_MP3;
#ifdef SND_COMPRESS_DEC_HDR
- } else if (format == AAC_ADTS_FORMAT) {
- uint16_t protection_absent, crc;
- fread(&adts_header, sizeof(adts_header), 1, file);
- if (parse_aac_header(&adts_header, &channels, &rate, (unsigned int*)&protection_absent) == -1) {
- fclose(file);
- exit(EXIT_FAILURE);
- }
- if (!protection_absent) {
- fread(&crc, 2, 1, file);
- }
- codec.id = SND_AUDIOCODEC_AAC;
- codec.format = SND_AUDIOSTREAMFORMAT_MP4ADTS;
- bits = 16;
- codec.options.aac_dec.audio_obj_type = 29;
- codec.options.aac_dec.pce_bits_size = 0;
+ } else if (format == AAC_ADTS_FORMAT) {
+ uint16_t protection_absent, crc;
+ fread(&adts_header, sizeof(adts_header), 1, file);
+ if (parse_aac_header(&adts_header, &channels, &rate, (unsigned int*)&protection_absent) == -1) {
+ fclose(file);
+ exit(EXIT_FAILURE);
+ }
+ if (!protection_absent) {
+ fread(&crc, 2, 1, file);
+ }
+ codec.id = SND_AUDIOCODEC_AAC;
+ codec.format = SND_AUDIOSTREAMFORMAT_MP4ADTS;
+ bits = 16;
+ codec.options.aac_dec.audio_obj_type = 29;
+ codec.options.aac_dec.pce_bits_size = 0;
#endif
- } else {
- printf("unknown format");
- }
- codec.ch_in = channels;
- codec.ch_out = channels;
- codec.sample_rate = rate;
- if (!codec.sample_rate) {
- fprintf(stderr, "invalid sample rate %d\n", rate);
- fclose(file);
- exit(EXIT_FAILURE);
- }
- codec.bit_rate = bits;
- codec.rate_control = 0;
- codec.profile = 0;
- codec.level = 0;
- codec.ch_mode = 0;
- codec.format = 0;
- if ((buffer_size != 0) && (frag != 0)) {
- config.fragment_size = buffer_size/frag;
- config.fragments = frag;
- } else {
- /* use driver defaults */
- config.fragment_size = 0;
- config.fragments = 0;
- }
- config.codec = &codec;
+ } else {
+ printf("unknown format");
+ }
+ codec.ch_in = channels;
+ codec.ch_out = channels;
+ codec.sample_rate = rate;
+ if (!codec.sample_rate) {
+ fprintf(stderr, "invalid sample rate %d\n", rate);
+ fclose(file);
+ exit(EXIT_FAILURE);
+ }
+ codec.bit_rate = bits;
+ codec.rate_control = 0;
+ codec.profile = 0;
+ codec.level = 0;
+ codec.ch_mode = 0;
+ codec.format = 0;
+ if ((buffer_size != 0) && (frag != 0)) {
+ config.fragment_size = buffer_size/frag;
+ config.fragments = frag;
+ } else {
+ /* use driver defaults */
+ config.fragment_size = 0;
+ config.fragments = 0;
+ }
+ config.codec = &codec;
- mixer = mixer_open(card);
- if (!mixer) {
- printf("Failed to open mixer\n");
- goto FILE_EXIT;
- }
+ mixer = mixer_open(card);
+ if (!mixer) {
+ printf("Failed to open mixer\n");
+ goto FILE_EXIT;
+ }
+ for (index = 0; index < intf_num; index++) {
+ ret = get_device_media_config(BACKEND_CONF_FILE, intf_name[index], &dev_config[index]);
+ if (ret) {
+ printf("Invalid input, entry not found for : %s\n", intf_name[index]);
+ fclose(file);
+ }
+ printf("Backend %s rate ch bit : %d, %d, %d\n", intf_name[index],
+ dev_config[index].rate, dev_config[index].ch, dev_config[index].bits);
- /* set device/audio_intf media config mixer control */
- if (set_agm_device_media_config(mixer, dev_config->ch, dev_config->rate,
- dev_config->bits, intf_name)) {
- printf("Failed to set device media config\n");
- goto MIXER_EXIT;
- }
+ /* set device/audio_intf media config mixer control */
+ if (set_agm_device_media_config(mixer, dev_config[index].ch, dev_config[index].rate,
+ dev_config[index].bits, intf_name[index])) {
+ printf("Failed to set device media config\n");
+ goto MIXER_EXIT;
+ }
- /* set audio interface metadata mixer control */
- if (set_agm_audio_intf_metadata(mixer, intf_name, 0, PLAYBACK,
- dev_config->rate, dev_config->bits, COMPRESSED_OFFLOAD_PLAYBACK)) {
- printf("Failed to set device metadata\n");
- goto MIXER_EXIT;
- }
+ /* set audio interface metadata mixer control */
+ if (set_agm_audio_intf_metadata(mixer, intf_name[index], device_kv[index], PLAYBACK,
+ dev_config[index].rate, dev_config[index].bits, stream_kv)) {
+ printf("Failed to set device metadata\n");
+ goto MIXER_EXIT;
+ }
+ }
- /* set audio interface metadata mixer control */
- if (set_agm_stream_metadata(mixer, device, COMPRESSED_OFFLOAD_PLAYBACK, PLAYBACK, STREAM_COMPRESS, NULL)) {
- printf("Failed to set stream metadata\n");
- goto MIXER_EXIT;
- }
+ /* set audio interface metadata mixer control */
+ if (set_agm_stream_metadata(mixer, device, stream_kv, PLAYBACK, STREAM_COMPRESS,
+ instance_kv)) {
+ printf("Failed to set stream metadata\n");
+ goto MIXER_EXIT;
+ }
- /* Note: No common metadata as of now*/
+ /* Note: No common metadata as of now*/
+ for (index = 0; index < intf_num; index++) {
+ if (devicepp_kv[index] != 0) {
+ if (set_agm_streamdevice_metadata(mixer, device, stream_kv, PLAYBACK, STREAM_COMPRESS, intf_name[index],
+ devicepp_kv[index])) {
+ printf("Failed to set pcm metadata\n");
+ goto MIXER_EXIT;
+ }
+ }
- /* connect stream to audio intf */
- if (connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_COMPRESS, true)) {
- printf("Failed to connect stream to audio interface\n");
- goto MIXER_EXIT;
- }
+ /* connect stream to audio intf */
+ if (connect_agm_audio_intf_to_stream(mixer, device, intf_name[index], STREAM_COMPRESS, true)) {
+ printf("Failed to connect pcm to audio interface\n");
+ goto MIXER_EXIT;
+ }
- if (configure_mfc(mixer, device, intf_name, PER_STREAM_PER_DEVICE_MFC,
- STREAM_COMPRESS, dev_config->rate, dev_config->ch,
- dev_config->bits)) {
- printf("Failed to configure pspd mfc\n");
- goto MIXER_EXIT;
- }
+ ret = agm_mixer_get_miid (mixer, device, intf_name[index], STREAM_PCM, PER_STREAM_PER_DEVICE_MFC, &miid);
+ if (ret) {
+ printf("MFC not present for this graph\n");
+ } else {
+ if (configure_mfc(mixer, device, intf_name[index], PER_STREAM_PER_DEVICE_MFC,
+ STREAM_COMPRESS, dev_config[index].rate, dev_config[index].ch,
+ dev_config[index].bits, miid)) {
+ printf("Failed to configure pspd mfc\n");
+ goto MIXER_EXIT;
+ }
+ }
- compress = compress_open(card, device, COMPRESS_IN, &config);
- if (!compress || !is_compress_ready(compress)) {
- fprintf(stderr, "Unable to open Compress device %d:%d\n",
- card, device);
- fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
- goto MIXER_EXIT;
- };
- if (verbose)
- printf("%s: Opened compress device\n", __func__);
- size = config.fragment_size;
- buffer = malloc(size * config.fragments);
- if (!buffer) {
- fprintf(stderr, "Unable to allocate %d bytes\n", size);
- goto COMP_EXIT;
- }
+ if (strstr(intf_name[index], "VIRT-")) {
+ if (get_group_device_info(BACKEND_CONF_FILE, intf_name[index], &grp_config[index]))
+ goto MIXER_EXIT;
- /* we will write frag fragment_size and then start */
- num_read = fread(buffer, 1, size * config.fragments, file);
- if (num_read > 0) {
- if (verbose)
- printf("%s: Doing first buffer write of %d\n", __func__, num_read);
- wrote = compress_write(compress, buffer, num_read);
- if (wrote < 0) {
- fprintf(stderr, "Error %d playing sample\n", wrote);
- fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
- goto BUF_EXIT;
- }
- if (wrote != num_read) {
- /* TODO: Buufer pointer needs to be set here */
- fprintf(stderr, "We wrote %d, DSP accepted %d\n", num_read, wrote);
- }
- }
- printf("Playing file %s On Card %u device %u, with buffer of %lu bytes\n",
- name, card, device, buffer_size);
- printf("Format %u Channels %u, %u Hz, Bit Rate %d\n",
- SND_AUDIOCODEC_MP3, channels, rate, bits);
+ if (set_agm_group_device_config(mixer, intf_name[index], &grp_config[index])) {
+ printf("Failed to set grp device config\n");
+ goto MIXER_EXIT;
+ }
+ }
+ }
- compress_start(compress);
- if (verbose)
- printf("%s: You should hear audio NOW!!!\n", __func__);
- do {
- num_read = fread(buffer, 1, size, file);
- if (num_read > 0) {
- wrote = compress_write(compress, buffer, num_read);
- if (wrote < 0) {
- fprintf(stderr, "Error playing sample\n");
- fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
- goto BUF_EXIT;
- }
- if (wrote != num_read) {
- /* TODO: Buffer pointer needs to be set here */
- fprintf(stderr, "We wrote %d, DSP accepted %d\n", num_read, wrote);
- }
- if (verbose) {
- print_time(compress);
- printf("%s: wrote %d\n", __func__, wrote);
- }
- if (pause) {
- printf("%s: pause \n", __func__);
- compress_pause(compress);
- sleep(2);
- printf("%s: resume \n", __func__);
- compress_resume(compress);
- }
- }
- } while (num_read > 0);
+ compress = compress_open(card, device, COMPRESS_IN, &config);
+ if (!compress || !is_compress_ready(compress)) {
+ fprintf(stderr, "Unable to open Compress device %d:%d\n",
+ card, device);
+ fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+ goto MIXER_EXIT;
+ };
+ if (verbose)
+ printf("%s: Opened compress device\n", __func__);
- if (verbose)
- printf("%s: exit success\n", __func__);
- /* issue drain if it supports */
- compress_drain(compress);
- /* disconnect stream to audio intf */
- connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_COMPRESS, false);
- free(buffer);
- fclose(file);
- compress_close(compress);
- return;
+ for (index = 0; index < intf_num; index++) {
+ if (strstr(intf_name[index], "VIRT-") || (device_kv[index] == SPEAKER) || (device_kv[index] == HANDSET)) {
+ if (set_agm_group_mux_config(mixer, device, &grp_config[index], intf_name[index], dev_config[index].ch)) {
+ printf("Failed to set grp device config\n");
+ }
+ }
+ }
+ size = config.fragment_size;
+ buffer = malloc(size * config.fragments);
+ if (!buffer) {
+ fprintf(stderr, "Unable to allocate %d bytes\n", size);
+ goto COMP_EXIT;
+ }
+
+ /* we will write frag fragment_size and then start */
+ num_read = fread(buffer, 1, size * config.fragments, file);
+ if (num_read > 0) {
+ if (verbose)
+ printf("%s: Doing first buffer write of %d\n", __func__, num_read);
+ wrote = compress_write(compress, buffer, num_read);
+ if (wrote < 0) {
+ fprintf(stderr, "Error %d playing sample\n", wrote);
+ fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+ goto BUF_EXIT;
+ }
+ if (wrote != num_read) {
+ /* TODO: Buufer pointer needs to be set here */
+ fprintf(stderr, "We wrote %d, DSP accepted %d\n", num_read, wrote);
+ }
+ }
+ printf("Playing file %s On Card %u device %u, with buffer of %lu bytes\n",
+ name, card, device, buffer_size);
+ printf("Format %u Channels %u, %u Hz, Bit Rate %d\n",
+ SND_AUDIOCODEC_MP3, channels, rate, bits);
+
+ compress_start(compress);
+ if (verbose)
+ printf("%s: You should hear audio NOW!!!\n", __func__);
+
+ do {
+ num_read = fread(buffer, 1, size, file);
+ if (num_read > 0) {
+ wrote = compress_write(compress, buffer, num_read);
+ if (wrote < 0) {
+ fprintf(stderr, "Error playing sample\n");
+ fprintf(stderr, "ERR: %s\n", compress_get_error(compress));
+ goto BUF_EXIT;
+ }
+ if (wrote != num_read) {
+ /* TODO: Buffer pointer needs to be set here */
+ fprintf(stderr, "We wrote %d, DSP accepted %d\n", num_read, wrote);
+ }
+ if (verbose) {
+ print_time(compress);
+ printf("%s: wrote %d\n", __func__, wrote);
+ }
+ if (pause) {
+ printf("%s: pause \n", __func__);
+ compress_pause(compress);
+ sleep(2);
+ printf("%s: resume \n", __func__);
+ compress_resume(compress);
+ }
+ }
+ } while (num_read > 0);
+
+ if (verbose)
+ printf("%s: exit success\n", __func__);
+ /* issue drain if it supports */
+ compress_drain(compress);
+ /* disconnect stream to audio intf */
+ for(index = 0; index < intf_num; index++) {
+ connect_agm_audio_intf_to_stream(mixer, device, intf_name[index], STREAM_COMPRESS, false);
+ }
+ free(buffer);
+ fclose(file);
+ compress_close(compress);
+ return;
BUF_EXIT:
- free(buffer);
+ free(buffer);
COMP_EXIT:
- /* disconnect stream to audio intf */
- connect_agm_audio_intf_to_stream(mixer, device, intf_name, STREAM_COMPRESS, false);
- compress_close(compress);
+ compress_close(compress);
MIXER_EXIT:
- mixer_close(mixer);
+ if (dev_config)
+ free(dev_config);
+ if (grp_config)
+ free(grp_config);
+ mixer_close(mixer);
FILE_EXIT:
- fclose(file);
- if (verbose)
- printf("%s: exit failure\n", __func__);
- exit(EXIT_FAILURE);
+ fclose(file);
+ if (verbose)
+ printf("%s: exit failure\n", __func__);
+ exit(EXIT_FAILURE);
}
-
diff --git a/plugins/tinyalsa/test/agmhostless.c b/plugins/tinyalsa/test/agmhostless.c
index d262f0a..9ff4952 100644
--- a/plugins/tinyalsa/test/agmhostless.c
+++ b/plugins/tinyalsa/test/agmhostless.c
@@ -46,25 +46,23 @@
close_f = 1;
}
-char *capture_audio_interface_name[] = {
- "CODEC_DMA-LPAIF_VA-TX-0",
- "CODEC_DMA-LPAIF_VA-TX-1",
- "MI2S-LPAIF_AXI-TX-PRIMARY",
- "TDM-LPAIF_AXI-TX-PRIMARY",
- "AUXPCM-LPAIF_AXI-TX-PRIMARY",
-};
+void play_loopback(unsigned int card, unsigned int p_device, unsigned int c_device, unsigned int channels,
+ unsigned int rate, enum pcm_format format, struct device_config *cap_config,
+ struct device_config *p_config, unsigned int period_size,
+ unsigned int period_count, unsigned int play_cap_time, char* capture_intf,
+ char* play_intf, unsigned int pdkv, unsigned int cdkv, unsigned int stream_kv,
+ unsigned int do_loopback);
-char *playback_audio_interface_name[] = {
- "CODEC_DMA-LPAIF_WSA-RX-0",
- "CODEC_DMA-LPAIF_WSA-RX-1",
- "MI2S-LPAIF_AXI-RX-PRIMARY",
- "TDM-LPAIF_AXI-RX-PRIMARY",
- "AUXPCM-LPAIF_AXI-RX-PRIMARY",
-};
-
-static void play_loopback(unsigned int card, unsigned int p_device, unsigned int c_device, unsigned int channels,
- unsigned int rate, enum pcm_format format, unsigned int period_size,
- unsigned int period_count, unsigned int play_cap_time, unsigned int capture_intf, unsigned int play_intf);
+void usage()
+{
+ printf(" Usage: %s [-D card] [-P Hostless Playback device] [-C Hostless Capture device] [-p period_size]\n"
+ " [-n n_periods] [-c channels] [-r rate] [-b bits] [-T playback/capture time ]\n"
+ " [-i capture intf] [-o playback intf]\n"
+ " [-cdkv capture_device_kv] [-pdkv playback_device_kv] [-skv stream_kv]\n"
+ " Used to enable 'hostless' mode for audio devices with a DSP back-end.\n"
+ " Alternatively, specify '-l' for loopback mode: this program will read\n"
+ " from the capture device and write to the playback device.\n");
+}
int main(int argc, char **argv)
{
@@ -77,34 +75,19 @@
unsigned int num_channels = 2;
unsigned int sample_rate = 48000;
unsigned int play_cap_time = 10;
- unsigned int c_audio_intf = 0;
- unsigned int p_audio_intf = 0;
+ char* c_intf_name = NULL;
+ char* p_intf_name = NULL;
+ unsigned int do_loopback = 0;
enum pcm_format format;
+ struct device_config capture_config;
+ struct device_config play_config;
+ unsigned int c_device_kv = 0;
+ unsigned int p_device_kv = 0;
+ unsigned int stream_kv = 0;
+ unsigned int ret = 0;
if (argc < 2) {
- printf("Usage: %s [-D card] [-P Hostless Playback device] [-C Hostless Capture device] [-p period_size]"
- " [-n n_periods] [-c num_channels] [-r sample_rate] [-T playback/capture time ] [-i capture intf id] [-o playback intf id]\n"
- " valid playback_intf_id :\n"
- "0 : WSA_CDC_DMA_RX_0\n"
- "1 : RX_CDC_DMA_RX_0\n"
- "2 : SLIM_0_RX\n"
- "3 : DISPLAY_PORT_RX\n"
- "4 : PRI_TDM_RX_0\n"
- "5 : SEC_TDM_RX_0\n"
- "6 : AUXPCM_RX\n"
- "7 : SEC_AUXPCM_RX\n"
- "8 : PRI_MI2S_RX\n"
- "9 : SEC_MI2S_RX\n"
- " valid capture_intf_id :\n"
- "0 : TX_CDC_DMA_TX_0\n"
- "1 : SLIM_0_TX\n"
- "2 : PRI_TDM_TX_0\n"
- "3 : SEC_TDM_TX_0\n"
- "4 : AUXPCM_TX\n"
- "5 : SEC_AUXPCM_TX\n"
- "6 : PRI_MI2S_TX\n"
- "7 : SEC_MI2S_TX\n",
- argv[0]);
+ usage();
return 1;
}
@@ -115,67 +98,84 @@
argv++;
if (*argv)
p_device = atoi(*argv);
- }
- if (strcmp(*argv, "-C") == 0) {
+ } else if (strcmp(*argv, "-C") == 0) {
argv++;
if (*argv)
c_device = atoi(*argv);
- }
- if (strcmp(*argv, "-p") == 0) {
+ } else if (strcmp(*argv, "-p") == 0) {
argv++;
if (*argv)
period_size = atoi(*argv);
- }
- if (strcmp(*argv, "-n") == 0) {
+ } else if (strcmp(*argv, "-n") == 0) {
argv++;
if (*argv)
period_count = atoi(*argv);
- }
- if (strcmp(*argv, "-c") == 0) {
+ } else if (strcmp(*argv, "-c") == 0) {
argv++;
if (*argv)
num_channels = atoi(*argv);
- }
- if (strcmp(*argv, "-r") == 0) {
+ } else if (strcmp(*argv, "-r") == 0) {
argv++;
if (*argv)
sample_rate = atoi(*argv);
- }
-
- if (strcmp(*argv, "-T") == 0) {
+ } else if (strcmp(*argv, "-b") == 0) {
+ argv++;
+ if (*argv)
+ bits = atoi(*argv);
+ } else if (strcmp(*argv, "-T") == 0) {
argv++;
if (*argv)
play_cap_time = atoi(*argv);
- }
-
- if (strcmp(*argv, "-D") == 0) {
+ } else if (strcmp(*argv, "-D") == 0) {
argv++;
if (*argv)
card = atoi(*argv);
- }
- if (strcmp(*argv, "-i") == 0) {
+ } else if (strcmp(*argv, "-i") == 0) {
argv++;
if (*argv)
- c_audio_intf = atoi(*argv);
- if (c_audio_intf >= sizeof(capture_audio_interface_name)/sizeof(char *)) {
- printf("Invalid audio interface index denoted by -i\n");
- return 1;
- }
- }
- if (strcmp(*argv, "-o") == 0) {
+ c_intf_name = *argv;
+ } else if (strcmp(*argv, "-o") == 0) {
argv++;
if (*argv)
- p_audio_intf = atoi(*argv);
- if (p_audio_intf >= sizeof(playback_audio_interface_name)/sizeof(char *)) {
- printf("Invalid audio interface index denoted by -i\n");
- return 1;
- }
+ p_intf_name = *argv;
+ } else if (strcmp(*argv, "-l") == 0) {
+ do_loopback = 1;
+ } else if (strcmp(*argv, "-skv") == 0) {
+ argv++;
+ if (*argv)
+ stream_kv = convert_char_to_hex(*argv);
+ } else if (strcmp(*argv, "-cdkv") == 0) {
+ argv++;
+ if (*argv)
+ c_device_kv = convert_char_to_hex(*argv);
+ } else if (strcmp(*argv, "-pdkv") == 0) {
+ argv++;
+ if (*argv)
+ p_device_kv = convert_char_to_hex(*argv);
+ } else if (strcmp(*argv, "-help") == 0) {
+ usage();
}
if (*argv)
argv++;
}
+ ret = get_device_media_config(BACKEND_CONF_FILE, c_intf_name, &capture_config);
+ if (ret) {
+ printf("Invalid input, assigning default values for : %s\n", c_intf_name);
+ capture_config.rate = sample_rate;
+ capture_config.bits = bits;
+ capture_config.ch = num_channels;
+ }
+
+ ret = get_device_media_config(BACKEND_CONF_FILE, p_intf_name, &play_config);
+ if (ret) {
+ printf("Invalid input, assigning default values for : %s\n", p_intf_name);
+ play_config.rate = sample_rate;
+ play_config.bits = bits;
+ play_config.ch = num_channels;
+ }
+
switch (bits) {
case 32:
format = PCM_FORMAT_S32_LE;
@@ -190,33 +190,33 @@
printf("%u bits is not supported.\n", bits);
return 1;
}
-
- signal(SIGINT, sigint_handler);
- signal(SIGHUP, sigint_handler);
- signal(SIGTERM, sigint_handler);
-
- play_loopback(card, p_device, c_device, num_channels, sample_rate,
- format, period_size, period_count, play_cap_time,
- c_audio_intf, p_audio_intf);
+ play_loopback(card, p_device, c_device, num_channels, sample_rate, format, &capture_config, &play_config, period_size,
+ period_count, play_cap_time, c_intf_name, p_intf_name, p_device_kv,
+ c_device_kv, stream_kv, do_loopback);
return 0;
}
void play_loopback(unsigned int card, unsigned int p_device, unsigned int c_device, unsigned int channels,
- unsigned int rate, enum pcm_format format, unsigned int period_size,
- unsigned int period_count, unsigned int play_cap_time, unsigned int capture_intf, unsigned int play_intf)
+ unsigned int rate, enum pcm_format format, struct device_config *cap_config,
+ struct device_config *p_config, unsigned int period_size,
+ unsigned int period_count, unsigned int play_cap_time, char* capture_intf,
+ char* play_intf, unsigned int pdkv, unsigned int cdkv, unsigned int stream_kv,
+ unsigned int do_loopback)
{
struct pcm_config config;
struct pcm *p_pcm, *c_pcm;
struct mixer *mixer;
- char *buffer;
- char *p_intf_name = playback_audio_interface_name[play_intf];
- char *c_intf_name = capture_audio_interface_name[capture_intf];
+ char *buffer = NULL;
+ char *p_intf_name = play_intf;
+ char *c_intf_name = capture_intf;
unsigned int size;
unsigned int bytes_read = 0;
- unsigned int frames = 0;
+ unsigned int frames = 0, ret = 0, miid = 0;
struct timespec end;
struct timespec now;
+ struct group_config grp_config;
+ stream_kv = stream_kv ? stream_kv : PCM_RX_LOOPBACK;
memset(&config, 0, sizeof(config));
config.channels = channels;
@@ -235,30 +235,31 @@
}
/* set device/audio_intf media config mixer control */
- if (set_agm_device_media_config(mixer, channels, rate,
- pcm_format_to_bits(format), p_intf_name)) {
+ if (set_agm_device_media_config(mixer, p_config->ch, p_config->rate,
+ p_config->bits, p_intf_name)) {
printf("Failed to set playback device media config\n");
goto err_close_mixer;
}
- if (set_agm_device_media_config(mixer, channels, rate,
- pcm_format_to_bits(format), c_intf_name)) {
+ if (set_agm_device_media_config(mixer, cap_config->ch, cap_config->rate,
+ cap_config->bits, c_intf_name)) {
printf("Failed to set capture device media config\n");
goto err_close_mixer;
}
/* set audio interface metadata mixer control */
- if (set_agm_audio_intf_metadata(mixer, c_intf_name, 0, CAPTURE, rate, pcm_format_to_bits(format), PCM_RX_LOOPBACK)) {
+ if (set_agm_audio_intf_metadata(mixer, c_intf_name, cdkv, CAPTURE, rate, cap_config->bits, stream_kv)) {
printf("Failed to set capture device metadata\n");
goto err_close_mixer;
}
- if (set_agm_audio_intf_metadata(mixer, p_intf_name, 0, PLAYBACK, rate, pcm_format_to_bits(format), PCM_RX_LOOPBACK)) {
+ if (set_agm_audio_intf_metadata(mixer, p_intf_name, pdkv, PLAYBACK, rate, p_config->bits, stream_kv)) {
printf("Failed to set playback device metadata\n");
goto err_close_mixer;
}
- if (set_agm_stream_metadata(mixer, c_device, PCM_RX_LOOPBACK, LOOPBACK, STREAM_PCM, NULL)) {
+ if (set_agm_stream_metadata(mixer, c_device, stream_kv, LOOPBACK, STREAM_PCM,
+ 0)) {
printf("Failed to capture stream metadata\n");
goto err_close_mixer;
}
@@ -282,11 +283,38 @@
goto err_disconnect;
}
+ if (strstr(p_intf_name, "VIRT-")) {
+ if (get_group_device_info(BACKEND_CONF_FILE, p_intf_name, &grp_config))
+ goto err_disconnect;
+
+ if (set_agm_group_device_config(mixer, p_intf_name, &grp_config)) {
+ printf("Failed to set grp device config\n");
+ goto err_disconnect;
+ }
+ }
+ ret = agm_mixer_get_miid (mixer, p_device, p_intf_name, STREAM_PCM, PER_STREAM_PER_DEVICE_MFC, &miid);
+ if (ret) {
+ printf("MFC not present for this graph\n");
+ } else {
+ if (configure_mfc(mixer, p_device, p_intf_name, PER_STREAM_PER_DEVICE_MFC,
+ STREAM_PCM, p_config->rate, p_config->ch,
+ p_config->bits, miid)) {
+ printf("Failed to configure pspd mfc\n");
+ goto err_disconnect;
+ }
+ }
+
p_pcm = pcm_open(card, p_device, PCM_OUT, &config);
if (!p_pcm || !pcm_is_ready(p_pcm)) {
printf("Unable to open playback PCM device (%s)\n",
pcm_get_error(p_pcm));
- goto err_close_c_pcm;
+ goto err_disconnect;
+ }
+ if (strstr(p_intf_name, "VIRT-") || (pdkv == SPEAKER) || (pdkv == HANDSET)) {
+ if (set_agm_group_mux_config(mixer, p_device, &grp_config, p_intf_name, p_config->ch)) {
+ printf("Failed to set mux config\n");
+ goto err_close_p_pcm;
+ }
}
if (pcm_start(p_pcm) < 0) {
@@ -298,7 +326,7 @@
if (!c_pcm || !pcm_is_ready(c_pcm)) {
printf("Unable to open playback PCM device (%s)\n",
pcm_get_error(c_pcm));
- goto err_disconnect;
+ goto err_close_p_pcm;
}
if (pcm_start(c_pcm) < 0) {
@@ -306,11 +334,34 @@
goto err_close_c_pcm;
}
+ if (do_loopback) {
+ size = pcm_frames_to_bytes(c_pcm, pcm_get_buffer_size(c_pcm));
+ buffer = malloc(size);
+ if (!buffer) {
+ printf("Unable to allocate %d bytes\n", size);
+ goto err_close_c_pcm;
+ }
+ }
+
clock_gettime(CLOCK_MONOTONIC, &end);
end.tv_sec += play_cap_time;
while (1) {
if (close_f)
break;
+ if (do_loopback) {
+ if (pcm_read(c_pcm, buffer, size)) {
+ printf("Unable to read from PCM capture device %u (%s)\n",
+ c_device, pcm_get_error(c_pcm));
+ break;
+ }
+ if (pcm_write(p_pcm, buffer, size)) {
+ printf("Unable to write to PCM playback device %u (%s)\n",
+ p_device, pcm_get_error(p_pcm));
+ break;
+ }
+ } else {
+ usleep(100000);
+ }
if (play_cap_time) {
clock_gettime(CLOCK_MONOTONIC, &now);
@@ -320,10 +371,12 @@
}
}
connect_play_pcm_to_cap_pcm(mixer, -1, c_device);
-err_close_p_pcm:
- pcm_close(p_pcm);
err_close_c_pcm:
pcm_close(c_pcm);
+err_close_p_pcm:
+ if (buffer)
+ free(buffer);
+ pcm_close(p_pcm);
err_disconnect:
connect_agm_audio_intf_to_stream(mixer, p_device, p_intf_name, STREAM_PCM, false);
connect_agm_audio_intf_to_stream(mixer, c_device, c_intf_name, STREAM_PCM, false);
diff --git a/plugins/tinyalsa/test/agmmixer.c b/plugins/tinyalsa/test/agmmixer.c
index 40714be..b7ef20c 100644
--- a/plugins/tinyalsa/test/agmmixer.c
+++ b/plugins/tinyalsa/test/agmmixer.c
@@ -88,25 +88,28 @@
struct gsl_module_id_info_entry {
- uint32_t module_id; /**< module id */
- uint32_t module_iid; /**< globally unique module instance id */
+ uint32_t module_id; /**< module id */
+ uint32_t module_iid; /**< globally unique module instance id */
};
/**
* Structure mapping the tag_id to module info (mid and miid)
*/
struct gsl_tag_module_info_entry {
- uint32_t tag_id; /**< tag id of the module */
- uint32_t num_modules; /**< number of modules matching the tag_id */
- struct gsl_module_id_info_entry module_entry[0]; /**< module list */
+ uint32_t tag_id; /**< tag id of the module */
+ uint32_t num_modules; /**< number of modules matching the tag_id */
+ struct gsl_module_id_info_entry module_entry[0]; /**< module list */
};
struct gsl_tag_module_info {
- uint32_t num_tags; /**< number of tags */
- struct gsl_tag_module_info_entry tag_module_entry[0];
- /**< variable payload of type struct gsl_tag_module_info_entry */
+ uint32_t num_tags; /**< number of tags */
+ struct gsl_tag_module_info_entry tag_module_entry[0];
+ /**< variable payload of type struct gsl_tag_module_info_entry */
};
+unsigned int slot_mask_map[5] = { 0, SLOT_MASK1, SLOT_MASK3, SLOT_MASK7, SLOT_MASK15};
+
+
#define PADDING_8BYTE_ALIGN(x) ((((x) + 7) & 7) ^ 7)
static unsigned int bits_to_alsa_format(unsigned int bits)
@@ -367,7 +370,7 @@
return ret;
}
-int set_agm_group_mux_config(struct mixer *mixer, unsigned int device, struct group_config *config, char *intf_name)
+int set_agm_group_mux_config(struct mixer *mixer, unsigned int device, struct group_config *config, char *intf_name, unsigned int channels)
{
char *stream = "PCM";
char *control = "setParamTag";
@@ -376,6 +379,7 @@
int ctl_len = 0, val_len;
int ret = 0;
struct agm_tag_config* tag_config = NULL;
+ uint32_t miid = 0;
ret = set_agm_stream_metadata_type(mixer, device, intf_name, STREAM_PCM);
if (ret)
@@ -403,7 +407,11 @@
tag_config->tag = TAG_DEVICE_MUX;
tag_config->num_tkvs = 1;
tag_config->kv[0].key = TAG_KEY_SLOT_MASK;
- tag_config->kv[0].value = config->slot_mask;
+ ret = agm_mixer_get_miid(mixer, device, intf_name, STREAM_PCM, TAG_DEVICE_MUX, &miid);
+ if (ret)
+ tag_config->kv[0].value = config->slot_mask;
+ else
+ tag_config->kv[0].value = slot_mask_map[channels];
mixer_ctl_set_array(ctl, tag_config, val_len);
done:
@@ -607,7 +615,7 @@
gkv[0].value = HAPTICS_DEVICE;
} else if (val == VOICE_UI) {
gkv[0].key = DEVICETX;
- gkv[0].value = HANDSETMIC_VA;
+ gkv[0].value = dkv ? dkv : HANDSETMIC_VA;
} else {
gkv[0].key = DEVICETX;
gkv[0].value = dkv ? dkv : HANDSETMIC;
@@ -743,22 +751,15 @@
int configure_mfc(struct mixer *mixer, int device, char *intf_name, int tag,
enum stream_type stype, unsigned int rate,
- unsigned int channels, unsigned int bits)
+ unsigned int channels, unsigned int bits, uint32_t miid)
{
int ret = 0;
- uint32_t miid = 0;
struct apm_module_param_data_t* header = NULL;
struct param_id_mfc_output_media_fmt_t *mfcConf;
uint16_t* pcmChannel = NULL;
uint8_t* payloadInfo = NULL;
size_t payloadSize = 0, padBytes = 0, size;
- ret = agm_mixer_get_miid(mixer, device, intf_name, stype, tag, &miid);
- if (ret) {
- printf("%s Get MIID from tag data failed\n", __func__);
- return ret;
- }
-
payloadSize = sizeof(struct apm_module_param_data_t) +
sizeof(struct param_id_mfc_output_media_fmt_t) +
sizeof(uint16_t)*channels;
@@ -792,7 +793,7 @@
}
int set_agm_capture_stream_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type usecase,
- enum stream_type stype, unsigned int dev_channels)
+ enum stream_type stype, unsigned int instance_kv)
{
char *stream = "PCM";
char *control = "metadata";
@@ -801,11 +802,18 @@
uint8_t *metadata = NULL;
struct agm_key_value *gkv = NULL, *ckv = NULL;
struct prop_data *prop = NULL;
- uint32_t num_gkv = 2, num_ckv = 1, num_props = 0;
+ uint32_t num_gkv = 1, num_ckv = 1, num_props = 0;
uint32_t gkv_size, ckv_size, prop_size, index = 0;
int ctl_len = 0, ret = 0, offset = 0;
char *type = "ZERO";
+ ret = set_agm_stream_metadata_type(mixer, device, type, stype);
+ if (ret)
+ return ret;
+
+ if (instance_kv != 0)
+ num_gkv += 1;
+
gkv_size = num_gkv * sizeof(struct agm_key_value);
ckv_size = num_ckv * sizeof(struct agm_key_value);
prop_size = sizeof(struct prop_data) + (num_props * sizeof(uint32_t));
@@ -830,9 +838,11 @@
gkv[index].value = val;
index++;
- gkv[index].key = INSTANCE;
- gkv[index].value = INSTANCE_1;
- index++;
+ if (instance_kv != 0) {
+ gkv[index].key = INSTANCE;
+ gkv[index].value = instance_kv;
+ index++;
+ }
index = 0;
ckv[index].key = VOLUME;
@@ -878,22 +888,20 @@
return ret;
}
-int set_agm_stream_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type usecase, enum stream_type stype, char *intf_name)
+int set_agm_streamdevice_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type usecase,
+ enum stream_type stype, char *intf_name,
+ unsigned int devicepp_kv)
{
char *stream = "PCM";
char *control = "metadata";
char *mixer_str;
struct mixer_ctl *ctl;
uint8_t *metadata = NULL;
- struct agm_key_value *gkv = NULL, *ckv = NULL;
- struct prop_data *prop = NULL;
- uint32_t num_gkv = 2, num_ckv = 1, num_props = 0;
- uint32_t gkv_size, ckv_size, prop_size, index = 0;
+ struct agm_key_value *gkv = NULL;
+ uint32_t num_gkv = 2;
+ uint32_t gkv_size, index = 0;
int ctl_len = 0, ret = 0, offset = 0;
- char *type = "ZERO";
-
- if (intf_name)
- type = intf_name;
+ char *type = intf_name;
ret = set_agm_stream_metadata_type(mixer, device, type, stype);
if (ret)
@@ -902,17 +910,100 @@
if (stype == STREAM_COMPRESS)
stream = "COMPRESS";
- if (val == PCM_LL_PLAYBACK || val == COMPRESSED_OFFLOAD_PLAYBACK || val == PCM_RECORD)
- num_gkv += 1;
+ gkv_size = num_gkv * sizeof(struct agm_key_value);
- if (val == HAPTICS_PLAYBACK)
- num_gkv = 1;
+ metadata = calloc(1, sizeof(num_gkv) + gkv_size);
+ if (!metadata)
+ return -ENOMEM;
+
+ gkv = calloc(num_gkv, sizeof(struct agm_key_value));
+ if (!gkv) {
+ free(metadata);
+ return -ENOMEM;
+ }
+ if (val == VOICE_UI) {
+ gkv[index].key = STREAMTX;
+ gkv[index].value = val;
+ index++;
+ } else if (usecase == PLAYBACK) {
+ gkv[index].key = STREAMRX;
+ gkv[index].value = val;
+ index++;
+ } else if (usecase == CAPTURE) {
+ gkv[index].key = STREAMRX;
+ gkv[index].value = val;
+ index++;
+ }
+ if (val == VOICE_UI) {
+ gkv[index].key = DEVICEPP_TX;
+ gkv[index].value = devicepp_kv;
+ index++;
+ } else if (usecase == PLAYBACK) {
+ gkv[index].key = DEVICEPP_RX;
+ gkv[index].value = devicepp_kv;
+ index++;
+ } else if (usecase == CAPTURE) {
+ gkv[index].key = DEVICEPP_TX;
+ gkv[index].value = devicepp_kv;
+ index++;
+ }
+
+ memcpy(metadata, &num_gkv, sizeof(num_gkv));
+ offset += sizeof(num_gkv);
+ memcpy(metadata + offset, gkv, gkv_size);
+ offset += gkv_size;
+
+ ctl_len = strlen(stream) + 4 + strlen(control) + 1;
+ mixer_str = calloc(1, ctl_len);
+ if (!mixer_str) {
+ free(metadata);
+ return -ENOMEM;
+ }
+ snprintf(mixer_str, ctl_len, "%s%d %s", stream, device, control);
+ ctl = mixer_get_ctl_by_name(mixer, mixer_str);
+ if (!ctl) {
+ printf("Invalid mixer control: %s\n", mixer_str);
+ free(gkv);
+ free(metadata);
+ free(mixer_str);
+ return ENOENT;
+ }
+
+ ret = mixer_ctl_set_array(ctl, metadata, sizeof(num_gkv) + gkv_size);
+
+ free(gkv);
+ free(metadata);
+ free(mixer_str);
+ return ret;
+}
+
+int set_agm_stream_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type usecase,
+ enum stream_type stype, unsigned int instance_kv)
+{
+ char *stream = "PCM";
+ char *control = "metadata";
+ char *mixer_str;
+ struct mixer_ctl *ctl;
+ uint8_t *metadata = NULL;
+ struct agm_key_value *gkv = NULL, *ckv = NULL;
+ struct prop_data *prop = NULL;
+ uint32_t num_gkv = 1, num_ckv = 1, num_props = 0;
+ uint32_t gkv_size, ckv_size, prop_size, index = 0;
+ int ctl_len = 0, ret = 0, offset = 0;
+ char *type = "ZERO";
+
+ ret = set_agm_stream_metadata_type(mixer, device, type, stype);
+ if (ret)
+ return ret;
+
+ if (stype == STREAM_COMPRESS)
+ stream = "COMPRESS";
+
+ if (instance_kv != 0)
+ num_gkv += 1;
if (val == VOICE_UI) {
- if (intf_name)
- num_gkv = 2;
- else
- num_gkv = 3;
+ num_gkv = 3;
}
gkv_size = num_gkv * sizeof(struct agm_key_value);
@@ -936,48 +1027,31 @@
}
if (val == VOICE_UI) {
- if (intf_name) {
- gkv[index].key = DEVICEPP_TX;
- gkv[index].value = DEVICEPP_TX_FLUENCE_FFECNS;
- index++;
- gkv[index].key = DEVICETX;
- gkv[index].value = HANDSETMIC;
- index++;
- } else {
- gkv[index].key = STREAMTX;
- gkv[index].value = val;
- index++;
+ gkv[index].key = STREAMTX;
+ gkv[index].value = val;
+ index++;
+ if (instance_kv != 0){
gkv[index].key = INSTANCE;
- gkv[index].value = INSTANCE_1;
- index++;
- gkv[index].key = STREAM_CONFIG;
- gkv[index].value = STREAM_CFG_VUI_SVA;
+ gkv[index].value = instance_kv;
index++;
}
- } else {
- if (usecase == PLAYBACK)
- gkv[index].key = STREAMRX;
- else
- gkv[index].key = STREAMTX;
-
+ gkv[index].key = STREAM_CONFIG;
+ gkv[index].value = STREAM_CFG_VUI_SVA;
+ index++;
+ } else if (usecase == PLAYBACK) {
+ gkv[index].key = STREAMRX;
gkv[index].value = val;
index++;
- if (val == PCM_LL_PLAYBACK || val == COMPRESSED_OFFLOAD_PLAYBACK ||
- val == PCM_RECORD) {
+ if (instance_kv != 0) {
printf("Instance key is added\n");
gkv[index].key = INSTANCE;
- gkv[index].value = INSTANCE_1;
+ gkv[index].value = instance_kv;
index++;
}
-
- if (usecase == PLAYBACK && val != HAPTICS_PLAYBACK) {
- gkv[index].key = DEVICEPP_RX;
- gkv[index].value = DEVICEPP_RX_AUDIO_MBDRC;
- } else if (val != HAPTICS_PLAYBACK) {
- gkv[index].key = DEVICEPP_TX;
- gkv[index].value = DEVICEPP_TX_AUDIO_FLUENCE_SMECNS;
- }
+ } else if (usecase == LOOPBACK) {
+ gkv[index].key = STREAMRX;
+ gkv[index].value = val;
}
index = 0;
diff --git a/plugins/tinyalsa/test/agmmixer.h b/plugins/tinyalsa/test/agmmixer.h
index ee293f2..15e0402 100644
--- a/plugins/tinyalsa/test/agmmixer.h
+++ b/plugins/tinyalsa/test/agmmixer.h
@@ -60,16 +60,27 @@
unsigned int slot_mask;
};
+typedef enum {
+ SLOT_MASK1 = 1,
+ SLOT_MASK3 = 3,
+ SLOT_MASK7 = 7,
+ SLOT_MASK15 = 15,
+}slot_mask_t;
+
int convert_char_to_hex(char *char_num);
int set_agm_device_media_config(struct mixer *mixer, unsigned int channels,
unsigned int rate, unsigned int bits, char *intf_name);
int set_agm_group_device_config(struct mixer *mixer, char *intf_name, struct group_config *config);
-int set_agm_group_mux_config(struct mixer *mixer, unsigned int device, struct group_config *config, char *intf_name);
+int set_agm_group_mux_config(struct mixer *mixer, unsigned int device, struct group_config *config, char *intf_name, unsigned int channels);
int connect_play_pcm_to_cap_pcm(struct mixer *mixer, unsigned int p_device, unsigned int c_device);
int set_agm_audio_intf_metadata(struct mixer *mixer, char *intf_name, unsigned int dkv, enum usecase_type, int rate, int bitwidth, uint32_t val);
int set_agm_stream_metadata_type(struct mixer *mixer, int device, char *val, enum stream_type stype);
-int set_agm_stream_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type utype, enum stream_type stype, char *intf_name);
-int set_agm_capture_stream_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type utype, enum stream_type stype, unsigned int dev_channels);
+int set_agm_streamdevice_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type usecase, enum stream_type stype,
+ char *intf_name, unsigned int devicepp_kv);
+int set_agm_stream_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type utype, enum stream_type stype,
+ unsigned int instance_kv);
+int set_agm_capture_stream_metadata(struct mixer *mixer, int device, uint32_t val, enum usecase_type utype, enum stream_type stype,
+ unsigned int instance_kv);
int connect_agm_audio_intf_to_stream(struct mixer *mixer, unsigned int device,
char *intf_name, enum stream_type, bool connect);
int agm_mixer_register_event(struct mixer *mixer, int device, enum stream_type stype, uint32_t miid, uint8_t is_register);
@@ -84,5 +95,5 @@
int get_device_media_config(char* filename, char *intf_name, struct device_config *config);
int get_group_device_info(char* filename, char *intf_name, struct group_config *config);
int configure_mfc(struct mixer *mixer, int device, char *intf_name, int tag, enum stream_type stype, unsigned int rate,
- unsigned int channels, unsigned int bits);
+ unsigned int channels, unsigned int bits, uint32_t miid);
#endif
diff --git a/plugins/tinyalsa/test/agmplay.c b/plugins/tinyalsa/test/agmplay.c
index 43258b3..3b3386e 100644
--- a/plugins/tinyalsa/test/agmplay.c
+++ b/plugins/tinyalsa/test/agmplay.c
@@ -66,8 +66,9 @@
static int close = 0;
-void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int device_kv,
- struct chunk_fmt fmt, struct device_config *dev_config, bool haptics);
+void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int *device_kv,
+ unsigned int stream_kv, unsigned int instance_kv, unsigned int *devicepp_kv,
+ struct chunk_fmt fmt, bool haptics, char **intf_name, int intf_num);
void stream_close(int sig)
{
@@ -76,24 +77,37 @@
close = 1;
}
+static void usage(void)
+{
+ printf(" Usage: %s file.wav [-help print usage] [-D card] [-d device]\n"
+ " [-num_intf num of interfaces followed by interface name]\n"
+ " [-i intf_name] : Can be multiple if num_intf is more than 1\n"
+ " [-dkv device_kv] : Can be multiple if num_intf is more than 1\n"
+ " [-dppkv deviceppkv] : Assign 0 if no device pp in the graph\n"
+ " [-ikv instance_kv] : Assign 0 if no instance kv in the graph\n"
+ " [-skv stream_kv] [-h haptics usecase]\n");
+}
+
int main(int argc, char **argv)
{
FILE *file;
struct riff_wave_header riff_wave_header;
struct chunk_header chunk_header;
struct chunk_fmt chunk_fmt;
- unsigned int card = 100, device = 100;
- unsigned int device_kv = 0;
+ unsigned int card = 100, device = 100, i=0;
+ int intf_num = 1;
+ unsigned int *device_kv = 0;
+ unsigned int stream_kv = 0;
+ unsigned int instance_kv = INSTANCE_1;
+ unsigned int *devicepp_kv = NULL;
bool haptics = false;
- char *intf_name = NULL;
+ char **intf_name = NULL;
struct device_config config;
char *filename;
int more_chunks = 1, ret = 0;
if (argc < 3) {
- printf("Usage: %s file.wav [-D card] [-d device] [-i device_id] [-h haptics]",
- " [-dkv device_kv]\n",
- argv[0]);
+ usage();
return 1;
}
@@ -143,51 +157,97 @@
argv++;
if (*argv)
card = atoi(*argv);
- } else if (strcmp(*argv, "-i") == 0) {
+ } else if (strcmp(*argv, "-num_intf") == 0) {
argv++;
if (*argv)
- intf_name = *argv;
+ intf_num = atoi(*argv);
+ } else if (strcmp(*argv, "-i") == 0) {
+ intf_name = (char**) malloc(intf_num * sizeof(char*));
+ if (!intf_name) {
+ printf("invalid memory\n");
+ }
+ for (i = 0; i < intf_num ; i++){
+ argv++;
+ if (*argv)
+ intf_name[i] = *argv;
+ }
} else if (strcmp(*argv, "-h") == 0) {
argv++;
if (*argv)
haptics = *argv;
} else if (strcmp(*argv, "-dkv") == 0) {
+ device_kv = (unsigned int *) malloc(intf_num * sizeof(unsigned int));
+ if (!device_kv) {
+ printf(" insufficient memory\n");
+ }
+ for (i = 0; i < intf_num ; i++) {
+ argv++;
+ if (*argv) {
+ device_kv[i] = convert_char_to_hex(*argv);
+ }
+ }
+ } else if (strcmp(*argv, "-skv") == 0) {
argv++;
if (*argv)
- device_kv = convert_char_to_hex(*argv);
+ stream_kv = convert_char_to_hex(*argv);
+ } else if (strcmp(*argv, "-ikv") == 0) {
+ argv++;
+ if (*argv) {
+ instance_kv = atoi(*argv);
+ }
+ } else if (strcmp(*argv, "-dppkv") == 0) {
+ devicepp_kv = (unsigned int *) malloc(intf_num * sizeof(unsigned int));
+ if (!devicepp_kv) {
+ printf(" insufficient memory\n");
+ }
+ for (i = 0; i < intf_num ; i++) {
+ devicepp_kv[i] = DEVICEPP_RX_AUDIO_MBDRC;
+ }
+ for (i = 0; i < intf_num ; i++)
+ {
+ argv++;
+ if (*argv) {
+ devicepp_kv[i] = convert_char_to_hex(*argv);
+ }
+ }
+ } else if (strcmp(*argv, "-help") == 0) {
+ usage();
}
if (*argv)
argv++;
}
- if (intf_name == NULL)
+ if (*intf_name == NULL)
return 1;
- ret = get_device_media_config(BACKEND_CONF_FILE, intf_name, &config);
- if (ret) {
- printf("Invalid input, entry not found for : %s\n", intf_name);
- fclose(file);
- return ret;
- }
- play_sample(file, card, device, device_kv, chunk_fmt, &config, haptics);
+ play_sample(file, card, device, device_kv, stream_kv, instance_kv, devicepp_kv,
+ chunk_fmt, haptics, intf_name, intf_num);
fclose(file);
+ if (device_kv)
+ free(device_kv);
+ if (devicepp_kv)
+ free(devicepp_kv);
+ if (intf_name)
+ free(intf_name);
return 0;
}
-void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int device_kv,
- struct chunk_fmt fmt, struct device_config *dev_config, bool haptics)
+void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int *device_kv,
+ unsigned int stream_kv, unsigned int instance_kv, unsigned int *devicepp_kv,
+ struct chunk_fmt fmt, bool haptics, char **intf_name, int intf_num)
{
struct pcm_config config;
struct pcm *pcm;
struct mixer *mixer;
char *buffer;
int playback_path, playback_value;
- int size;
+ int size, index, ret = 0;
int num_read;
- char *name = dev_config->name;
- struct group_config grp_config;
+ struct group_config *grp_config = (struct group_config *)malloc(intf_num*sizeof(struct group_config *));
+ struct device_config *dev_config = (struct device_config *)malloc(intf_num*sizeof(struct device_config *));
+ uint32_t miid = 0;
memset(&config, 0, sizeof(config));
config.channels = fmt.num_channels;
@@ -204,62 +264,87 @@
config.stop_threshold = 0;
config.silence_threshold = 0;
- printf("Backend %s rate ch bit : %d, %d, %d\n", name,
- dev_config->rate, dev_config->ch, dev_config->bits);
mixer = mixer_open(card);
if (!mixer) {
printf("Failed to open mixer\n");
return;
}
- /* set device/audio_intf media config mixer control */
- if (set_agm_device_media_config(mixer, dev_config->ch, dev_config->rate,
- dev_config->bits, name)) {
- printf("Failed to set device media config\n");
- goto err_close_mixer;
- }
-
if (haptics) {
playback_path = HAPTICS;
- playback_value = HAPTICS_PLAYBACK;
+ stream_kv = stream_kv ? stream_kv : HAPTICS_PLAYBACK;
} else {
playback_path = PLAYBACK;
- playback_value = PCM_LL_PLAYBACK;
+ stream_kv = stream_kv ? stream_kv : PCM_LL_PLAYBACK;
}
- /* set audio interface metadata mixer control */
- if (set_agm_audio_intf_metadata(mixer, name, device_kv, playback_path,
- dev_config->rate, dev_config->bits, PCM_LL_PLAYBACK)) {
- printf("Failed to set device metadata\n");
- goto err_close_mixer;
+
+ for (index = 0; index < intf_num; index++) {
+ ret = get_device_media_config(BACKEND_CONF_FILE, intf_name[index], &dev_config[index]);
+ if (ret) {
+ printf("Invalid input, entry not found for : %s\n", intf_name[index]);
+ fclose(file);
+ }
+ printf("Backend %s rate ch bit : %d, %d, %d\n", intf_name[index],
+ dev_config[index].rate, dev_config[index].ch, dev_config[index].bits);
+
+ /* set device/audio_intf media config mixer control */
+ if (set_agm_device_media_config(mixer, dev_config[index].ch, dev_config[index].rate,
+ dev_config[index].bits, intf_name[index])) {
+ printf("Failed to set device media config\n");
+ goto err_close_mixer;
+ }
+
+ /* set audio interface metadata mixer control */
+ if (set_agm_audio_intf_metadata(mixer, intf_name[index], device_kv[index], playback_path,
+ dev_config[index].rate, dev_config[index].bits, stream_kv)) {
+ printf("Failed to set device metadata\n");
+ goto err_close_mixer;
+ }
}
+
/* set audio interface metadata mixer control */
- if (set_agm_stream_metadata(mixer, device, playback_value, PLAYBACK, STREAM_PCM, NULL)) {
+ if (set_agm_stream_metadata(mixer, device, stream_kv, PLAYBACK, STREAM_PCM,
+ instance_kv)) {
printf("Failed to set pcm metadata\n");
goto err_close_mixer;
}
- /* Note: No common metadata as of now*/
+ /* Note: No common metadata as of now*/
+ for (index = 0; index < intf_num; index++) {
+ if (devicepp_kv[index] != 0) {
+ if (set_agm_streamdevice_metadata(mixer, device, stream_kv, PLAYBACK, STREAM_PCM, intf_name[index],
+ devicepp_kv[index])) {
+ printf("Failed to set pcm metadata\n");
+ goto err_close_mixer;
+ }
+ }
- /* connect pcm stream to audio intf */
- if (connect_agm_audio_intf_to_stream(mixer, device, name, STREAM_PCM, true)) {
- printf("Failed to connect pcm to audio interface\n");
- goto err_close_mixer;
- }
-
- if (configure_mfc(mixer, device, name, PER_STREAM_PER_DEVICE_MFC,
- STREAM_PCM, dev_config->rate, dev_config->ch,
- dev_config->bits)) {
- printf("Failed to configure pspd mfc\n");
- goto err_close_mixer;
- }
-
- if (strstr(name, "VIRT-")) {
- if (get_group_device_info(BACKEND_CONF_FILE, name, &grp_config))
+ /* connect pcm stream to audio intf */
+ if (connect_agm_audio_intf_to_stream(mixer, device, intf_name[index], STREAM_PCM, true)) {
+ printf("Failed to connect pcm to audio interface\n");
goto err_close_mixer;
+ }
- if (set_agm_group_device_config(mixer, name, &grp_config)) {
- printf("Failed to set grp device config\n");
- goto err_close_mixer;
+ ret = agm_mixer_get_miid (mixer, device, intf_name[index], STREAM_PCM, PER_STREAM_PER_DEVICE_MFC, &miid);
+ if (ret) {
+ printf("MFC not present for this graph\n");
+ } else {
+ if (configure_mfc(mixer, device, intf_name[index], PER_STREAM_PER_DEVICE_MFC,
+ STREAM_PCM, dev_config[index].rate, dev_config[index].ch,
+ dev_config[index].bits, miid)) {
+ printf("Failed to configure pspd mfc\n");
+ goto err_close_mixer;
+ }
+ }
+
+ if (strstr(intf_name[index], "VIRT-")) {
+ if (get_group_device_info(BACKEND_CONF_FILE, intf_name[index], &grp_config[index]))
+ goto err_close_mixer;
+
+ if (set_agm_group_device_config(mixer, intf_name[index], &grp_config[index])) {
+ printf("Failed to set grp device config\n");
+ goto err_close_mixer;
+ }
}
}
@@ -270,10 +355,11 @@
goto err_close_mixer;
}
- if (strstr(name, "VIRT-")) {
- if (set_agm_group_mux_config(mixer, device, &grp_config, name)) {
- printf("Failed to set grp device config\n");
- goto err_close_pcm;
+ for (index = 0; index < intf_num; index++) {
+ if (strstr(intf_name[index], "VIRT-") || (device_kv[index] == SPEAKER) || (device_kv[index] == HANDSET)) {
+ if (set_agm_group_mux_config(mixer, device, &grp_config[index], intf_name[index], dev_config[index].ch)) {
+ printf("Failed to set grp device config\n");
+ }
}
}
@@ -306,13 +392,18 @@
} while (!close && num_read > 0);
pcm_stop(pcm);
- /* connect pcm stream to audio intf */
- connect_agm_audio_intf_to_stream(mixer, device, name, STREAM_PCM, false);
+ /* disconnect pcm stream to audio intf */
+ for (index = 0; index < intf_num; index++) {
+ connect_agm_audio_intf_to_stream(mixer, device, intf_name[index], STREAM_PCM, false);
+ }
free(buffer);
err_close_pcm:
pcm_close(pcm);
err_close_mixer:
+ if (dev_config)
+ free(dev_config);
+ if (grp_config)
+ free(grp_config);
mixer_close(mixer);
}
-
diff --git a/plugins/tinyalsa/test/backend_conf.xml b/plugins/tinyalsa/test/backend_conf.xml
index 1e342d3..883a08f 100644
--- a/plugins/tinyalsa/test/backend_conf.xml
+++ b/plugins/tinyalsa/test/backend_conf.xml
@@ -66,5 +66,9 @@
<device name="TDM-LPAIF_VA-TX-PRIMARY" rate="48000" ch="1" bits="16" />
<device name="TDM-LPAIF_WSA-RX-PRIMARY" rate="48000" ch="1" bits="16" />
<device name="TDM-LPAIF_WSA-TX-PRIMARY" rate="48000" ch="1" bits="16" />
+ <device name="TDM-LPAIF_AXI-TX-PRIMARY" rate="48000" ch="2" bits="16" />
+ <device name="AUXPCM-LPAIF_AXI-TX-PRIMARY" rate="48000" ch="2" bits="16" />
+ <device name="MI2S-LPAIF_AXI-RX-PRIMARY" rate="48000" ch="2" bits="16" />
+ <device name="AUXPCM-LPAIF_AXI-RX-PRIMARY" rate="48000" ch="2" bits="16" />
</config>