home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.4front-tech.com
/
ftp.4front-tech.com.tar
/
ftp.4front-tech.com
/
ossfree
/
snd-util-3.8.tar.gz
/
snd-util-3.8.tar
/
sndkit
/
xvmixer
/
xvmixer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-01-28
|
9KB
|
399 lines
/*
* xvmixer.c xview3 based mixer program for Linux
*
* Copyright by Hannu Savolainen 1993
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. 2.
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/soundcard.h>
#include <xview/frame.h>
#include <xview/panel.h>
#include <xview/svrimage.h>
#include <xview/icon.h>
#include "locked.bit"
#include "unlocked.bit"
#include "rec.bit"
void slider_moved();
void toggle_changed();
char dev_name[20] = "/dev/mixer";
int mixer; /* The mixer device */
int devmask = 0; /* Bitmask for supported mixer devices */
int recsrc = 0; /* Currently selected recording sources */
int recmask = 0; /* Supported recording sources */
int stereodevs = 0; /* Channels supporting stereo */
unsigned long locked=0xffffffff;/* Channels with left and right locked */
char *labels[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_LABELS;
int level[SOUND_MIXER_NRDEVICES];
Panel_item volume_l[SOUND_MIXER_NRDEVICES];
Panel_item volume_r[SOUND_MIXER_NRDEVICES];
Panel_item buttons[SOUND_MIXER_NRDEVICES];
int key;
#ifdef USE_XBM_ICON
static Icon icon;
static Pixmap icon_pm, mask_icon_pm;
static Server_image icon_image, icon_image_mask;
static Display *dpy;
Window root_win;
#include "xvmixer.xbm"
#include "xvmixer-mask.xbm"
#endif /* USE_XBM_ICON */
Server_image locked_image, unlocked_image, rec_image, lock;
int main(argc, argv)
int argc;
char *argv[];
{
Frame frame;
Panel panel;
int i, n, left, right, x, rec;
int stereo;
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
if (!strcmp(argv[0], "xvmixer2"))
strcpy(dev_name, "/dev/mixer1");
if ((mixer=open(dev_name, O_RDWR, 0)) == -1)
{
perror(dev_name);
exit(-1);
}
if (ioctl(mixer, SOUND_MIXER_READ_DEVMASK, &devmask) == -1)
{
perror("SOUND_MIXER_READ_DEVMASK");
exit(-1);
}
if (ioctl(mixer, SOUND_MIXER_READ_RECMASK, &recmask) == -1)
{
perror("SOUND_MIXER_READ_RECMASK");
exit(-1);
}
if (ioctl(mixer, SOUND_MIXER_READ_RECSRC, &recsrc) == -1)
{
perror("SOUND_MIXER_READ_RECSRC");
exit(-1);
}
if (ioctl(mixer, SOUND_MIXER_READ_STEREODEVS, &stereodevs) == -1)
{
perror("SOUND_MIXER_READ_STEREODEVS");
exit(-1);
}
frame = (Frame) xv_create(XV_NULL, FRAME,
FRAME_LABEL, argv[0],
XV_WIDTH, 800,
XV_HEIGHT, 400,
NULL);
panel = (Panel) xv_create(frame, PANEL,
PANEL_LAYOUT, PANEL_HORIZONTAL,
PANEL_ITEM_Y_GAP, 0,
NULL);
locked_image = (Server_image)xv_create((int)NULL, SERVER_IMAGE,
XV_HEIGHT, locked_height,
XV_WIDTH, locked_width,
SERVER_IMAGE_X_BITS, locked_bits,
NULL);
unlocked_image = (Server_image)xv_create((int)NULL, SERVER_IMAGE,
XV_HEIGHT, unlocked_height,
XV_WIDTH, unlocked_width,
SERVER_IMAGE_X_BITS, unlocked_bits,
NULL);
rec_image = (Server_image)xv_create((int)NULL, SERVER_IMAGE,
XV_HEIGHT, rec_height,
XV_WIDTH, rec_width,
SERVER_IMAGE_X_BITS, rec_bits,
NULL);
#ifdef USE_XBM_ICON
dpy = (Display *) xv_get(frame, XV_DISPLAY);
root_win = RootWindow (dpy, DefaultScreen(dpy));
icon_pm = XCreatePixmapFromBitmapData(dpy,
root_win, icon_bits, icon_width, icon_height,
1, 0, 1);
mask_icon_pm = XCreatePixmapFromBitmapData(dpy,
root_win, mask_icon_bits, mask_icon_width,
mask_icon_height, 1, 0, 1);
icon_image = (Server_image) xv_create(NULL,SERVER_IMAGE,
SERVER_IMAGE_PIXMAP, icon_pm, NULL);
icon_image_mask = (Server_image) xv_create(NULL,SERVER_IMAGE,
SERVER_IMAGE_PIXMAP, mask_icon_pm,
NULL);
icon = (Icon) xv_create(frame, ICON,
ICON_IMAGE, icon_image,
ICON_MASK_IMAGE, icon_image_mask,
ICON_TRANSPARENT, TRUE,
NULL);
xv_set(frame,
FRAME_ICON, icon,
NULL);
#endif /* USE_XBM_ICON */
key = xv_unique_key();
n = 0;
for(i=0; i<SOUND_MIXER_NRDEVICES; i++)
if ((1 << i) & devmask) {
if (ioctl(mixer, MIXER_READ(i), &level[i]) == -1)
{
perror("MIXER_READ");
exit(-1);
}
left = level[i] & 0x7f;
right = (level[i] >> 8) & 0x7f;
lock = unlocked_image;
if (left != right)
locked &=~(1 << i); /* Unlock */
else
lock = locked_image;
if ((1 << i) & locked) left = right = (left+right)/2;
stereo = !!((1 << i) & stereodevs); /* 0 or 1 */
rec = !!((1 << i) & recsrc);
rec <<= 1;
x = n++ * 50;
xv_create(panel, PANEL_MESSAGE,
PANEL_LABEL_STRING, labels[i],
XV_X, x+4,
XV_Y, 2,
NULL);
volume_l[i] = (Panel_item) xv_create(panel, PANEL_SLIDER,
XV_KEY_DATA, key, i+1,
PANEL_NOTIFY_LEVEL, PANEL_ALL,
PANEL_NOTIFY_PROC, slider_moved,
PANEL_SHOW_RANGE, FALSE,
PANEL_SHOW_VALUE, FALSE,
PANEL_DIRECTION, PANEL_VERTICAL,
XV_X, x + 4 + !stereo * 7,
XV_Y, 20,
PANEL_VALUE, left,
NULL);
if (stereo) {
volume_r[i] = (Panel_item) xv_create(panel, PANEL_SLIDER,
XV_KEY_DATA, key, -(i+1),
PANEL_NOTIFY_LEVEL, PANEL_ALL,
PANEL_NOTIFY_PROC, slider_moved,
PANEL_SHOW_RANGE, FALSE,
PANEL_SHOW_VALUE, FALSE,
PANEL_DIRECTION, PANEL_VERTICAL,
XV_X, x+15+4,
XV_Y, 20,
PANEL_VALUE, right,
NULL);
}
if ((1 << i) & recmask)
{ /* Possible recording source */
buttons[i] = (Panel_item) xv_create(panel, PANEL_TOGGLE,
PANEL_CHOICE_IMAGES, lock, rec_image, NULL,
XV_KEY_DATA, key, i,
PANEL_NOTIFY_PROC, toggle_changed,
PANEL_LAYOUT, PANEL_VERTICAL,
XV_Y, 140,
XV_X, x,
PANEL_VALUE, rec | 0x01,
NULL);
} else {
buttons[i] = (Panel_item) xv_create(panel, PANEL_TOGGLE,
PANEL_CHOICE_IMAGES, lock, NULL,
XV_KEY_DATA, key, i,
PANEL_NOTIFY_PROC, toggle_changed,
PANEL_LAYOUT, PANEL_VERTICAL,
XV_Y, 140,
XV_X, x,
PANEL_VALUE, rec | 0x01,
NULL);
}
}
window_fit(panel);
window_fit(frame);
xv_main_loop(frame);
exit(0);
}
void
slider_moved(item, value, event)
Panel_item item;
int value;
Event *event;
{
int dev, ch, val;
dev = (int) xv_get(item, XV_KEY_DATA, key);
val = value & 0x7f;
if (dev>0)
{
ch = 0;
dev--;
}
else
{
ch = 1;
dev = -dev - 1;
}
if ((1 << dev) & locked)
level[dev] = ((val << 8) & 0x7f00) | (val & 0x007f);
else
if (ch)
level[dev] = (level[dev] & 0x007f) | (val << 8);
else
level[dev] = (level[dev] & 0x7f00) | val;
if (ioctl(mixer, MIXER_WRITE(dev), &level[dev]) == -1)
{
perror("MIXER_WRITE");
exit(-1);
}
if ((1 << dev) & stereodevs)
if ((1 << dev) & locked) /* Sync the other channel */
if (ch) {
xv_set(volume_l[dev], PANEL_VALUE, val, NULL);
} else {
xv_set(volume_r[dev], PANEL_VALUE, val, NULL);
}
}
void
toggle_changed(Panel_item item, int value, Event *event)
{
int i, dev, rec, lock, val, tmp_src, changed;
dev = (int) xv_get(item, XV_KEY_DATA, key);
lock = value & 0x01;
rec = (value & 0x02) >> 1;
if (locked ^ (lock << dev)) /* Locked or unlocked */
if (lock) {
locked |= (1 << dev);
val = ((level[dev] & 0x7f00) >> 8) + (level[dev] & 0x007f);
val /= 2;
level[dev] = ((val << 8) & 0x7f00) | (val & 0x007f);
if (ioctl(mixer, MIXER_WRITE(dev), &level[dev]) == -1)
{
perror("MIXER_WRITE");
exit(-1);
}
xv_set(volume_l[dev], PANEL_VALUE, val, NULL);
if ((1 << dev) & recmask)
xv_set(buttons[dev], PANEL_CHOICE_IMAGES,
locked_image, rec_image, NULL,
NULL);
else
xv_set(buttons[dev], PANEL_CHOICE_IMAGES,
locked_image, NULL,
NULL);
if ((1 << dev) & stereodevs)
xv_set(volume_r[dev], PANEL_VALUE, val, NULL);
} else {
locked &= ~(1 << dev);
if ((1 << dev) & recmask)
xv_set(buttons[dev], PANEL_CHOICE_IMAGES,
unlocked_image, rec_image, NULL,
NULL);
else
xv_set(buttons[dev], PANEL_CHOICE_IMAGES,
unlocked_image, NULL,
NULL);
}
if (recsrc ^ (rec << dev)) /* Rec/play changed */
{
recsrc ^= (1 << dev);
tmp_src = recsrc;
if (ioctl(mixer, SOUND_MIXER_WRITE_RECSRC, &recsrc) == -1)
{
perror("SOUND_MIXER_WRITE_RECSRC");
exit(-1);
}
if (recsrc ^ tmp_src) /* The device has changed the mask */
{
changed = recsrc ^ tmp_src;
for (i=0;i<SOUND_MIXER_NRDEVICES;i++)
if (changed & (1 << i))
{
xv_set(buttons[i], PANEL_VALUE,
(int)xv_get(buttons[i], PANEL_VALUE) ^ 0x02,
NULL);
}
}
}
}