Home | History | Annotate | Download | only in taudio
      1 #include <unistd.h>
      2 #include <stdlib.h>
      3 #include <stdio.h>
      4 #include <sys/types.h>
      5 #include <sys/stat.h>
      6 #include <fcntl.h>
      7 #include <errno.h>
      8 #include <assert.h>
      9 
     10 #include <sys/ioctl.h>
     11 #include <linux/cpcap_audio.h>
     12 #include <linux/tegra_audio.h>
     13 
     14 #define FAILIF(x, ...) do if (x) { \
     15     fprintf(stderr, __VA_ARGS__);  \
     16     exit(EXIT_FAILURE);            \
     17 } while (0)
     18 
     19 static char buffer[4096];
     20 
     21 int
     22 main(int argc, char *argv[])
     23 {
     24     int opt, cfd;
     25     int output = -4;
     26     int input = -3;
     27     int volume = -1; /* max 15 */
     28     int in_volume = -1; /* max 31 */
     29     int record = -1; /* start 1, stop 0 */
     30     int use_dma = -1;
     31     int in_rate = -1;
     32     int in_channels = -1;
     33 
     34     while ((opt = getopt(argc, argv, "o::i::s:c:v::g::d:r:")) != -1) {
     35         switch (opt) {
     36         case 'o':
     37             if (optarg)
     38                 output = atoi(optarg);
     39             else
     40                 output = -5;
     41             break;
     42         case 'i':
     43             if (optarg)
     44                 input = atoi(optarg);
     45             else
     46                 input = -4;
     47             break;
     48         case 'v':
     49             if (optarg)
     50                 volume = atoi(optarg);
     51             else
     52                 volume = -2;
     53             break;
     54         case 's':
     55             in_rate = atoi(optarg);
     56             break;
     57         case 'c':
     58             in_channels = atoi(optarg);
     59             break;
     60         case 'g':
     61             if (optarg)
     62                 in_volume = atoi(optarg);
     63             else
     64                 in_volume = -2;
     65             break;
     66         case 'd':
     67             use_dma = atoi(optarg);
     68             break;
     69         case 'r':
     70             record = atoi(optarg);
     71             break;
     72         default: /* '?' */
     73             fprintf(stderr, "Unknown option\n");
     74             exit(EXIT_FAILURE);
     75         }
     76     }
     77 
     78     cfd = open("/dev/audio_ctl", O_RDWR);
     79 
     80     printf("cfd opened\n");
     81 
     82     FAILIF(cfd < 0, "could not open control: %s\n", strerror(errno));
     83 
     84     if (output > -4 && output < 4) {
     85         struct cpcap_audio_stream cfg;
     86         assert(!output); // 1 or 2 or 3 or -1 or -2 or -3
     87         if (output < 0) {
     88             cfg.id = (-output) - 1;
     89             cfg.on = 0;
     90             printf("set output %d to OFF\n", cfg.id);
     91         }
     92         else {
     93             cfg.id = output - 1;
     94             cfg.on = 1;
     95             printf("set output %d to ON\n", cfg.id);
     96         }
     97         FAILIF(ioctl(cfd, CPCAP_AUDIO_OUT_SET_OUTPUT, &cfg) < 0,
     98                "Cannot set output device %d: %s\n", cfg.id, strerror(errno));
     99     }
    100     else if (output == -5) {
    101         struct cpcap_audio_stream cfg;
    102         FAILIF(ioctl(cfd, CPCAP_AUDIO_OUT_GET_OUTPUT, &cfg) < 0,
    103                "Cannot get output device %d: %s\n", cfg.id, strerror(errno));
    104         printf("current output: %d, %s\n", cfg.id, (cfg.on ? "on" : "off"));
    105     }
    106 
    107     if (volume >= 0) {
    108         printf("set output volume\n");
    109         FAILIF(ioctl(cfd, CPCAP_AUDIO_OUT_SET_VOLUME, volume) < 0,
    110                "Cannot set volume to %d: %s\n", output, strerror(errno));
    111     }
    112     else if (volume == -2) {
    113         FAILIF(ioctl(cfd, CPCAP_AUDIO_OUT_GET_VOLUME, &volume) < 0,
    114                "Cannot get volume: %s\n", strerror(errno));
    115         printf("speaker volume: %d\n", volume);
    116     }
    117 
    118     if (in_volume >= 0) {
    119         printf("set input volume\n");
    120         FAILIF(ioctl(cfd, CPCAP_AUDIO_IN_SET_VOLUME, in_volume) < 0,
    121                "Cannot set input volume to %d: %s\n", output, strerror(errno));
    122     }
    123     else if (in_volume == -2) {
    124         FAILIF(ioctl(cfd, CPCAP_AUDIO_IN_GET_VOLUME, &in_volume) < 0,
    125                "Cannot get input volume: %s\n", strerror(errno));
    126         printf("microphone gain: %d\n", in_volume);
    127     }
    128 
    129     if (input > -3 && input < 3) {
    130         struct cpcap_audio_stream cfg;
    131         assert(!input); // 1 or 2 or -1 or -2
    132         if (input < 0) {
    133             cfg.id = (-input) - 1;
    134             cfg.on = 0;
    135             printf("set input %d to OFF\n", cfg.id);
    136         }
    137         else {
    138             cfg.id = input - 1;
    139             cfg.on = 1;
    140             printf("set input %d to ON\n", cfg.id);
    141         }
    142         FAILIF(ioctl(cfd, CPCAP_AUDIO_IN_SET_INPUT, &cfg) < 0,
    143                "Cannot set input device %d: %s\n", cfg.id, strerror(errno));
    144     }
    145     else if (input == -4) {
    146         struct cpcap_audio_stream cfg;
    147         FAILIF(ioctl(cfd, CPCAP_AUDIO_IN_GET_INPUT, &cfg) < 0,
    148                "Cannot get input device %d: %s\n", cfg.id, strerror(errno));
    149         printf("current input: %d, %s\n", cfg.id, (cfg.on ? "on" : "off"));
    150     }
    151 
    152     if (in_channels >= 0 || in_rate >= 0) {
    153         int recfd;
    154         struct tegra_audio_in_config cfg;
    155 
    156         printf("set input config\n");
    157 
    158         printf("opening audio input\n");
    159         recfd = open("/dev/audio1_in_ctl", O_RDWR);
    160         FAILIF(recfd < 0, "could not open for recording: %s\n", strerror(errno));
    161 
    162         printf("getting audio-input config\n");
    163         FAILIF(ioctl(recfd, TEGRA_AUDIO_IN_GET_CONFIG, &cfg) < 0,
    164                "could not get input config: %s\n", strerror(errno));
    165         if (in_channels >= 0)
    166             cfg.stereo = in_channels == 2;
    167         if (in_rate >= 0)
    168             cfg.rate = in_rate;
    169         printf("setting audio-input config (stereo %d, rate %d)\n", cfg.stereo, cfg.rate);
    170         FAILIF(ioctl(recfd, TEGRA_AUDIO_IN_SET_CONFIG, &cfg) < 0,
    171                "could not set input config: %s\n", strerror(errno));
    172         close(recfd);
    173     }
    174 
    175     if (use_dma >= 0) {
    176         int piofd = open("/sys/kernel/debug/tegra_audio/dma", O_RDWR);
    177         FAILIF(piofd < 0, "Could not open DMA/PIO toggle file: %s\n", strerror(errno));
    178         if (use_dma)
    179             FAILIF(write(piofd, "dma\n", sizeof("dma\n")) < 0,
    180                    "Could not set to DMA: %s\n", strerror(errno));
    181         else
    182             FAILIF(write(piofd, "dma\n", sizeof("pio\n")) < 0,
    183                    "Could not set to PIO: %s\n", strerror(errno));
    184     }
    185 
    186     if (record >= 0) {
    187         printf("opening audio input\n");
    188         int recfd = open("/dev/audio1_in_ctl", O_RDWR);
    189         printf("done opening audio input\n");
    190         FAILIF(recfd < 0, "could not open for recording: %s\n", strerror(errno));
    191         if (record) {
    192             printf("start recording\n");
    193             FAILIF(ioctl(recfd, TEGRA_AUDIO_IN_START) < 0,
    194                    "Could not start recording: %s\n", strerror(errno));
    195         } else {
    196             printf("stop recording\n");
    197             FAILIF(ioctl(recfd, TEGRA_AUDIO_IN_STOP) < 0,
    198                    "Could not stop recording: %s\n", strerror(errno));
    199         }
    200     }
    201 
    202     return 0;
    203 }
    204 
    205