mirror of
https://github.com/alsa-project/alsa-tools.git
synced 2025-10-29 05:40:25 -04:00
envy24control: midi support for mixer
Hello devlopers, I have made the mixer sliders in envy24control react to MIDI controllers. This way the hardware mixer can be controlled from a sequencer program or some external MIDI controller hardware. envy24control became a standard ALSA sequencer client which you can connect to arbitrary other MIDI sources/sinks. Signed-off-by: Dirk Jagdmann <doj@cubic.org>
This commit is contained in:
parent
465acb88f4
commit
1be230856c
6 changed files with 269 additions and 41 deletions
|
|
@ -1,7 +1,7 @@
|
|||
AM_CFLAGS = @ENVY24CONTROL_CFLAGS@
|
||||
bin_PROGRAMS = envy24control
|
||||
man_MANS = envy24control.1
|
||||
envy24control_SOURCES = envy24control.c envy24control.h levelmeters.c \
|
||||
envy24control_SOURCES = envy24control.c envy24control.h levelmeters.c midi.c \
|
||||
mixer.c patchbay.c hardware.c driverevents.c volume.c \
|
||||
profiles.c profiles.h
|
||||
envy24control_LDFLAGS = @ENVY24CONTROL_LIBS@
|
||||
|
|
|
|||
|
|
@ -1,72 +1,75 @@
|
|||
.TH "envy24control" 1 "16 May 2004"
|
||||
.SH NAME
|
||||
.TH "envy24control" "1" "16 May 2004" "" ""
|
||||
.SH "NAME"
|
||||
envy24control \- GUI control tool for Envy24 (ice1712) based
|
||||
soundcards, under ALSA.
|
||||
|
||||
.SH SYNOPSIS
|
||||
\fBenvy24control\fP [\fI\-c\fP card-number] [\fI\-D\fP control-name] [\fI\-o\fP 0-num DACs max 8] [\fI\-i\fP 0-num ADCs max 8] [\fI\-p\fP 0-8] [\fI\-s\fP 0-2] [\fI\-f\fP <profiles file name>] [\fI\-v\fP] [<profile number>|<profile name>]
|
||||
.SH "SYNOPSIS"
|
||||
\fBenvy24control\fP [\fI\-c\fP card\-number] [\fI\-D\fP control\-name] [\fI\-o\fP 0\-num DACs max 8] [\fI\-i\fP 0\-num ADCs max 8] [\fI\-p\fP 0\-8] [\fI\-s\fP 0\-2] [\fI\-f\fP <profiles file name>] [\fI\-v\fP] [<profile number>|<profile name>] [\fI\-m\fP midi\-channel]
|
||||
|
||||
.SH DESCRIPTION
|
||||
.SH "DESCRIPTION"
|
||||
\fBenvy24control\fP allows control of the digital mixer, channel gains
|
||||
and other hardware settings for sound cards based on the ice1712
|
||||
chipset (Midiman Delta series, Terratec EWS and EWX series). It also
|
||||
displays a level meter for each input and output channel.
|
||||
|
||||
.SH INVOKING
|
||||
|
||||
\fBenvy24control\fP [\fI\-c\fP card-number] [\fI\-D\fP control-name] [\fI\-o\fP 0-num DACs max 8] [\fI\-i\fP 0-num ADCs max 8] [\fI\-p\fP 0-8] [\fI\-s\fP 0-2] [\fI\-f\fP <profiles file name>] [\fI\-v\fP] [<profile number>|<profile name>]
|
||||
.TP
|
||||
If no control-name is given, then the first sound card is used.
|
||||
.SH "INVOKING"
|
||||
\fBenvy24control\fP [\fI\-c\fP card\-number] [\fI\-D\fP control\-name] [\fI\-o\fP 0\-num DACs max 8] [\fI\-i\fP 0\-num ADCs max 8] [\fI\-p\fP 0\-8] [\fI\-s\fP 0\-2] [\fI\-f\fP <profiles file name>] [\fI\-v\fP] [<profile number>|<profile name>] [\fI\-m\fP midi\-channel]
|
||||
.TP
|
||||
If no control\-name is given, then the first sound card is used.
|
||||
|
||||
.SS Options
|
||||
.TP
|
||||
\fI\-c\fP card-number
|
||||
Use the card specified by card-number rather than the first card.
|
||||
.TP
|
||||
\fI\-c\fP card\-number
|
||||
Use the card specified by card\-number rather than the first card.
|
||||
This is equivalent with \fI\-Dhw:n\fP option where \fIn\fP is the card number.
|
||||
.TP
|
||||
\fI\-D\fP control-name
|
||||
Use the card specified by control-name rather than the first card,
|
||||
.TP
|
||||
\fI\-D\fP control\-name
|
||||
Use the card specified by control\-name rather than the first card,
|
||||
normally this will be of the form hw:\fIn\fP where \fIn\fP is the sound
|
||||
card number (zero-based). This is only needed if you have more than one
|
||||
Envy24-based card or if your Envy24 card is not configured as the first
|
||||
card number (zero\-based). This is only needed if you have more than one
|
||||
Envy24\-based card or if your Envy24 card is not configured as the first
|
||||
card in your ALSA driver setup.
|
||||
.TP
|
||||
.TP
|
||||
\fI\-o\fP outputs
|
||||
Limit number of analog line outputs to display. Default is the number of
|
||||
DACs in the driver specification. Maximum is 8.
|
||||
The number of analog output lines can only be reduced from the available
|
||||
number of output lines.
|
||||
.TP
|
||||
.TP
|
||||
\fI\-i\fP inputs
|
||||
Limit number of analog line inputs to display. Default is the number of
|
||||
ADCs in the driver specification. Maximum is 8.
|
||||
The number of analog input lines can only be reduced from the available
|
||||
number of input lines.
|
||||
.TP
|
||||
.TP
|
||||
\fI\-p\fP pcm outputs
|
||||
Limit number of PCM outputs to display. Default is 8.
|
||||
.TP
|
||||
.TP
|
||||
\fI\-s\fP spdif inputs/outputs
|
||||
Limit number of SPDIF inputs/outputs to display. Default is 2.
|
||||
.TP
|
||||
.TP
|
||||
\fI\-f\fP name and path of the profiles file name.
|
||||
From/to this file will envy24control read/write the alsactl settings.
|
||||
If is not given DEFAULT_PROFILERC or for restore if DEFAULT_PROFILERC
|
||||
doesn't exists SYS_PROFILERC will be used.
|
||||
.TP
|
||||
.TP
|
||||
\fI\-v\fP view spdif playback channels in the mixer.
|
||||
It is not possible to manage something (muting, volume levels).
|
||||
It is only to view the levelmeters.
|
||||
Default is no view of spdif playback channels in the mixer.
|
||||
|
||||
.SH SEE ALSO
|
||||
.TP
|
||||
\fI\-m\fP midi\-channel
|
||||
Use MIDI controller values to control the Faders in the mixer view.
|
||||
The application will react to controllers on channel midi\-channel and
|
||||
send controllers on this channel when the user moves the GUI sliders.
|
||||
.SH "SEE ALSO"
|
||||
\fB
|
||||
alsamixer(1),
|
||||
amixer(1),
|
||||
gamix(1)
|
||||
\fP
|
||||
|
||||
.SH AUTHOR
|
||||
.SH "AUTHOR"
|
||||
\fBenvy24control\fP is by Jaroslav Kysela <perex@suse.cz>
|
||||
This document is by James Tappin <james@xena.uklinux.net>.
|
||||
Last updated by Dirk Kalis <dirk.kalis@t\-online.de>.
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
******************************************************************************/
|
||||
|
||||
#include "envy24control.h"
|
||||
#include "midi.h"
|
||||
#define _GNU_SOURCE
|
||||
#include <getopt.h>
|
||||
|
||||
|
|
@ -1926,7 +1927,7 @@ static void create_profiles(GtkWidget *main, GtkWidget *notebook, int page)
|
|||
|
||||
static void usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: envy24control [-c card#] [-D control-name] [-o num-outputs] [-i num-inputs] [-p num-pcm-outputs] [-s num-spdif-in/outs] [-v] [-f profiles-file] [profile name|profile id]\n");
|
||||
fprintf(stderr, "usage: envy24control [-c card#] [-D control-name] [-o num-outputs] [-i num-inputs] [-p num-pcm-outputs] [-s num-spdif-in/outs] [-v] [-f profiles-file] [profile name|profile id] [-m channel-num]\n");
|
||||
fprintf(stderr, "\t-c, --card\tAlsa card number to control\n");
|
||||
fprintf(stderr, "\t-D, --device\tcontrol-name\n");
|
||||
fprintf(stderr, "\t-o, --outputs\tLimit number of analog line outputs to display\n");
|
||||
|
|
@ -1935,6 +1936,7 @@ static void usage(void)
|
|||
fprintf(stderr, "\t-s, --spdif\tLimit number of spdif inputs/outputs to display\n");
|
||||
fprintf(stderr, "\t-v, --view_spdif_playback\tshows the spdif playback channels in the mixer\n");
|
||||
fprintf(stderr, "\t-f, --profiles_file\tuse file as profiles file\n");
|
||||
fprintf(stderr, "\t-m, --midichannel\tmidi channel number for controller control\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
|
@ -1946,17 +1948,19 @@ int main(int argc, char **argv)
|
|||
snd_ctl_elem_value_t *val;
|
||||
int npfds;
|
||||
struct pollfd *pfds;
|
||||
int midi_fd, midi_channel = -1;
|
||||
int page;
|
||||
int input_channels_set = 0;
|
||||
int output_channels_set = 0;
|
||||
static struct option long_options[] = {
|
||||
{"device", 1, 0, 'D'},
|
||||
{"card", 1, 0, 'c'},
|
||||
{"profiles_file", 1, 0, 'f'},
|
||||
{"inputs", 1, 0, 'i'},
|
||||
{"midichannel", 1, 0, 'm'},
|
||||
{"outputs", 1, 0, 'o'},
|
||||
{"pcm_outputs", 1, 0, 'p'},
|
||||
{"spdif", 1, 0, 's'},
|
||||
{"profiles_file", 1, 0, 'f'},
|
||||
{"view_spdif_playback", 0, 0, 'v'},
|
||||
{ NULL }
|
||||
};
|
||||
|
|
@ -1977,8 +1981,16 @@ int main(int argc, char **argv)
|
|||
view_spdif_playback = 0;
|
||||
profiles_file_name = DEFAULT_PROFILERC;
|
||||
default_profile = NULL;
|
||||
while ((c = getopt_long(argc, argv, "D:c:i:o:p:s:f:v", long_options, NULL)) != -1) {
|
||||
while ((c = getopt_long(argc, argv, "D:c:f:i:m:o:p:s:v", long_options, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 'D':
|
||||
name = optarg;
|
||||
card_number = atoi(strchr(name, ':') + sizeof(char));
|
||||
if (card_number < 0 || card_number >= MAX_CARD_NUMBERS) {
|
||||
fprintf(stderr, "envy24control: invalid card number %d\n", card_number);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
i = atoi(optarg);
|
||||
if (i < 0 || i >= MAX_CARD_NUMBERS) {
|
||||
|
|
@ -1989,13 +2001,8 @@ int main(int argc, char **argv)
|
|||
sprintf(tmpname, "hw:%d", i);
|
||||
name = tmpname;
|
||||
break;
|
||||
case 'D':
|
||||
name = optarg;
|
||||
card_number = atoi(strchr(name, ':') + sizeof(char));
|
||||
if (card_number < 0 || card_number >= MAX_CARD_NUMBERS) {
|
||||
fprintf(stderr, "envy24control: invalid card number %d\n", card_number);
|
||||
exit(1);
|
||||
}
|
||||
case 'f':
|
||||
profiles_file_name = optarg;
|
||||
break;
|
||||
case 'i':
|
||||
input_channels = atoi(optarg);
|
||||
|
|
@ -2005,6 +2012,14 @@ int main(int argc, char **argv)
|
|||
}
|
||||
input_channels_set = 1;
|
||||
break;
|
||||
case 'm':
|
||||
midi_channel = atoi(optarg);
|
||||
if (midi_channel < 1 || midi_channel > 16) {
|
||||
fprintf(stderr, "envy24control: invalid midi channel number %i\n", midi_channel);
|
||||
exit(1);
|
||||
}
|
||||
--midi_channel;
|
||||
break;
|
||||
case 'o':
|
||||
output_channels = atoi(optarg);
|
||||
if (output_channels < 0 || output_channels > MAX_OUTPUT_CHANNELS) {
|
||||
|
|
@ -2027,9 +2042,6 @@ int main(int argc, char **argv)
|
|||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
profiles_file_name = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
view_spdif_playback = 1;
|
||||
break;
|
||||
|
|
@ -2083,6 +2095,8 @@ int main(int argc, char **argv)
|
|||
patchbay_init();
|
||||
hardware_init();
|
||||
analog_volume_init();
|
||||
if (midi_channel >= 0)
|
||||
midi_fd = midi_init(argv[0], midi_channel);
|
||||
|
||||
fprintf(stderr, "using\t --- input_channels: %i\n\t --- output_channels: %i\n\t --- pcm_output_channels: %i\n\t --- spdif in/out channels: %i\n", \
|
||||
input_channels, output_channels, pcm_output_channels, spdif_channels);
|
||||
|
|
@ -2123,6 +2137,9 @@ int main(int argc, char **argv)
|
|||
ctl);
|
||||
snd_ctl_subscribe_events(ctl, 1);
|
||||
}
|
||||
if (midi_fd >= 0) {
|
||||
gdk_input_add(midi_fd, GDK_INPUT_READ, midi_process, NULL);
|
||||
}
|
||||
gtk_timeout_add(40, level_meters_timeout_callback, NULL);
|
||||
gtk_timeout_add(100, master_clock_status_timeout_callback, NULL);
|
||||
gtk_timeout_add(100, internal_clock_status_timeout_callback, NULL);
|
||||
|
|
@ -2141,6 +2158,7 @@ int main(int argc, char **argv)
|
|||
gtk_main();
|
||||
|
||||
snd_ctl_close(ctl);
|
||||
midi_close();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
|||
188
envy24control/midi.c
Normal file
188
envy24control/midi.c
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/*****************************************************************************
|
||||
envy24control.c - Env24 chipset (ICE1712) control utility
|
||||
midi controller code
|
||||
(c) 2004 by Dirk Jagdmann <doj@cubic.org>
|
||||
|
||||
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.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
******************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
#include "midi.h"
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static snd_seq_t *seq=0;
|
||||
static int client, clientId, port, ch;
|
||||
static char *portname=0, *appname=0;
|
||||
static int nofeedback=-1;
|
||||
static int maxstreams=0;
|
||||
static uint8_t currentvalues[128];
|
||||
|
||||
void midi_maxstreams(int m)
|
||||
{
|
||||
maxstreams=(m-1)*2;
|
||||
}
|
||||
|
||||
int midi_close()
|
||||
{
|
||||
int i=0;
|
||||
if(seq)
|
||||
i=snd_seq_close(seq);
|
||||
|
||||
seq=0;
|
||||
client=port=0;
|
||||
if(portname)
|
||||
free(portname), portname=0;
|
||||
if(appname)
|
||||
free(appname), appname=0;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void do_controller(int c, int v)
|
||||
{
|
||||
snd_seq_event_t ev;
|
||||
snd_seq_ev_clear(&ev);
|
||||
snd_seq_ev_set_source(&ev, port);
|
||||
snd_seq_ev_set_subs(&ev);
|
||||
snd_seq_ev_set_direct(&ev);
|
||||
snd_seq_ev_set_controller(&ev,ch,c,v);
|
||||
snd_seq_event_output(seq, &ev);
|
||||
snd_seq_drain_output(seq);
|
||||
}
|
||||
|
||||
int midi_controller(int c, int v)
|
||||
{
|
||||
if(c==nofeedback) return 0;
|
||||
if(c<0 || c>127) return 0;
|
||||
|
||||
v*=127; v/=96;
|
||||
if(v<0) v=0;
|
||||
if(v>127) v=127;
|
||||
currentvalues[c]=v;
|
||||
do_controller(c,v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int midi_init(char *appname, int channel)
|
||||
{
|
||||
snd_seq_client_info_t *clientinfo;
|
||||
int npfd;
|
||||
struct pollfd *pfd;
|
||||
|
||||
if(seq)
|
||||
return 0;
|
||||
|
||||
ch=channel;
|
||||
|
||||
if(snd_seq_open(&seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK) < 0)
|
||||
{
|
||||
g_warning("could not init ALSA sequencer\n");
|
||||
seq=0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
snd_seq_set_client_name(seq, appname);
|
||||
snd_seq_client_info_alloca(&clientinfo);
|
||||
snd_seq_get_client_info (seq, clientinfo);
|
||||
client=snd_seq_client_info_get_client(clientinfo);
|
||||
clientId = snd_seq_client_id(seq);
|
||||
|
||||
portname=g_strdup_printf("%s Mixer Control", appname);
|
||||
port=snd_seq_create_simple_port(seq, portname,
|
||||
SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE|SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ,
|
||||
SND_SEQ_PORT_TYPE_APPLICATION);
|
||||
if(port < 0)
|
||||
{
|
||||
g_warning("could not create ALSA sequencer port\n");
|
||||
midi_close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
npfd=snd_seq_poll_descriptors_count(seq, POLLIN);
|
||||
if(npfd<=0)
|
||||
{
|
||||
g_warning("could not get number of ALSA sequencer poll descriptors\n");
|
||||
midi_close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
pfd=(struct pollfd*)alloca(npfd * sizeof(struct pollfd));
|
||||
if(pfd==0)
|
||||
{
|
||||
g_warning("could not alloc memory for ALSA sequencer poll descriptors\n");
|
||||
midi_close();
|
||||
return -1;
|
||||
}
|
||||
if(snd_seq_poll_descriptors(seq, pfd, npfd, POLLIN) != npfd)
|
||||
{
|
||||
g_warning("number of returned poll desc is not equal of request poll desc\n");
|
||||
midi_close();
|
||||
return -1;
|
||||
}
|
||||
|
||||
return pfd[0].fd;
|
||||
}
|
||||
|
||||
void mixer_adjust(GtkAdjustment *adj, gpointer data);
|
||||
|
||||
void midi_process(gpointer data, gint source, GdkInputCondition condition)
|
||||
{
|
||||
snd_seq_event_t *ev;
|
||||
static GtkAdjustment *adj=0;
|
||||
if(!adj)
|
||||
adj=(GtkAdjustment*) gtk_adjustment_new(0, 0, 96, 1, 1, 10);
|
||||
|
||||
do
|
||||
{
|
||||
snd_seq_event_input(seq, &ev);
|
||||
if(!ev) continue;
|
||||
switch(ev->type)
|
||||
{
|
||||
case SND_SEQ_EVENT_CONTROLLER:
|
||||
#if 0
|
||||
fprintf(stderr, "Channel %02d: Controller %03d: Value:%d\n",
|
||||
ev->data.control.channel, ev->data.control.param, ev->data.control.value);
|
||||
#endif
|
||||
if(ev->data.control.channel == ch && ev->data.control.param < maxstreams)
|
||||
{
|
||||
int stream=ev->data.control.param+1;
|
||||
long data=((stream/2)<<16)|(stream&1);
|
||||
int v=ev->data.control.value; v*=96; v/=127;
|
||||
gtk_adjustment_set_value(adj, 96-v);
|
||||
nofeedback=ev->data.control.param;
|
||||
mixer_adjust(adj, (gpointer)data);
|
||||
nofeedback=-1;
|
||||
}
|
||||
break;
|
||||
|
||||
case SND_SEQ_EVENT_PORT_SUBSCRIBED:
|
||||
#if 0
|
||||
fprintf(stderr, "event subscribed send.client:%i dest.client:%i clientId:%i\n",
|
||||
(int)ev->data.connect.sender.client, (int)ev->data.connect.dest.client, clientId);
|
||||
#endif
|
||||
if(ev->data.connect.dest.client!=clientId)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<sizeof(currentvalues); ++i)
|
||||
do_controller(i, currentvalues[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
snd_seq_free_event(ev);
|
||||
}
|
||||
while (snd_seq_event_input_pending(seq, 0) > 0);
|
||||
}
|
||||
12
envy24control/midi.h
Normal file
12
envy24control/midi.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef MIDI__H
|
||||
#define MIDI__H
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
|
||||
int midi_init(char *appname, int channel);
|
||||
int midi_close();
|
||||
void midi_maxstreams(int);
|
||||
int midi_controller(int c, int v);
|
||||
void midi_process(gpointer data, gint source, GdkInputCondition condition);
|
||||
|
||||
#endif
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
******************************************************************************/
|
||||
|
||||
#include "envy24control.h"
|
||||
#include "midi.h"
|
||||
|
||||
#define MULTI_PLAYBACK_SWITCH "Multi Playback Switch"
|
||||
#define MULTI_PLAYBACK_VOLUME "Multi Playback Volume"
|
||||
|
|
@ -62,6 +63,8 @@ void mixer_update_stream(int stream, int vol_flag, int sw_flag)
|
|||
toggle_set(mixer_stereo_toggle[stream-1], FALSE);
|
||||
gtk_adjustment_set_value(GTK_ADJUSTMENT(mixer_adj[stream-1][0]), 96 - v[0]);
|
||||
gtk_adjustment_set_value(GTK_ADJUSTMENT(mixer_adj[stream-1][1]), 96 - v[1]);
|
||||
midi_controller(stream*2-1, v[0]);
|
||||
midi_controller(stream*2, v[1]);
|
||||
}
|
||||
if (sw_flag) {
|
||||
snd_ctl_elem_value_t *sw;
|
||||
|
|
@ -139,10 +142,12 @@ static void set_volume1(int stream, int left, int right)
|
|||
if (left >= 0) {
|
||||
change |= (snd_ctl_elem_value_get_integer(vol, 0) != left);
|
||||
snd_ctl_elem_value_set_integer(vol, 0, left);
|
||||
midi_controller(stream*2-1, left);
|
||||
}
|
||||
if (right >= 0) {
|
||||
change |= (snd_ctl_elem_value_get_integer(vol, 1) != right);
|
||||
snd_ctl_elem_value_set_integer(vol, 1, right);
|
||||
midi_controller(stream*2, right);
|
||||
}
|
||||
if (change) {
|
||||
if ((err = snd_ctl_elem_write(ctl, vol)) < 0 && err != -EBUSY)
|
||||
|
|
@ -176,6 +181,8 @@ void mixer_init(void)
|
|||
int nb_active_channels;
|
||||
snd_ctl_elem_value_t *val;
|
||||
|
||||
midi_maxstreams(sizeof(stream_is_active)/sizeof(stream_is_active[0]));
|
||||
|
||||
snd_ctl_elem_value_alloca(&val);
|
||||
snd_ctl_elem_value_set_interface(val, SND_CTL_ELEM_IFACE_MIXER);
|
||||
memset (stream_is_active, 0, (MAX_PCM_OUTPUT_CHANNELS + MAX_SPDIF_CHANNELS + MAX_INPUT_CHANNELS + MAX_SPDIF_CHANNELS) * sizeof(int));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue