Andy's CarPlayer

/***************************************************************************
                          mixer.c  -  description
                             -------------------
    begin                : Mon Jun 14 2004
    copyright            : (C) 2004 by Andy Clews
    email                : andy  clews  blueyonder  co  uk
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 

// #include "display.h"
 #include "log.h"
 #include "mpg_interface.h"
// #include "get_songs.h"
// #include "player_control.h"
 #include "mixer.h"

/***************************************************************************
 *                                                                         *
 *                      Global Variables                                   *
 *                                                                         *
 ***************************************************************************/

 int mixer_balance = 0;

 //   Find a mixer device...

 int find_mixer_dev(char *channel)
 {
    char *devs[] = SOUND_DEVICE_NAMES;
    int i;

    //   Search the number of a named mixer device...

    for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
       if (!strcasecmp(devs[i], channel))
          return i;
    return -1;
 }

 //  Get a value from mixer device


int mixer_get (char *chan, int *llevel, int *rlevel)
{
        int fd, dev;
        int i, stereo;

        // search the device
        dev = find_mixer_dev(chan);
        if (dev < 0) {
                log_printf(LOG_DEBUG, "mixer_get(): Mixer device '%s' doesn't exist\n", chan);
                return -1;
        }

        // open mixer
        fd = open("/dev/mixer", O_RDONLY);

        if (fd < 0) {
                log_printf(LOG_DEBUG, "mixer_get(): Error opening mixer: %s\n", strerror(errno));
                return -1;
        }

        // check channel
        if (ioctl(fd, SOUND_MIXER_READ_DEVMASK, &i) < 0) {
                log_printf(LOG_DEBUG, "mixer_get(): read devmask failed: %s\n", strerror(errno));
                return -2;
        }
        if (!(i & (1<> 8;
        } else {
                *llevel = i & 0xff;
                *rlevel = i & 0xff;
        }

        // close mixer
        close(fd);

        // okay
        log_printf(LOG_NOISY_DEBUG, "mixer_get(): '%s' reads %d/%d\n", chan, *llevel, *rlevel);
        return 0;
}


/*
 * Set a value to mixer device
 */
int mixer_set (char *chan, int llevel, int rlevel)
{
        int fd, dev;
        int i, stereo;

        // search the device
        dev = find_mixer_dev(chan);
        if (dev < 0) {
                log_printf(LOG_NORMAL, "mixer_set(): Mixer device '%s' doesn't exist\n", chan);
                return -1;
        }

        // open mixer
        fd = open("/dev/mixer", O_RDONLY);

        if (fd < 0) {
                log_printf(LOG_NORMAL, "mixer_set(): Error opening mixer: %s\n", strerror(errno));
                return -1;
        }

        // check channel
        if (ioctl(fd, SOUND_MIXER_READ_DEVMASK, &i) < 0) {
                log_printf(LOG_NORMAL, "mixer_set(): read devmask failed: %s\n", strerror(errno));
                return -2;
        }
        if (!(i & (1< 0) ? (value * (50-abs(balance)) / 50) : value;
        rlevel = (balance < 0) ? (value * (50-abs(balance)) / 50) : value;

        // set new levels
        if (mixer_set( chan, llevel, rlevel))
                return -1;

        return 0;
}

/*
 * Change the volume mixer channel
 */
int mixer_change_volume (char *chan, int step)
{
        int llevel, rlevel, value, balance;

        balance = 0;

        // get old levels
        if (mixer_get(chan, &llevel, &rlevel))
                return -1;
        value = MAX(llevel, rlevel);

        // check levels
        value = MIN(MAX(value, 0), 100);
        balance = MIN(MAX(balance, -50), 50);

        // update value
        value = value + step;

        // calculate new levels
        llevel = (balance > 0) ? (value * (50-abs(balance)) / 50) : value;
        rlevel = (balance < 0) ? (value * (50-abs(balance)) / 50) : value;

        // set new levels
        if (mixer_set(chan, llevel, rlevel))
                return -1;

        return 0;
}

/*
 * Create a bar from a volume
 */
int get_volume(char *channel)
{
    int value, llevel, rlevel;
    
    //calculated the number of blocks to display
    mixer_get(channel, &llevel, &rlevel);
    value = MAX(llevel, rlevel);
                        
    return value;
}