updated on Thu Jan 26 16:09:46 UTC 2012
[aur-mirror.git] / tvtime-alsa / tvtime-1.0.2-alsamixer.patch
blob63289e0fee3cf7165393d5dd932235fee15f85ef
1 diff -Nurp tvtime-1.0.2/configure.ac tvtime-1.0.2-alsamixer/configure.ac
2 --- tvtime-1.0.2/configure.ac 2005-09-14 23:40:44.000000000 +0200
3 +++ tvtime-1.0.2-alsamixer/configure.ac 2009-05-11 16:42:46.000000000 +0200
4 @@ -74,18 +74,26 @@ dnl ------------------------------------
5 dnl libxml2
6 dnl ---------------------------------------------
7 dnl Test for libxml2
9 AC_PATH_PROG(LIBXML2_CONFIG,xml2-config,no)
10 if test "$LIBXML2_CONFIG" = "no" ; then
11 AC_MSG_ERROR(libxml2 needed and xml2-config not found)
12 else
13 XML2_LIBS="`$LIBXML2_CONFIG --libs`"
14 XML2_FLAG="`$LIBXML2_CONFIG --cflags`"
15 - AC_DEFINE(HAVE_LIBXML2,,[LIBXML2 support])
16 + AC_DEFINE(HAVE_LIBXML2,,[LIBXML2 support])
18 AC_SUBST(XML2_LIBS)
19 AC_SUBST(XML2_FLAG)
21 +dnl ---------------------------------------------
22 +dnl libasound2
23 +dnl ---------------------------------------------
24 +dnl Test for ALSA
25 +AM_PATH_ALSA(1.0.9,
26 + [ AC_DEFINE(HAVE_ALSA,1,[Define this if you have Alsa (libasound) installed]) ],
27 + AC_MSG_RESULT(libasound needed and not found))
28 +AM_CONDITIONAL(HAVE_ALSA, test x"$no_alsa" != "yes")
31 dnl ---------------------------------------------
32 dnl check for gtk+-2.0
33 diff -Nurp tvtime-1.0.2/src/commands.c tvtime-1.0.2-alsamixer/src/commands.c
34 --- tvtime-1.0.2/src/commands.c 2005-11-10 03:39:05.000000000 +0100
35 +++ tvtime-1.0.2-alsamixer/src/commands.c 2009-05-11 16:42:46.000000000 +0200
36 @@ -3056,10 +3056,10 @@ void commands_handle( commands_t *cmd, i
37 break;
39 case TVTIME_MIXER_TOGGLE_MUTE:
40 - mixer_mute( !mixer_ismute() );
41 + mixer->mute( !mixer->ismute() );
43 if( cmd->osd ) {
44 - tvtime_osd_show_data_bar( cmd->osd, _("Volume"), (mixer_get_volume()) & 0xff );
45 + tvtime_osd_show_data_bar( cmd->osd, _("Volume"), (mixer->get_volume()) & 0xff );
47 break;
49 @@ -3073,9 +3073,9 @@ void commands_handle( commands_t *cmd, i
50 /* Check to see if an argument was passed, if so, use it. */
51 if (atoi(arg) > 0) {
52 int perc = atoi(arg);
53 - volume = mixer_set_volume( ( (tvtime_cmd == TVTIME_MIXER_UP) ? perc : -perc ) );
54 + volume = mixer->set_volume( ( (tvtime_cmd == TVTIME_MIXER_UP) ? perc : -perc ) );
55 } else {
56 - volume = mixer_set_volume( ( (tvtime_cmd == TVTIME_MIXER_UP) ? 1 : -1 ) );
57 + volume = mixer->set_volume( ( (tvtime_cmd == TVTIME_MIXER_UP) ? 1 : -1 ) );
60 if( cmd->osd ) {
61 diff -Nurp tvtime-1.0.2/src/Makefile.am tvtime-1.0.2-alsamixer/src/Makefile.am
62 --- tvtime-1.0.2/src/Makefile.am 2005-02-08 06:00:16.000000000 +0100
63 +++ tvtime-1.0.2-alsamixer/src/Makefile.am 2009-05-11 16:42:46.000000000 +0200
64 @@ -29,6 +29,11 @@ OPT_CFLAGS = -Wall -pedantic -I. -DDATAD
65 -DCONFDIR="\"$(pkgsysconfdir)\"" -DFIFODIR="\"$(tmpdir)\"" \
66 -D_LARGEFILE64_SOURCE -DLOCALEDIR="\"$(localedir)\""
68 +if HAVE_ALSA
69 +ALSA_SRCS = mixer-alsa.c
70 +else
71 +ALSA_SRCS =
72 +endif
73 COMMON_SRCS = mixer.c videoinput.c rtctimer.c leetft.c osdtools.c tvtimeconf.c \
74 pngoutput.c tvtimeosd.c input.c cpu_accel.c speedy.c pnginput.c \
75 deinterlace.c videotools.c attributes.h deinterlace.h leetft.h \
76 @@ -40,7 +45,7 @@ COMMON_SRCS = mixer.c videoinput.c rtcti
77 utils.h utils.c pulldown.h pulldown.c hashtable.h hashtable.c \
78 cpuinfo.h cpuinfo.c videodev.h videodev2.h menu.c menu.h \
79 outputfilter.h outputfilter.c xmltv.h xmltv.c gettext.h tvtimeglyphs.h \
80 - copyfunctions.h copyfunctions.c
81 + copyfunctions.h copyfunctions.c mixer-oss.c $(ALSA_SRCS)
83 if ARCH_X86
84 DSCALER_SRCS = $(top_srcdir)/plugins/dscalerapi.h \
85 @@ -74,10 +79,10 @@ bin_PROGRAMS = tvtime tvtime-command tvt
87 tvtime_SOURCES = $(COMMON_SRCS) $(OUTPUT_SRCS) $(PLUGIN_SRCS) tvtime.c
88 tvtime_CFLAGS = $(TTF_CFLAGS) $(PNG_CFLAGS) $(OPT_CFLAGS) \
89 - $(PLUGIN_CFLAGS) $(X11_CFLAGS) $(XML2_FLAG) \
90 + $(PLUGIN_CFLAGS) $(X11_CFLAGS) $(XML2_FLAG) $(ALSA_CFLAGS) \
91 $(FONT_CFLAGS) $(AM_CFLAGS)
92 tvtime_LDFLAGS = $(TTF_LIBS) $(ZLIB_LIBS) $(PNG_LIBS) \
93 - $(X11_LIBS) $(XML2_LIBS) -lm -lstdc++
94 + $(X11_LIBS) $(XML2_LIBS) $(ALSA_LIBS) -lm -lstdc++
96 tvtime_command_SOURCES = utils.h utils.c tvtimeconf.h tvtimeconf.c \
97 tvtime-command.c
98 @@ -90,6 +95,6 @@ tvtime_configure_LDFLAGS = $(ZLIB_LIBS)
99 tvtime_scanner_SOURCES = utils.h utils.c videoinput.h videoinput.c \
100 tvtimeconf.h tvtimeconf.c station.h station.c tvtime-scanner.c \
101 mixer.h mixer.c
102 -tvtime_scanner_CFLAGS = $(OPT_CFLAGS) $(XML2_FLAG) $(AM_CFLAGS)
103 -tvtime_scanner_LDFLAGS = $(ZLIB_LIBS) $(XML2_LIBS)
104 +tvtime_scanner_CFLAGS = $(OPT_CFLAGS) $(XML2_FLAG) $(ALSA_CFLAGS) $(AM_CFLAGS)
105 +tvtime_scanner_LDFLAGS = $(ZLIB_LIBS) $(XML2_LIBS) $(ALSA_LIBS)
107 diff -Nurp tvtime-1.0.2/src/mixer-alsa.c tvtime-1.0.2-alsamixer/src/mixer-alsa.c
108 --- tvtime-1.0.2/src/mixer-alsa.c 1970-01-01 01:00:00.000000000 +0100
109 +++ tvtime-1.0.2-alsamixer/src/mixer-alsa.c 2009-05-11 16:42:46.000000000 +0200
110 @@ -0,0 +1,240 @@
111 +/**
112 + * Copyright (C) 2006 Philipp Hahn <pmhahn@users.sourceforge.net>
114 + * This program is free software; you can redistribute it and/or modify
115 + * it under the terms of the GNU General Public License as published by
116 + * the Free Software Foundation; either version 2, or (at your option)
117 + * any later version.
119 + * This program is distributed in the hope that it will be useful,
120 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
121 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
122 + * GNU General Public License for more details.
124 + * You should have received a copy of the GNU General Public License
125 + * along with this program; if not, write to the Free Software Foundation,
126 + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
127 + */
129 +#include <stdio.h>
130 +#include <sys/types.h>
131 +#include <string.h>
132 +#include <math.h>
133 +#include <alsa/asoundlib.h>
134 +#include "utils.h"
135 +#include "mixer.h"
137 +static const char alsa_core_devnames[] = "default";
138 +static char *card, *channel;
139 +static int muted = 0;
140 +static int mutecount = 0;
141 +static snd_mixer_t *handle = NULL;
142 +static snd_mixer_elem_t *elem = NULL;
144 +static long alsa_min, alsa_max, alsa_vol;
146 +static void alsa_open_mixer( void )
148 + int err;
149 + static snd_mixer_selem_id_t *sid = NULL;
150 + if ((err = snd_mixer_open (&handle, 0)) < 0) {
151 + fprintf(stderr, "mixer: open error: %s\n", snd_strerror(err));
152 + return;
154 + if ((err = snd_mixer_attach (handle, card)) < 0) {
155 + fprintf(stderr, "mixer: attach error: %s\n", snd_strerror(err));
156 + goto error;
158 + if ((err = snd_mixer_selem_register (handle, NULL, NULL)) < 0) {
159 + fprintf(stderr, "mixer: register error: %s\n", snd_strerror(err));
160 + goto error;
162 + if ((err = snd_mixer_load (handle)) < 0) {
163 + fprintf(stderr, "mixer: load error: %s\n", snd_strerror(err));
164 + goto error;
166 + snd_mixer_selem_id_malloc(&sid);
167 + if (sid == NULL)
168 + goto error;
169 + snd_mixer_selem_id_set_name(sid, channel);
170 + if (!(elem = snd_mixer_find_selem(handle, sid))) {
171 + fprintf(stderr, "mixer: find error: %s\n", snd_strerror(err));
172 + goto error;
174 + if (!snd_mixer_selem_has_playback_volume(elem)) {
175 + fprintf(stderr, "mixer: no playback\n");
176 + goto error;
178 + snd_mixer_selem_get_playback_volume_range(elem, &alsa_min, &alsa_max);
179 + if ((alsa_max - alsa_min) <= 0) {
180 + fprintf(stderr, "mixer: no valid playback range\n");
181 + goto error;
183 + snd_mixer_selem_id_free(sid);
184 + return;
186 +error:
187 + if (sid)
188 + snd_mixer_selem_id_free(sid);
189 + if (handle) {
190 + snd_mixer_close(handle);
191 + handle = NULL;
193 + return;
196 +/* Volume saved to file */
197 +static int alsa_get_unmute_volume( void )
199 + long val;
200 + assert (elem);
202 + if (snd_mixer_selem_is_playback_mono(elem)) {
203 + snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_MONO, &val);
204 + return val;
205 + } else {
206 + int c, n = 0;
207 + long sum = 0;
208 + for (c = 0; c <= SND_MIXER_SCHN_LAST; c++) {
209 + if (snd_mixer_selem_has_playback_channel(elem, c)) {
210 + snd_mixer_selem_get_playback_volume(elem, SND_MIXER_SCHN_FRONT_LEFT, &val);
211 + sum += val;
212 + n++;
215 + if (! n) {
216 + return 0;
219 + val = sum / n;
220 + sum = (long)((double)(alsa_vol * (alsa_max - alsa_min)) / 100. + 0.5);
222 + if (sum != val) {
223 + alsa_vol = (long)(((val * 100.) / (alsa_max - alsa_min)) + 0.5);
225 + return alsa_vol;
229 +static int alsa_get_volume( void )
231 + if (muted)
232 + return 0;
233 + else
234 + return alsa_get_unmute_volume();
237 +static int alsa_set_volume( int percentdiff )
239 + long volume;
241 + alsa_get_volume();
243 + alsa_vol += percentdiff;
244 + if( alsa_vol > 100 ) alsa_vol = 100;
245 + if( alsa_vol < 0 ) alsa_vol = 0;
247 + volume = (long)((alsa_vol * (alsa_max - alsa_min) / 100.) + 0.5);
249 + snd_mixer_selem_set_playback_volume_all(elem, volume + alsa_min);
250 + snd_mixer_selem_set_playback_switch_all(elem, 1);
251 + muted = 0;
252 + mutecount = 0;
254 + return alsa_vol;
257 +static void alsa_mute( int mute )
259 + /**
260 + * Make sure that if multiple users mute the card,
261 + * we only honour the last one.
262 + */
263 + if( !mute && mutecount ) mutecount--;
264 + if( mutecount ) return;
266 + if( mute ) {
267 + mutecount++;
268 + muted = 1;
269 + if (snd_mixer_selem_has_playback_switch(elem))
270 + snd_mixer_selem_set_playback_switch_all(elem, 0);
271 + else
272 + fprintf(stderr, "mixer: mute not implemented\n");
273 + } else {
274 + muted = 0;
275 + if (snd_mixer_selem_has_playback_switch(elem))
276 + snd_mixer_selem_set_playback_switch_all(elem, 1);
277 + else
278 + fprintf(stderr, "mixer: mute not implemented\n");
282 +static int alsa_ismute( void )
284 + return muted;
287 +static int alsa_set_device( const char *devname )
289 + int i;
291 + if (card) free(card);
292 + card = strdup( devname );
293 + if( !card ) return -1;
295 + i = strcspn( card, "/" );
296 + if( i == strlen( card ) ) {
297 + channel = "Line";
298 + } else {
299 + card[i] = 0;
300 + channel = card + i + 1;
302 + alsa_open_mixer();
303 + if (!handle) {
304 + fprintf( stderr, "mixer: Can't open mixer %s, "
305 + "mixer volume and mute unavailable.\n", card );
306 + return -1;
308 + return 0;
311 +static void alsa_set_state( int ismuted, int unmute_volume )
313 + /**
314 + * 1. we come back unmuted: Don't touch anything
315 + * 2. we don't have a saved volume: Don't touch anything
316 + * 3. we come back muted and we have a saved volume:
317 + * - if tvtime muted it, unmute to old volume
318 + * - if user did it, remember that we're muted and old volume
319 + */
320 + if( alsa_get_volume() == 0 && unmute_volume > 0 ) {
321 + snd_mixer_selem_set_playback_volume_all(elem, unmute_volume);
322 + muted = 1;
324 + if( !ismuted ) {
325 + alsa_mute( 0 );
330 +static void alsa_close_device( void )
332 + elem = NULL;
333 + if (handle)
334 + snd_mixer_close(handle);
335 + handle = NULL;
336 + muted = 0;
337 + mutecount = 0;
340 +struct mixer alsa_mixer = {
341 + .set_device = alsa_set_device,
342 + .set_state = alsa_set_state,
343 + .get_volume = alsa_get_volume,
344 + .get_unmute_volume = alsa_get_unmute_volume,
345 + .set_volume = alsa_set_volume,
346 + .mute = alsa_mute,
347 + .ismute = alsa_ismute,
348 + .close_device = alsa_close_device,
350 +// vim: ts=4 sw=4 et foldmethod=marker
351 diff -Nurp tvtime-1.0.2/src/mixer.c tvtime-1.0.2-alsamixer/src/mixer.c
352 --- tvtime-1.0.2/src/mixer.c 2004-10-29 04:15:23.000000000 +0200
353 +++ tvtime-1.0.2-alsamixer/src/mixer.c 2009-05-11 16:42:46.000000000 +0200
354 @@ -19,230 +19,104 @@
355 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
358 -#include <stdio.h>
359 -#include <fcntl.h>
360 -#include <unistd.h>
361 -#include <sys/types.h>
362 -#include <sys/stat.h>
363 -#include <sys/ioctl.h>
364 -#include <sys/soundcard.h>
365 -#include <sys/mman.h>
366 -#include <string.h>
367 -#include "utils.h"
368 #include "mixer.h"
370 -static char *mixer_device = "/dev/mixer";
371 -static int saved_volume = (50 << 8 & 0xFF00) | (50 & 0x00FF);
372 -static int mixer_channel = SOUND_MIXER_LINE;
373 -static int mixer_dev_mask = 1 << SOUND_MIXER_LINE;
374 -static int muted = 0;
375 -static int mutecount = 0;
376 -static int fd = -1;
378 -int mixer_get_volume( void )
380 - int v, cmd, devs;
381 - int curvol = 0;
383 - if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
384 - if( fd != -1 ) {
386 - ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
387 - if( devs & mixer_dev_mask ) {
388 - cmd = MIXER_READ( mixer_channel );
389 - } else {
390 - return curvol;
393 - ioctl( fd, cmd, &v );
394 - curvol = ( v & 0xFF00 ) >> 8;
397 - return curvol;
398 +/**
399 + * Sets the mixer device and channel.
400 + */
401 +static int null_set_device( const char *devname )
403 + return 0;
406 -int mixer_get_unmute_volume( void )
407 +/**
408 + * Sets the initial state of the mixer device.
409 + */
410 +static void null_set_state( int ismuted, int unmute_volume )
412 - if( muted ) {
413 - return saved_volume;
414 - } else {
415 - int v, cmd, devs;
417 - if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
418 - if( fd != -1 ) {
420 - ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
421 - if( devs & mixer_dev_mask ) {
422 - cmd = MIXER_READ( mixer_channel );
423 - } else {
424 - return -1;
427 - ioctl( fd, cmd, &v );
428 - return v;
432 - return -1;
435 -int mixer_set_volume( int percentdiff )
436 +/**
437 + * Returns the current volume setting.
438 + */
439 +static int null_get_volume( void )
441 - int v, cmd, devs, levelpercentage;
443 - levelpercentage = mixer_get_volume();
445 - levelpercentage += percentdiff;
446 - if( levelpercentage > 100 ) levelpercentage = 100;
447 - if( levelpercentage < 0 ) levelpercentage = 0;
449 - if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
450 - if( fd != -1 ) {
451 - ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
452 - if( devs & mixer_dev_mask ) {
453 - cmd = MIXER_WRITE( mixer_channel );
454 - } else {
455 - return 0;
458 - v = ( levelpercentage << 8 ) | levelpercentage;
459 - ioctl( fd, cmd, &v );
460 - muted = 0;
461 - mutecount = 0;
462 - return v;
465 return 0;
468 -void mixer_mute( int mute )
469 +/**
470 + * Returns the volume that would be used to restore the unmute state.
471 + */
472 +static int null_get_unmute_volume( void )
474 - int v, cmd, devs;
476 - /**
477 - * Make sure that if multiple users mute the card,
478 - * we only honour the last one.
479 - */
480 - if( !mute && mutecount ) mutecount--;
481 - if( mutecount ) return;
483 - if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
485 - if( mute ) {
486 - mutecount++;
487 - if( fd != -1 ) {
489 - /* Save volume */
490 - ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
491 - if( devs & mixer_dev_mask ) {
492 - cmd = MIXER_READ( mixer_channel );
493 - } else {
494 - return;
497 - ioctl( fd,cmd,&v );
498 - saved_volume = v;
500 - /* Now set volume to 0 */
501 - ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
502 - if( devs & mixer_dev_mask ) {
503 - cmd = MIXER_WRITE( mixer_channel );
504 - } else {
505 - return;
508 - v = 0;
509 - ioctl( fd, cmd, &v );
511 - muted = 1;
512 - return;
514 - } else {
515 - if( fd != -1 ) {
516 - ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
517 - if( devs & mixer_dev_mask ) {
518 - cmd = MIXER_WRITE( mixer_channel );
519 - } else {
520 - return;
523 - v = saved_volume;
524 - ioctl( fd, cmd, &v );
525 - muted = 0;
526 - return;
529 + return 0;
532 -int mixer_ismute( void )
533 +/**
534 + * Tunes the relative volume.
535 + */
536 +static int null_set_volume( int percentdiff )
538 - return muted;
539 + return 0;
542 -static char *oss_core_devnames[] = SOUND_DEVICE_NAMES;
544 -void mixer_set_device( const char *devname )
545 +/**
546 + * Sets the mute state.
547 + */
548 +static void null_mute( int mute )
550 - const char *channame;
551 - int found = 0;
552 - int i;
554 - mixer_device = strdup( devname );
555 - if( !mixer_device ) return;
557 - i = strcspn( mixer_device, ":" );
558 - if( i == strlen( mixer_device ) ) {
559 - channame = "line";
560 - } else {
561 - mixer_device[ i ] = 0;
562 - channame = mixer_device + i + 1;
564 - if( !file_is_openable_for_read( mixer_device ) ) {
565 - fprintf( stderr, "mixer: Can't open device %s, "
566 - "mixer volume and mute unavailable.\n", mixer_device );
569 - mixer_channel = SOUND_MIXER_LINE;
570 - for( i = 0; i < SOUND_MIXER_NRDEVICES; i++ ) {
571 - if( !strcasecmp( channame, oss_core_devnames[ i ] ) ) {
572 - mixer_channel = i;
573 - found = 1;
574 - break;
577 - if( !found ) {
578 - fprintf( stderr, "mixer: No such mixer channel '%s', using channel 'line'.\n", channame );
580 - mixer_dev_mask = 1 << mixer_channel;
583 -void mixer_set_state( int ismuted, int unmute_volume )
584 +/**
585 + * Returns true if the mixer is muted.
586 + */
587 +static int null_ismute( void )
589 - /**
590 - * 1. we come back unmuted: Don't touch anything
591 - * 2. we don't have a saved volume: Don't touch anything
592 - * 3. we come back muted and we have a saved volume:
593 - * - if tvtime muted it, unmute to old volume
594 - * - if user did it, remember that we're muted and old volume
595 - */
596 - if( mixer_get_volume() == 0 && unmute_volume > 0 ) {
597 - saved_volume = unmute_volume;
598 - muted = 1;
600 - if( !ismuted ) {
601 - mixer_mute( 0 );
604 + return 0;
607 -void mixer_close_device( void )
608 +/**
609 + * Closes the mixer device if it is open.
610 + */
611 +static void null_close_device( void )
613 - if( fd >= 0 ) close( fd );
614 - saved_volume = (50 << 8 & 0xFF00) | (50 & 0x00FF);
615 - mixer_channel = SOUND_MIXER_LINE;
616 - mixer_dev_mask = 1 << SOUND_MIXER_LINE;
617 - muted = 0;
618 - mutecount = 0;
619 - fd = -1;
622 +/* The null device, which always works. */
623 +static struct mixer null_mixer = {
624 + .set_device = null_set_device,
625 + .set_state = null_set_state,
626 + .get_volume = null_get_volume,
627 + .get_unmute_volume = null_get_unmute_volume,
628 + .set_volume = null_set_volume,
629 + .mute = null_mute,
630 + .ismute = null_ismute,
631 + .close_device = null_close_device,
634 +/* List of all available access methods.
635 + * Uses weak symbols: NULL is not linked in. */
636 +static struct mixer *mixers[] = {
637 + &alsa_mixer,
638 + &oss_mixer,
639 + &null_mixer /* LAST */
641 +/* The actual access method. */
642 +struct mixer *mixer = &null_mixer;
644 +/**
645 + * Sets the mixer device and channel.
646 + * Try each access method until one succeeds.
647 + */
648 +void mixer_set_device( const char *devname )
650 + int i;
651 + mixer->close_device();
652 + for (i = 0; i < sizeof(mixers)/sizeof(mixers[0]); i++) {
653 + mixer = mixers[i];
654 + if (!mixer)
655 + continue;
656 + if (mixer->set_device(devname) == 0)
657 + break;
660 diff -Nurp tvtime-1.0.2/src/mixer.h tvtime-1.0.2-alsamixer/src/mixer.h
661 --- tvtime-1.0.2/src/mixer.h 2004-08-27 03:18:49.000000000 +0200
662 +++ tvtime-1.0.2-alsamixer/src/mixer.h 2009-05-11 16:42:46.000000000 +0200
663 @@ -27,45 +27,58 @@ extern "C" {
664 #endif
667 - * Sets the mixer device and channel. The device name is of the form
668 - * devicename:channelname. The default is /dev/mixer:line.
669 + * Sets the mixer device and channel.
670 + * All interfaces are scanned until one succeeds.
672 void mixer_set_device( const char *devname );
674 +struct mixer {
675 +/**
676 + * Sets the mixer device and channel.
677 + */
678 +int (* set_device)( const char *devname );
681 * Sets the initial state of the mixer device.
683 -void mixer_set_state( int ismuted, int unmute_volume );
684 +void (* set_state)( int ismuted, int unmute_volume );
687 * Returns the current volume setting.
689 -int mixer_get_volume( void );
690 +int (* get_volume)( void );
693 * Returns the volume that would be used to restore the unmute state.
695 -int mixer_get_unmute_volume( void );
696 +int (* get_unmute_volume)( void );
699 * Tunes the relative volume.
701 -int mixer_set_volume( int percentdiff );
702 +int (* set_volume)( int percentdiff );
705 * Sets the mute state.
707 -void mixer_mute( int mute );
708 +void (* mute)( int mute );
711 * Returns true if the mixer is muted.
713 -int mixer_ismute( void );
714 +int (* ismute)( void );
717 * Closes the mixer device if it is open.
719 -void mixer_close_device( void );
720 +void (* close_device)( void );
723 +#pragma weak alsa_mixer
724 +extern struct mixer alsa_mixer;
725 +#pragma weak oss_mixer
726 +extern struct mixer oss_mixer;
727 +extern struct mixer *mixer;
729 #ifdef __cplusplus
731 diff -Nurp tvtime-1.0.2/src/mixer-oss.c tvtime-1.0.2-alsamixer/src/mixer-oss.c
732 --- tvtime-1.0.2/src/mixer-oss.c 1970-01-01 01:00:00.000000000 +0100
733 +++ tvtime-1.0.2-alsamixer/src/mixer-oss.c 2009-05-11 16:42:46.000000000 +0200
734 @@ -0,0 +1,261 @@
735 +/**
736 + * Copyright (C) 2002, 2003 Doug Bell <drbell@users.sourceforge.net>
738 + * Some mixer routines from mplayer, http://mplayer.sourceforge.net.
739 + * Copyright (C) 2000-2002. by A'rpi/ESP-team & others
741 + * This program is free software; you can redistribute it and/or modify
742 + * it under the terms of the GNU General Public License as published by
743 + * the Free Software Foundation; either version 2, or (at your option)
744 + * any later version.
746 + * This program is distributed in the hope that it will be useful,
747 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
748 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
749 + * GNU General Public License for more details.
751 + * You should have received a copy of the GNU General Public License
752 + * along with this program; if not, write to the Free Software Foundation,
753 + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
754 + */
756 +#include <stdio.h>
757 +#include <fcntl.h>
758 +#include <unistd.h>
759 +#include <sys/types.h>
760 +#include <sys/stat.h>
761 +#include <sys/ioctl.h>
762 +#include <sys/soundcard.h>
763 +#include <sys/mman.h>
764 +#include <string.h>
765 +#include "utils.h"
766 +#include "mixer.h"
768 +static char *mixer_device = "/dev/mixer";
769 +static int saved_volume = (50 << 8 & 0xFF00) | (50 & 0x00FF);
770 +static int mixer_channel = SOUND_MIXER_LINE;
771 +static int mixer_dev_mask = 1 << SOUND_MIXER_LINE;
772 +static int muted = 0;
773 +static int mutecount = 0;
774 +static int fd = -1;
776 +static int oss_get_volume( void )
778 + int v, cmd, devs;
779 + int curvol = 0;
781 + if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
782 + if( fd != -1 ) {
784 + ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
785 + if( devs & mixer_dev_mask ) {
786 + cmd = MIXER_READ( mixer_channel );
787 + } else {
788 + return curvol;
791 + ioctl( fd, cmd, &v );
792 + curvol = ( v & 0xFF00 ) >> 8;
795 + return curvol;
798 +static int oss_get_unmute_volume( void )
800 + if( muted ) {
801 + return saved_volume;
802 + } else {
803 + int v, cmd, devs;
805 + if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
806 + if( fd != -1 ) {
808 + ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
809 + if( devs & mixer_dev_mask ) {
810 + cmd = MIXER_READ( mixer_channel );
811 + } else {
812 + return -1;
815 + ioctl( fd, cmd, &v );
816 + return v;
820 + return -1;
823 +static int oss_set_volume( int percentdiff )
825 + int v, cmd, devs, levelpercentage;
827 + levelpercentage = oss_get_volume();
829 + levelpercentage += percentdiff;
830 + if( levelpercentage > 100 ) levelpercentage = 100;
831 + if( levelpercentage < 0 ) levelpercentage = 0;
833 + if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
834 + if( fd != -1 ) {
835 + ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
836 + if( devs & mixer_dev_mask ) {
837 + cmd = MIXER_WRITE( mixer_channel );
838 + } else {
839 + return 0;
842 + v = ( levelpercentage << 8 ) | levelpercentage;
843 + ioctl( fd, cmd, &v );
844 + muted = 0;
845 + mutecount = 0;
846 + return v;
849 + return 0;
852 +static void oss_mute( int mute )
854 + int v, cmd, devs;
856 + /**
857 + * Make sure that if multiple users mute the card,
858 + * we only honour the last one.
859 + */
860 + if( !mute && mutecount ) mutecount--;
861 + if( mutecount ) return;
863 + if( fd < 0 ) fd = open( mixer_device, O_RDONLY );
865 + if( mute ) {
866 + mutecount++;
867 + if( fd != -1 ) {
869 + /* Save volume */
870 + ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
871 + if( devs & mixer_dev_mask ) {
872 + cmd = MIXER_READ( mixer_channel );
873 + } else {
874 + return;
877 + ioctl( fd,cmd,&v );
878 + saved_volume = v;
880 + /* Now set volume to 0 */
881 + ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
882 + if( devs & mixer_dev_mask ) {
883 + cmd = MIXER_WRITE( mixer_channel );
884 + } else {
885 + return;
888 + v = 0;
889 + ioctl( fd, cmd, &v );
891 + muted = 1;
892 + return;
894 + } else {
895 + if( fd != -1 ) {
896 + ioctl( fd, SOUND_MIXER_READ_DEVMASK, &devs );
897 + if( devs & mixer_dev_mask ) {
898 + cmd = MIXER_WRITE( mixer_channel );
899 + } else {
900 + return;
903 + v = saved_volume;
904 + ioctl( fd, cmd, &v );
905 + muted = 0;
906 + return;
911 +static int oss_ismute( void )
913 + return muted;
916 +static char *oss_core_devnames[] = SOUND_DEVICE_NAMES;
918 +static int oss_set_device( const char *devname )
920 + const char *channame;
921 + int found = 0;
922 + int i;
924 + mixer_device = strdup( devname );
925 + if( !mixer_device ) return -1;
927 + i = strcspn( mixer_device, ":" );
928 + if( i == strlen( mixer_device ) ) {
929 + channame = "line";
930 + } else {
931 + mixer_device[ i ] = 0;
932 + channame = mixer_device + i + 1;
934 + if( !file_is_openable_for_read( mixer_device ) ) {
935 + fprintf( stderr, "mixer: Can't open device %s, "
936 + "mixer volume and mute unavailable.\n", mixer_device );
937 + return -1;
940 + mixer_channel = SOUND_MIXER_LINE;
941 + for( i = 0; i < SOUND_MIXER_NRDEVICES; i++ ) {
942 + if( !strcasecmp( channame, oss_core_devnames[ i ] ) ) {
943 + mixer_channel = i;
944 + found = 1;
945 + break;
948 + if( !found ) {
949 + fprintf( stderr, "mixer: No such mixer channel '%s', using channel 'line'.\n", channame );
950 + return -1;
952 + mixer_dev_mask = 1 << mixer_channel;
953 + return 0;
956 +static void oss_set_state( int ismuted, int unmute_volume )
958 + /**
959 + * 1. we come back unmuted: Don't touch anything
960 + * 2. we don't have a saved volume: Don't touch anything
961 + * 3. we come back muted and we have a saved volume:
962 + * - if tvtime muted it, unmute to old volume
963 + * - if user did it, remember that we're muted and old volume
964 + */
965 + if( oss_get_volume() == 0 && unmute_volume > 0 ) {
966 + saved_volume = unmute_volume;
967 + muted = 1;
969 + if( !ismuted ) {
970 + oss_mute( 0 );
975 +static void oss_close_device( void )
977 + if( fd >= 0 ) close( fd );
978 + saved_volume = (50 << 8 & 0xFF00) | (50 & 0x00FF);
979 + mixer_channel = SOUND_MIXER_LINE;
980 + mixer_dev_mask = 1 << SOUND_MIXER_LINE;
981 + muted = 0;
982 + mutecount = 0;
983 + fd = -1;
986 +struct mixer oss_mixer = {
987 + .set_device = oss_set_device,
988 + .set_state = oss_set_state,
989 + .get_volume = oss_get_volume,
990 + .get_unmute_volume = oss_get_unmute_volume,
991 + .set_volume = oss_set_volume,
992 + .mute = oss_mute,
993 + .ismute = oss_ismute,
994 + .close_device = oss_close_device,
996 diff -Nurp tvtime-1.0.2/src/tvtime.c tvtime-1.0.2-alsamixer/src/tvtime.c
997 --- tvtime-1.0.2/src/tvtime.c 2005-09-08 04:55:54.000000000 +0200
998 +++ tvtime-1.0.2-alsamixer/src/tvtime.c 2009-05-11 16:42:46.000000000 +0200
999 @@ -1441,7 +1441,7 @@ int tvtime_main( rtctimer_t *rtctimer, i
1001 /* Set the mixer device. */
1002 mixer_set_device( config_get_mixer_device( ct ) );
1003 - mixer_set_state( config_get_muted( ct ), config_get_unmute_volume( ct ) );
1004 + mixer->set_state( config_get_muted( ct ), config_get_unmute_volume( ct ) );
1006 /* Setup OSD stuff. */
1007 pixel_aspect = ( (double) width ) /
1008 @@ -2565,14 +2565,14 @@ int tvtime_main( rtctimer_t *rtctimer, i
1009 snprintf( number, 4, "%d", quiet_screenshots );
1010 config_save( ct, "QuietScreenshots", number );
1012 - snprintf( number, 6, "%d", mixer_get_unmute_volume() );
1013 + snprintf( number, 6, "%d", mixer->get_unmute_volume() );
1014 config_save( ct, "UnmuteVolume", number );
1016 - snprintf( number, 4, "%d", mixer_ismute() );
1017 + snprintf( number, 4, "%d", mixer->ismute() );
1018 config_save( ct, "Muted", number );
1020 if( config_get_mute_on_exit( ct ) ) {
1021 - mixer_mute( 1 );
1022 + mixer->mute( 1 );
1025 if( vidin ) {
1026 @@ -2619,7 +2619,7 @@ int tvtime_main( rtctimer_t *rtctimer, i
1027 if( osd ) {
1028 tvtime_osd_delete( osd );
1030 - mixer_close_device();
1031 + mixer->close_device();
1033 /* Free temporary memory. */
1034 free( colourbars );
1035 diff -Nurp tvtime-1.0.2/src/videoinput.c tvtime-1.0.2-alsamixer/src/videoinput.c
1036 --- tvtime-1.0.2/src/videoinput.c 2005-09-08 05:13:37.000000000 +0200
1037 +++ tvtime-1.0.2-alsamixer/src/videoinput.c 2009-05-11 16:42:46.000000000 +0200
1038 @@ -1269,7 +1269,7 @@ void videoinput_set_tuner_freq( videoinp
1041 vidin->change_muted = 1;
1042 - mixer_mute( 1 );
1043 + mixer->mute( 1 );
1044 videoinput_do_mute( vidin, vidin->user_muted || vidin->change_muted );
1045 vidin->cur_tuner_state = TUNER_STATE_SIGNAL_DETECTED;
1046 vidin->signal_acquire_wait = SIGNAL_ACQUIRE_DELAY;
1047 @@ -1620,7 +1620,7 @@ int videoinput_check_for_signal( videoin
1048 if( vidin->change_muted ) {
1049 vidin->change_muted = 0;
1050 videoinput_do_mute( vidin, vidin->user_muted || vidin->change_muted );
1051 - mixer_mute( 0 );
1052 + mixer->mute( 0 );
1054 break;
1056 @@ -1631,7 +1631,7 @@ int videoinput_check_for_signal( videoin
1057 vidin->cur_tuner_state = TUNER_STATE_SIGNAL_LOST;
1058 vidin->signal_recover_wait = SIGNAL_RECOVER_DELAY;
1059 vidin->change_muted = 1;
1060 - mixer_mute( 1 );
1061 + mixer->mute( 1 );
1062 videoinput_do_mute( vidin, vidin->user_muted || vidin->change_muted );
1063 case TUNER_STATE_SIGNAL_LOST:
1064 if( vidin->signal_recover_wait ) {