audiomgmt_monitor.c example

This is a sample application shows how to get the current active audio types.

Tip: The APIs used in this sample code are available if you installed Audio component BuildID 387—October 2, 2017 (7.0.387.S201710021920) or later release.
You can use the following options to run the program:

/*
 * $QNXLicenseC: 
 * Copyright 2017, QNX Software Systems Limited. All Rights Reserved.
 *  
 * Licensed under the Apache License, Version 2.0 (the "License"). You  
 * may not reproduce, modify or distribute this software except in  
 * compliance with the License. You may obtain a copy of the License  
 * at: http://www.apache.org/licenses/LICENSE-2.0  
 *  
 * Unless required by applicable law or agreed to in writing, software  
 * distributed under the License is distributed on an "AS IS" basis,  
 * WITHOUT WARRANTIES OF ANY KIND, either express or implied. 
 * 
 * This file may contain contributions from others, either as  
 * contributors under the License or as licensors under other terms.   
 * Please review this entire file for other proprietary rights or license  
 * notices, as well as the QNX Development Suite License Guide at  
 * http://licensing.qnx.com/license-guide/ for other information. 
 * $ 
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <devctl.h>
#include <errno.h>
#include <sys/asoundlib.h>

void audiomgmt_cb ( snd_ctl_t *hdl, void *private_data, int cmd)
{
    int status, i, j;
    const char *ducking_output = private_data;
    snd_ducking_status_t *info = NULL;
    snd_ducking_type_status_t *active_type = NULL;


    switch (cmd)
    {
        case SND_CTL_READ_AUDIOMGMT_CHG:
            if ((status = snd_ctl_ducking_read(hdl, ducking_output, &info )) != EOK)
            {
                printf("Failed to read ducking info - %s\n", snd_strerror(status));
                return;
            }

            printf("\nActive audio types = %d\n", info->ntypes);
            /* The active_types structure is variable in size and is based on the
             * number of PIDs it references. For this reason, you must
             * walk the active_type member of the info structure using the
             * SND_DUCKING_STATUS_NEXT_TYPE() macro.
             */
            for (i = 0, active_type = info->active_types;
                 i < info->ntypes;
                 i++, active_type = SND_DUCKING_STATUS_NEXT_TYPE(active_type))
            {
                printf("Audio Type %s, Priority %d\n", active_type->name, active_type->prio);
                printf("\tPids (%d): ", active_type->npids);
                for (j = 0; j < active_type->npids; j++)
                {
                    printf("%d ", active_type->pids[j]);
                }
                printf("\n");
            }
            /* snd_ctl_ducking_read() allocates memory for the info buffer,
             * so you must free the memory that was allocated for you.
             */
            free(info);
            break;
        default:
            break;
    }
}

int main (int argc, char *argv[])
{
    int c;
    fd_set rfds;
    int card = 0, ctl_fd;
    snd_ctl_t *handle;
    snd_ctl_callbacks_t callbacks;
    char *ducking_output = NULL;

    optind = 1;
    while ((c = getopt(argc, argv, "a:n:")) != EOF)
    {
        switch (c)
        {
            case 'a':
                card = strtol (optarg, &optarg, 0);
                break;
            case 'n':
                ducking_output = optarg;
                break;
            default:
                break;
        }
    }

    if (snd_ctl_open(&handle, card) != EOK)
    {
        printf("Failed to open control device on card %d\n", card);
        return 1;
    }
    ctl_fd = snd_ctl_file_descriptor(handle);
    memset(&callbacks, 0, sizeof (callbacks));
    callbacks.private_data = ducking_output;
    callbacks.audiomgmt = &audiomgmt_cb;

    FD_ZERO(&rfds);
    while (1)
    {
        FD_SET(ctl_fd, &rfds);
        if (select(ctl_fd + 1, &rfds, NULL, NULL, NULL) == -1)
        {
            printf("Select failed - %s\n", strerror(errno));
            return 1;
        }

        if (FD_ISSET(ctl_fd, &rfds))
        {
            snd_ctl_read(handle, &callbacks);
        }
    }
    snd_ctl_close (handle);
    return 0;
}