annotate src/alsaplay.c @ 5518:3cc7470ea71c

gnuclient: if TMPDIR was set and connect failed, try again with /tmp 2011-06-03 Aidan Kehoe <kehoea@parhasard.net> * gnuslib.c (connect_to_unix_server): Retry with /tmp as a directory in which to search for Unix sockets if an attempt to connect with some other directory failed (which may be because gnuclient and gnuserv don't share an environment value for TMPDIR, or because gnuserv was compiled with USE_TMPDIR turned off).
author Aidan Kehoe <kehoea@parhasard.net>
date Fri, 03 Jun 2011 18:40:57 +0100
parents 308d34e9f07d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
1 /* Play sound with the ALSA library
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
2 Copyright (C) 2006 Jerry James.
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
3
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
4 This file is part of XEmacs.
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
5
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 4976
diff changeset
6 XEmacs is free software: you can redistribute it and/or modify it
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
7 under the terms of the GNU General Public License as published by the
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 4976
diff changeset
8 Free Software Foundation, either version 3 of the License, or (at your
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 4976
diff changeset
9 option) any later version.
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
10
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
11 XEmacs is distributed in the hope that it will be useful, but WITHOUT
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
14 for more details.
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
15
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
5402
308d34e9f07d Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents: 4976
diff changeset
17 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. */
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
18
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
19 /* Synched up with: Not in FSF. */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
20
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
21 /* TODO: Support asynchronous sound playing; see the NAS support in sound.c */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
22
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
23 #include <config.h>
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
24 #include "lisp.h"
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
25 #include "sound.h"
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
26 #include "sysfile.h"
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
27
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
28 /* We can't just include <alsa/asoundlib.h> because it tries to redefine
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
29 * several symbols defined by the previous header files.
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
30 */
3347
316f3f347b4f [xemacs-hg @ 2006-04-18 17:28:30 by james]
james
parents: 3335
diff changeset
31 #include <alsa/version.h>
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
32 #include <alsa/input.h>
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
33 #include <alsa/output.h>
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
34 #include <alsa/conf.h>
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
35 #include <alsa/global.h>
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
36 #include <alsa/pcm.h>
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
37 #include <alsa/error.h>
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
38 #include <alsa/hwdep.h>
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
39 #include <alsa/rawmidi.h>
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
40 #include <alsa/control.h>
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
41 #include <alsa/mixer.h>
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
42
3335
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
43 #define ALSA_VERSION(major,minor,sub) (((major)<<16) | ((minor)<<8)| (sub))
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
44
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
45 struct mixer_state
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
46 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
47 snd_mixer_t *mixer;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
48 snd_mixer_elem_t *vol_ctl;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
49
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
50 /* Which channels need the old volume restored */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
51 int reset_front_left;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
52 int reset_front_center;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
53 int reset_front_right;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
54 int reset_rear_left;
3335
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
55 int reset_rear_right;
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
56 int reset_woofer;
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
57 #if SND_LIB_VERSION >= ALSA_VERSION (1, 0, 10)
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
58 int reset_rear_center;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
59 int reset_side_left;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
60 int reset_side_right;
3335
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
61 #endif
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
62
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
63 /* Old volumes for the channels */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
64 long front_left_vol;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
65 long front_center_vol;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
66 long front_right_vol;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
67 long rear_left_vol;
3335
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
68 long rear_right_vol;
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
69 long woofer_vol;
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
70 #if SND_LIB_VERSION >= ALSA_VERSION (1, 0, 10)
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
71 long rear_center_vol;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
72 long side_left_vol;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
73 long side_right_vol;
3335
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
74 #endif
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
75 };
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
76
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
77 /* Assemble a machine half-word in little-endian order */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
78 #define HALF_LE(arr,start) (arr[start] + (arr[start + 1] << 8))
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
79
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
80 /* Assemble a machine word in little-endian order */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
81 #define WORD_LE(arr,start) (arr[start] + (arr[start + 1] << 8) + \
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
82 (arr[start + 2] << 16) + (arr[start + 3] << 24))
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
83
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
84 /* Assemble a machine word in big-endian order */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
85 #define WORD_BE(arr,start) ((arr[start] << 24) + (arr[start + 1] << 16) + \
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
86 (arr[start + 2] << 8) + arr[start + 3])
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
87
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
88 /* This function was inspired by miscplay.c.
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
89 * Examine sound data to determine its format.
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
90 *
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
91 * TODO: Detect other formats that ALSA can play, such as GSM and MPEG.
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
92 */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
93 static snd_pcm_format_t
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
94 analyze_format (const Binbyte *format, int *speed, int *tracks)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
95 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
96 if (!memcmp (format, "Creative Voice File\x1A\x1A\x00", 22) &&
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
97 HALF_LE (format, 22) == ((0x1233 - HALF_LE (format, 24)) & 0xFFFF))
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
98 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
99 /* VOC */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
100 *speed = 8000;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
101 *tracks = 2;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
102 return SND_PCM_FORMAT_U8;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
103 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
104 else if (!memcmp (format, "RIFF", 4) && !memcmp (format + 8, "WAVEfmt ", 8))
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
105 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
106 /* WAVE */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
107 *speed = WORD_LE (format, 24);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
108 *tracks = format[22];
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
109 return format[32] / format[22] == 1
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
110 ? SND_PCM_FORMAT_U8
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
111 : SND_PCM_FORMAT_S16_LE;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
112 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
113 else if (!memcmp (format, ".snd", 4))
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
114 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
115 /* Sun/NeXT Audio (big endian) */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
116 if (WORD_BE (format, 4) < 24)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
117 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
118 *speed = 8000;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
119 *tracks = 1;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
120 return SND_PCM_FORMAT_MU_LAW;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
121 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
122 *speed = WORD_BE (format, 16);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
123 *tracks = format[23];
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
124 if (!memcmp (format + 12, "\000\000\000", 3))
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
125 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
126 switch (format[15])
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
127 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
128 case 1:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
129 case 17:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
130 case 29:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
131 return SND_PCM_FORMAT_MU_LAW;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
132 case 2:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
133 return SND_PCM_FORMAT_S8;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
134 case 3:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
135 return SND_PCM_FORMAT_S16_BE;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
136 case 4:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
137 return SND_PCM_FORMAT_S24_BE;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
138 case 5:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
139 return SND_PCM_FORMAT_S32_BE;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
140 case 23:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
141 case 24:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
142 case 25:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
143 case 26:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
144 return SND_PCM_FORMAT_IMA_ADPCM;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
145 case 27:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
146 return SND_PCM_FORMAT_A_LAW;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
147 default:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
148 break;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
149 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
150 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
151 return SND_PCM_FORMAT_UNKNOWN;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
152 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
153 else if (!memcmp (format, ".sd", 4))
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
154 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
155 /* DEC Audio (little endian) */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
156 if (WORD_LE (format, 4) < 24)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
157 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
158 *speed = 8000;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
159 *tracks = 1;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
160 return SND_PCM_FORMAT_MU_LAW;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
161 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
162 *speed = WORD_LE (format, 16);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
163 *tracks = format[20];
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
164 if (!memcmp (format + 13, "\000\000\000", 3))
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
165 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
166 switch (format[12])
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
167 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
168 case 1:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
169 case 17:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
170 case 29:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
171 return SND_PCM_FORMAT_MU_LAW;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
172 case 2:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
173 return SND_PCM_FORMAT_S8;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
174 case 3:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
175 return SND_PCM_FORMAT_S16_LE;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
176 case 4:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
177 return SND_PCM_FORMAT_S24_LE;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
178 case 5:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
179 return SND_PCM_FORMAT_S32_LE;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
180 case 23:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
181 case 24:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
182 case 25:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
183 case 26:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
184 return SND_PCM_FORMAT_IMA_ADPCM;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
185 case 27:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
186 return SND_PCM_FORMAT_A_LAW;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
187 default:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
188 break;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
189 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
190 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
191 return SND_PCM_FORMAT_UNKNOWN;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
192 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
193 else
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
194 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
195 /* We don't know what it is. Guess that it is mono audio in unsigned
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
196 * byte format. Maybe we should error if we reach this point.
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
197 */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
198 *speed = 8000;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
199 *tracks = 1;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
200 return SND_PCM_FORMAT_U8;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
201 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
202 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
203
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
204 /* Set the volume: if any errors occur, we accept the existing volume */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
205 static void
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
206 set_volume (struct mixer_state *mix, int volume)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
207 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
208 snd_mixer_selem_id_t *volume_id;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
209 long min_vol, max_vol, dev_vol;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
210
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
211 if (snd_mixer_open (&mix->mixer, 0) < 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
212 return;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
213
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
214 if (snd_mixer_attach (mix->mixer, "default") < 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
215 return;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
216
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
217 if (snd_mixer_selem_register (mix->mixer, NULL, NULL) < 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
218 return;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
219
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
220 if (snd_mixer_load (mix->mixer) < 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
221 return;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
222
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
223 snd_mixer_selem_id_alloca (&volume_id);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
224 snd_mixer_selem_id_set_name (volume_id, "PCM");
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
225
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
226 if ((mix->vol_ctl = snd_mixer_find_selem (mix->mixer, volume_id)) == NULL)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
227 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
228 snd_mixer_selem_id_set_name (volume_id, "Master");
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
229 if ((mix->vol_ctl = snd_mixer_find_selem (mix->mixer, volume_id))
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
230 == NULL)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
231 return;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
232 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
233
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
234 /* Translate the Lisp volume range to the device volume range */
3335
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
235 #if SND_LIB_VERSION < ALSA_VERSION (1, 0, 10)
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
236 snd_mixer_selem_get_playback_volume_range (mix->vol_ctl, &min_vol, &max_vol);
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
237 #else
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
238 if (snd_mixer_selem_get_playback_volume_range (mix->vol_ctl, &min_vol,
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
239 &max_vol) < 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
240 return;
3335
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
241 #endif
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
242
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
243 dev_vol = volume * (max_vol - min_vol) / 100 + min_vol;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
244
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
245 /* Record the old volumes */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
246 if (snd_mixer_selem_get_playback_volume
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
247 (mix->vol_ctl, SND_MIXER_SCHN_FRONT_LEFT, &mix->front_left_vol) >= 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
248 mix->reset_front_left = 1;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
249
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
250 if (snd_mixer_selem_get_playback_volume
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
251 (mix->vol_ctl, SND_MIXER_SCHN_FRONT_CENTER, &mix->front_center_vol) >= 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
252 mix->reset_front_center = 1;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
253
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
254 if (snd_mixer_selem_get_playback_volume
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
255 (mix->vol_ctl, SND_MIXER_SCHN_FRONT_RIGHT, &mix->front_right_vol) >= 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
256 mix->reset_front_right = 1;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
257
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
258 if (snd_mixer_selem_get_playback_volume
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
259 (mix->vol_ctl, SND_MIXER_SCHN_REAR_LEFT, &mix->rear_left_vol) >= 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
260 mix->reset_rear_left = 1;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
261
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
262 if (snd_mixer_selem_get_playback_volume
3335
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
263 (mix->vol_ctl, SND_MIXER_SCHN_REAR_RIGHT, &mix->rear_right_vol) >= 0)
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
264 mix->reset_rear_right = 1;
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
265
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
266 if (snd_mixer_selem_get_playback_volume
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
267 (mix->vol_ctl, SND_MIXER_SCHN_WOOFER, &mix->woofer_vol) >= 0)
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
268 mix->reset_woofer = 1;
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
269
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
270 #if SND_LIB_VERSION >= ALSA_VERSION (1, 0, 10)
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
271 if (snd_mixer_selem_get_playback_volume
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
272 (mix->vol_ctl, SND_MIXER_SCHN_REAR_CENTER, &mix->rear_center_vol) >= 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
273 mix->reset_rear_center = 1;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
274
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
275 if (snd_mixer_selem_get_playback_volume
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
276 (mix->vol_ctl, SND_MIXER_SCHN_SIDE_LEFT, &mix->side_left_vol) >= 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
277 mix->reset_side_left = 1;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
278
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
279 if (snd_mixer_selem_get_playback_volume
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
280 (mix->vol_ctl, SND_MIXER_SCHN_SIDE_RIGHT, &mix->side_right_vol) >= 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
281 mix->reset_side_right = 1;
3335
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
282 #endif
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
283
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
284 /* Set the volume */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
285 snd_mixer_selem_set_playback_volume_all (mix->vol_ctl, dev_vol);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
286 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
287
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
288 static void
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
289 reset_volume (const struct mixer_state *mix)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
290 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
291 if (mix->reset_front_left)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
292 snd_mixer_selem_set_playback_volume
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
293 (mix->vol_ctl, SND_MIXER_SCHN_FRONT_LEFT, mix->front_left_vol);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
294
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
295 if (mix->reset_front_center)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
296 snd_mixer_selem_set_playback_volume
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
297 (mix->vol_ctl, SND_MIXER_SCHN_FRONT_CENTER, mix->front_center_vol);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
298
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
299 if (mix->reset_front_right)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
300 snd_mixer_selem_set_playback_volume
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
301 (mix->vol_ctl, SND_MIXER_SCHN_FRONT_RIGHT, mix->front_right_vol);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
302
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
303 if (mix->reset_rear_left)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
304 snd_mixer_selem_set_playback_volume
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
305 (mix->vol_ctl, SND_MIXER_SCHN_REAR_LEFT, mix->rear_left_vol);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
306
3335
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
307 if (mix->reset_rear_right)
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
308 snd_mixer_selem_set_playback_volume
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
309 (mix->vol_ctl, SND_MIXER_SCHN_REAR_RIGHT, mix->rear_right_vol);
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
310
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
311 if (mix->reset_woofer)
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
312 snd_mixer_selem_set_playback_volume
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
313 (mix->vol_ctl, SND_MIXER_SCHN_WOOFER, mix->woofer_vol);
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
314
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
315 #if SND_LIB_VERSION >= ALSA_VERSION (1, 0, 10)
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
316 if (mix->reset_rear_center)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
317 snd_mixer_selem_set_playback_volume
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
318 (mix->vol_ctl, SND_MIXER_SCHN_REAR_CENTER, mix->rear_center_vol);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
319
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
320 if (mix->reset_side_left)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
321 snd_mixer_selem_set_playback_volume
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
322 (mix->vol_ctl, SND_MIXER_SCHN_SIDE_LEFT, mix->side_left_vol);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
323
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
324 if (mix->reset_side_right)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
325 snd_mixer_selem_set_playback_volume
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
326 (mix->vol_ctl, SND_MIXER_SCHN_SIDE_RIGHT, mix->side_right_vol);
3335
f63530aa6c68 [xemacs-hg @ 2006-04-10 15:16:45 by james]
james
parents: 3308
diff changeset
327 #endif
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
328
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
329 snd_mixer_close (mix->mixer);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
330 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
331
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
332 int
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
333 alsa_play_sound_data (const Binbyte *data, int length, int volume)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
334 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
335 snd_pcm_t *pcm_handle;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
336 snd_pcm_hw_params_t *hwparams;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
337 snd_pcm_format_t format;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
338 struct mixer_state mix;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
339 int speed, tracks, err;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
340
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
341 /* Set the PCM parameters */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
342 if ((err = snd_pcm_open (&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK,
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
343 0)) < 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
344 goto error_pcm_open;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
345
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
346 snd_pcm_hw_params_alloca (&hwparams);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
347
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
348 if ((err = snd_pcm_hw_params_any (pcm_handle, hwparams)) < 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
349 goto error_pcm;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
350
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
351 format = analyze_format (data, &speed, &tracks);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
352
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
353 if ((err = snd_pcm_hw_params_set_access (pcm_handle, hwparams,
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
354 SND_PCM_ACCESS_RW_INTERLEAVED)) < 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
355 goto error_pcm;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
356
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
357 if ((err = snd_pcm_hw_params_set_format (pcm_handle, hwparams, format)) < 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
358 goto error_pcm;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
359
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
360 if ((err = snd_pcm_hw_params_set_rate (pcm_handle, hwparams, speed, 0)) < 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
361 goto error_pcm;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
362
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
363 if ((err = snd_pcm_hw_params_set_channels (pcm_handle, hwparams, tracks))
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
364 < 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
365 goto error_pcm;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
366
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
367 if ((err = snd_pcm_hw_params (pcm_handle, hwparams)) < 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
368 goto error_pcm;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
369
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
370 /* Set the volume */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
371 memset (&mix, 0, sizeof (mix));
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
372 set_volume (&mix, volume);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
373
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
374 /* Play the sound */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
375 if ((err = snd_pcm_writei (pcm_handle, data, length)) < 0)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
376 goto error_mixer;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
377
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
378 /* Put the volume back the way it used to be */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
379 reset_volume (&mix);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
380
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
381 /* Release resources */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
382 snd_pcm_close (pcm_handle);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
383 return 1;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
384
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
385 error_mixer:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
386 reset_volume (&mix);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
387 error_pcm:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
388 snd_pcm_close (pcm_handle);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
389 error_pcm_open:
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
390 sound_perror (snd_strerror (err));
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
391 return 0;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
392 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
393
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
394 /* Read the sound file into an internal buffer, then call
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
395 * alsa_play_sound_data.
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
396 */
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
397 int
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
398 alsa_play_sound_file (const Extbyte *sound_file, int volume)
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
399 {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
400 Binbyte *data;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
401 int fd, retval;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
402 struct stat st;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
403
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
404 fd = retry_open (sound_file, O_RDONLY, 0);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
405 if (fd < 0) {
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
406 sound_perror (sound_file);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
407 return 0;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
408 }
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
409
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
410 qxe_fstat (fd, &st);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
411 data = xnew_array (Binbyte, st.st_size);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
412 retry_read (fd, data, st.st_size);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
413 retry_close (fd);
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
414 retval = alsa_play_sound_data (data, st.st_size, volume);
4976
16112448d484 Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents: 3347
diff changeset
415 xfree (data);
3308
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
416 return retval;
34cfe24248f6 [xemacs-hg @ 2006-03-27 17:40:45 by james]
james
parents:
diff changeset
417 }