Mercurial > audlegacy
annotate Plugins/Output/alsa/audio.c @ 1362:651327e12a3a trunk
[svn] - use of sleep() or usleep() in multi-thread program may cause 100% CPU usage because of signal distribution.
author | yaz |
---|---|
date | Fri, 30 Jun 2006 04:18:20 -0700 |
parents | 7baea4fb20a4 |
children | f12d7e208b43 |
rev | line source |
---|---|
61 | 1 /* XMMS - ALSA output plugin |
2 * Copyright (C) 2001-2003 Matthieu Sozeau <mattam@altern.org> | |
3 * Copyright (C) 1998-2003 Peter Alm, Mikael Alm, Olle Hallnas, | |
4 * Thomas Nilsson and 4Front Technologies | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
5 * Copyright (C) 1999-2005 Haavard Kvaalen |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
6 * Copyright (C) 2005 Takashi Iwai |
61 | 7 * |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
21 */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
22 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
23 /* |
61 | 24 * CHANGES |
25 * | |
26 * 2005.01.05 Takashi Iwai <tiwai@suse.de> | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
27 * Impelemented the multi-threaded mode with an audio-thread. |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
28 * Many fixes and cleanups. |
61 | 29 */ |
30 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
31 |
61 | 32 #include "alsa.h" |
33 #include <ctype.h> | |
34 #include <libaudacious/xconvert.h> | |
35 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
36 static snd_pcm_t *alsa_pcm; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
37 static snd_output_t *logs; |
61 | 38 |
39 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
40 /* Number of bytes that we have received from the input plugin */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
41 static guint64 alsa_total_written; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
42 /* Number of bytes that we have sent to the sound card */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
43 static guint64 alsa_hw_written; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
44 static guint64 output_time_offset; |
61 | 45 |
46 /* device buffer/period sizes in bytes */ | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
47 static int hw_buffer_size, hw_period_size; /* in output bytes */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
48 static int hw_buffer_size_in, hw_period_size_in; /* in input bytes */ |
61 | 49 |
50 /* Set/Get volume */ | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
51 static snd_mixer_elem_t *pcm_element; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
52 static snd_mixer_t *mixer; |
61 | 53 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
54 static gboolean going, paused, mixer_start = TRUE; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
55 static gboolean prebuffer, remove_prebuffer; |
61 | 56 |
57 static gboolean alsa_can_pause; | |
58 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
59 /* for audio thread */ |
215 | 60 static GThread *audio_thread; /* audio loop thread */ |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
61 static int thread_buffer_size; /* size of intermediate buffer in bytes */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
62 static char *thread_buffer; /* audio intermediate buffer */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
63 static int rd_index, wr_index; /* current read/write position in int-buffer */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
64 static gboolean pause_request; /* pause status currently requested */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
65 static int flush_request; /* flush status (time) currently requested */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
66 static int prebuffer_size; |
1278 | 67 GMutex *alsa_mutex; |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
68 |
61 | 69 static guint mixer_timeout; |
70 | |
71 struct snd_format { | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
72 unsigned int rate; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
73 unsigned int channels; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
74 snd_pcm_format_t format; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
75 AFormat xmms_format; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
76 int sample_bits; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
77 int bps; |
61 | 78 }; |
79 | |
80 static struct snd_format *inputf = NULL; | |
81 static struct snd_format *effectf = NULL; | |
82 static struct snd_format *outputf = NULL; | |
83 | |
84 static int alsa_setup(struct snd_format *f); | |
85 static void alsa_write_audio(char *data, int length); | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
86 static void alsa_cleanup_mixer(void); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
87 static int get_thread_buffer_filled(void); |
61 | 88 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
89 static struct snd_format * snd_format_from_xmms(AFormat fmt, int rate, int channels); |
61 | 90 |
91 static struct xmms_convert_buffers *convertb; | |
92 | |
93 static convert_func_t alsa_convert_func; | |
94 static convert_channel_func_t alsa_stereo_convert_func; | |
95 static convert_freq_func_t alsa_frequency_convert_func; | |
96 | |
97 static const struct { | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
98 AFormat xmms; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
99 snd_pcm_format_t alsa; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
100 } format_table[] = |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
101 {{FMT_S16_LE, SND_PCM_FORMAT_S16_LE}, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
102 {FMT_S16_BE, SND_PCM_FORMAT_S16_BE}, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
103 {FMT_S16_NE, SND_PCM_FORMAT_S16}, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
104 {FMT_U16_LE, SND_PCM_FORMAT_U16_LE}, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
105 {FMT_U16_BE, SND_PCM_FORMAT_U16_BE}, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
106 {FMT_U16_NE, SND_PCM_FORMAT_U16}, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
107 {FMT_U8, SND_PCM_FORMAT_U8}, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
108 {FMT_S8, SND_PCM_FORMAT_S8}, |
61 | 109 }; |
110 | |
111 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
112 static void debug(char *str, ...) G_GNUC_PRINTF(1, 2); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
113 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
114 static void debug(char *str, ...) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
115 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
116 va_list args; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
117 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
118 if (alsa_cfg.debug) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
119 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
120 va_start(args, str); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
121 g_logv(NULL, G_LOG_LEVEL_MESSAGE, str, args); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
122 va_end(args); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
123 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
124 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
125 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
126 int alsa_playing(void) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
127 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
128 if (!going || paused || alsa_pcm == NULL) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
129 return FALSE; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
130 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
131 return snd_pcm_state(alsa_pcm) == SND_PCM_STATE_RUNNING; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
132 } |
61 | 133 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
134 static int xrun_recover(void) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
135 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
136 if (alsa_cfg.debug) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
137 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
138 snd_pcm_status_t *alsa_status; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
139 snd_pcm_status_alloca(&alsa_status); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
140 if (snd_pcm_status(alsa_pcm, alsa_status) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
141 g_warning("xrun_recover(): snd_pcm_status() failed"); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
142 else |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
143 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
144 printf("Status:\n"); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
145 snd_pcm_status_dump(alsa_status, logs); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
146 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
147 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
148 return snd_pcm_prepare(alsa_pcm); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
149 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
150 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
151 static int suspend_recover(void) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
152 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
153 int err; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
154 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
155 while ((err = snd_pcm_resume(alsa_pcm)) == -EAGAIN) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
156 /* wait until suspend flag is released */ |
1362
651327e12a3a
[svn] - use of sleep() or usleep() in multi-thread program may cause 100% CPU usage because of signal distribution.
yaz
parents:
1278
diff
changeset
|
157 xmms_usleep(1000000); |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
158 if (err < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
159 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
160 g_warning("alsa_handle_error(): " |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
161 "snd_pcm_resume() failed."); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
162 return snd_pcm_prepare(alsa_pcm); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
163 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
164 return err; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
165 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
166 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
167 /* handle generic errors */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
168 static int alsa_handle_error(int err) |
61 | 169 { |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
170 switch (err) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
171 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
172 case -EPIPE: |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
173 return xrun_recover(); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
174 case -ESTRPIPE: |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
175 return suspend_recover(); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
176 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
177 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
178 return err; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
179 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
180 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
181 /* update and get the available space on h/w buffer (in frames) */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
182 static snd_pcm_sframes_t alsa_get_avail(void) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
183 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
184 snd_pcm_sframes_t ret; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
185 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
186 if (alsa_pcm == NULL) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
187 return 0; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
188 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
189 while ((ret = snd_pcm_avail_update(alsa_pcm)) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
190 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
191 ret = alsa_handle_error(ret); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
192 if (ret < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
193 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
194 g_warning("alsa_get_avail(): snd_pcm_avail_update() failed: %s", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
195 snd_strerror(-ret)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
196 return 0; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
197 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
198 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
199 return ret; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
200 } |
61 | 201 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
202 /* get the free space on buffer */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
203 int alsa_free(void) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
204 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
205 if (remove_prebuffer && prebuffer) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
206 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
207 prebuffer = FALSE; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
208 remove_prebuffer = FALSE; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
209 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
210 if (prebuffer) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
211 remove_prebuffer = TRUE; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
212 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
213 return thread_buffer_size - get_thread_buffer_filled() - 1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
214 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
215 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
216 /* do pause operation */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
217 static void alsa_do_pause(gboolean p) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
218 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
219 if (paused == p) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
220 return; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
221 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
222 if (alsa_pcm) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
223 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
224 if (alsa_can_pause) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
225 snd_pcm_pause(alsa_pcm, p); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
226 else if (p) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
227 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
228 snd_pcm_drop(alsa_pcm); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
229 snd_pcm_prepare(alsa_pcm); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
230 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
231 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
232 paused = p; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
233 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
234 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
235 void alsa_pause(short p) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
236 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
237 debug("alsa_pause"); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
238 pause_request = p; |
61 | 239 } |
240 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
241 /* close PCM and release associated resources */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
242 static void alsa_close_pcm(void) |
61 | 243 { |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
244 if (alsa_pcm) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
245 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
246 int err; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
247 snd_pcm_drop(alsa_pcm); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
248 if ((err = snd_pcm_close(alsa_pcm)) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
249 g_warning("alsa_pcm_close() failed: %s", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
250 snd_strerror(-err)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
251 alsa_pcm = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
252 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
253 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
254 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
255 void alsa_close(void) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
256 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
257 if (!going) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
258 return; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
259 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
260 debug("Closing device"); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
261 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
262 going = 0; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
263 |
215 | 264 g_thread_join(audio_thread); |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
265 |
1278 | 266 g_mutex_lock(alsa_mutex); /* alsa_loop locks alsa_mutex! */ |
267 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
268 alsa_cleanup_mixer(); |
61 | 269 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
270 xmms_convert_buffers_destroy(convertb); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
271 convertb = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
272 g_free(inputf); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
273 inputf = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
274 g_free(effectf); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
275 effectf = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
276 g_free(outputf); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
277 outputf = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
278 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
279 alsa_save_config(); |
61 | 280 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
281 if (alsa_cfg.debug) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
282 snd_output_close(logs); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
283 debug("Device closed"); |
1275
847d9a218f66
[svn] - use mutex locking to make alsa stay happy with dmix
nenolod
parents:
1150
diff
changeset
|
284 |
847d9a218f66
[svn] - use mutex locking to make alsa stay happy with dmix
nenolod
parents:
1150
diff
changeset
|
285 g_mutex_unlock(alsa_mutex); |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
286 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
287 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
288 /* reopen ALSA PCM */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
289 static int alsa_reopen(struct snd_format *f) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
290 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
291 /* remember the current position */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
292 output_time_offset += (alsa_hw_written * 1000) / outputf->bps; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
293 alsa_hw_written = 0; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
294 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
295 alsa_close_pcm(); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
296 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
297 return alsa_setup(f); |
61 | 298 } |
299 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
300 /* do flush (drop) operation */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
301 static void alsa_do_flush(int time) |
61 | 302 { |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
303 if (alsa_pcm) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
304 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
305 snd_pcm_drop(alsa_pcm); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
306 snd_pcm_prepare(alsa_pcm); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
307 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
308 /* correct the offset */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
309 output_time_offset = time; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
310 alsa_total_written = (guint64) time * inputf->bps / 1000; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
311 rd_index = wr_index = alsa_hw_written = 0; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
312 } |
61 | 313 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
314 void alsa_flush(int time) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
315 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
316 flush_request = time; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
317 while (flush_request != -1) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
318 xmms_usleep(10000); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
319 } |
61 | 320 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
321 static void parse_mixer_name(char *str, char **name, int *index) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
322 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
323 char *end; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
324 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
325 while (isspace(*str)) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
326 str++; |
61 | 327 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
328 if ((end = strchr(str, ',')) != NULL) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
329 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
330 *name = g_strndup(str, end - str); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
331 end++; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
332 *index = atoi(end); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
333 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
334 else |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
335 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
336 *name = g_strdup(str); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
337 *index = 0; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
338 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
339 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
340 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
341 int alsa_get_mixer(snd_mixer_t **mixer, int card) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
342 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
343 char *dev; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
344 int err; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
345 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
346 debug("alsa_get_mixer"); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
347 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
348 dev = g_strdup_printf("hw:%i", card); |
61 | 349 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
350 if ((err = snd_mixer_open(mixer, 0)) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
351 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
352 g_warning("alsa_get_mixer(): Failed to open empty mixer: %s", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
353 snd_strerror(-err)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
354 mixer = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
355 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
356 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
357 if ((err = snd_mixer_attach(*mixer, dev)) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
358 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
359 g_warning("alsa_get_mixer(): Attaching to mixer %s failed: %s", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
360 dev, snd_strerror(-err)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
361 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
362 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
363 if ((err = snd_mixer_selem_register(*mixer, NULL, NULL)) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
364 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
365 g_warning("alsa_get_mixer(): Failed to register mixer: %s", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
366 snd_strerror(-err)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
367 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
368 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
369 if ((err = snd_mixer_load(*mixer)) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
370 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
371 g_warning("alsa_get_mixer(): Failed to load mixer: %s", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
372 snd_strerror(-err)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
373 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
374 } |
61 | 375 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
376 g_free(dev); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
377 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
378 return (*mixer != NULL); |
61 | 379 } |
380 | |
381 | |
382 static snd_mixer_elem_t* alsa_get_mixer_elem(snd_mixer_t *mixer, char *name, int index) | |
383 { | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
384 snd_mixer_selem_id_t *selem_id; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
385 snd_mixer_elem_t* elem; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
386 snd_mixer_selem_id_alloca(&selem_id); |
61 | 387 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
388 if (index != -1) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
389 snd_mixer_selem_id_set_index(selem_id, index); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
390 if (name != NULL) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
391 snd_mixer_selem_id_set_name(selem_id, name); |
61 | 392 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
393 elem = snd_mixer_find_selem(mixer, selem_id); |
61 | 394 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
395 return elem; |
61 | 396 } |
397 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
398 static int alsa_setup_mixer(void) |
61 | 399 { |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
400 char *name; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
401 long int a, b; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
402 long alsa_min_vol, alsa_max_vol; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
403 int err, index; |
61 | 404 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
405 debug("alsa_setup_mixer"); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
406 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
407 if ((err = alsa_get_mixer(&mixer, alsa_cfg.mixer_card)) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
408 return err; |
61 | 409 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
410 parse_mixer_name(alsa_cfg.mixer_device, &name, &index); |
61 | 411 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
412 pcm_element = alsa_get_mixer_elem(mixer, name, index); |
61 | 413 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
414 g_free(name); |
61 | 415 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
416 if (!pcm_element) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
417 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
418 g_warning("alsa_setup_mixer(): Failed to find mixer element: %s", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
419 alsa_cfg.mixer_device); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
420 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
421 } |
61 | 422 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
423 /* |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
424 * Work around a bug in alsa-lib up to 1.0.0rc2 where the |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
425 * new range don't take effect until the volume is changed. |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
426 * This hack should be removed once we depend on Alsa 1.0.0. |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
427 */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
428 snd_mixer_selem_get_playback_volume(pcm_element, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
429 SND_MIXER_SCHN_FRONT_LEFT, &a); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
430 snd_mixer_selem_get_playback_volume(pcm_element, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
431 SND_MIXER_SCHN_FRONT_RIGHT, &b); |
61 | 432 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
433 snd_mixer_selem_get_playback_volume_range(pcm_element, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
434 &alsa_min_vol, &alsa_max_vol); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
435 snd_mixer_selem_set_playback_volume_range(pcm_element, 0, 100); |
61 | 436 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
437 if (alsa_max_vol == 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
438 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
439 pcm_element = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
440 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
441 } |
61 | 442 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
443 if (!alsa_cfg.soft_volume) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
444 alsa_set_volume(a * 100 / alsa_max_vol, b * 100 / alsa_max_vol); |
61 | 445 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
446 debug("alsa_setup_mixer: end"); |
61 | 447 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
448 return 0; |
61 | 449 } |
450 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
451 static int alsa_mixer_timeout(void *data) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
452 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
453 if (mixer) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
454 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
455 snd_mixer_close(mixer); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
456 mixer = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
457 pcm_element = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
458 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
459 mixer_timeout = 0; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
460 mixer_start = TRUE; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
461 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
462 g_message("alsa mixer timed out"); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
463 return FALSE; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
464 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
465 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
466 static void alsa_cleanup_mixer(void) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
467 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
468 pcm_element = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
469 if (mixer) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
470 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
471 snd_mixer_close(mixer); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
472 mixer = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
473 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
474 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
475 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
476 void alsa_get_volume(int *l, int *r) |
61 | 477 { |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
478 long ll = *l, lr = *r; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
479 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
480 if (mixer_start) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
481 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
482 alsa_setup_mixer(); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
483 mixer_start = FALSE; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
484 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
485 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
486 if (alsa_cfg.soft_volume) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
487 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
488 *l = alsa_cfg.vol.left; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
489 *r = alsa_cfg.vol.right; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
490 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
491 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
492 if (!pcm_element) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
493 return; |
61 | 494 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
495 snd_mixer_handle_events(mixer); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
496 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
497 if (!alsa_cfg.soft_volume) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
498 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
499 snd_mixer_selem_get_playback_volume(pcm_element, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
500 SND_MIXER_SCHN_FRONT_LEFT, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
501 &ll); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
502 snd_mixer_selem_get_playback_volume(pcm_element, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
503 SND_MIXER_SCHN_FRONT_RIGHT, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
504 &lr); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
505 *l = ll; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
506 *r = lr; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
507 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
508 if (mixer_timeout) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
509 gtk_timeout_remove(mixer_timeout); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
510 mixer_timeout = gtk_timeout_add(5000, alsa_mixer_timeout, NULL); |
61 | 511 } |
512 | |
513 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
514 void alsa_set_volume(int l, int r) |
61 | 515 { |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
516 if (alsa_cfg.soft_volume) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
517 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
518 alsa_cfg.vol.left = l; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
519 alsa_cfg.vol.right = r; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
520 return; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
521 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
522 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
523 if (!pcm_element) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
524 return; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
525 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
526 snd_mixer_selem_set_playback_volume(pcm_element, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
527 SND_MIXER_SCHN_FRONT_LEFT, l); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
528 snd_mixer_selem_set_playback_volume(pcm_element, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
529 SND_MIXER_SCHN_FRONT_RIGHT, r); |
61 | 530 } |
531 | |
532 | |
533 /* | |
534 * audio stuff | |
535 */ | |
536 | |
537 /* return the size of audio data filled in the audio thread buffer */ | |
538 static int get_thread_buffer_filled(void) | |
539 { | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
540 if (wr_index >= rd_index) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
541 return wr_index - rd_index; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
542 return thread_buffer_size - (rd_index - wr_index); |
61 | 543 } |
544 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
545 int alsa_get_output_time(void) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
546 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
547 snd_pcm_sframes_t delay; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
548 guint64 bytes = alsa_hw_written; |
61 | 549 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
550 if (!going || alsa_pcm == NULL) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
551 return 0; |
61 | 552 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
553 if (!snd_pcm_delay(alsa_pcm, &delay)) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
554 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
555 unsigned int d = snd_pcm_frames_to_bytes(alsa_pcm, delay); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
556 if (bytes < d) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
557 bytes = 0; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
558 else |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
559 bytes -= d; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
560 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
561 return output_time_offset + (bytes * 1000) / outputf->bps; |
61 | 562 } |
563 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
564 int alsa_get_written_time(void) |
61 | 565 { |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
566 if (!going) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
567 return 0; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
568 return (alsa_total_written * 1000) / inputf->bps; |
61 | 569 } |
570 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
571 #define STEREO_ADJUST(type, type2, endian) \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
572 do { \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
573 type *ptr = data; \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
574 for (i = 0; i < length; i += 4) \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
575 { \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
576 *ptr = type2##_TO_##endian(type2##_FROM_## endian(*ptr) * \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
577 alsa_cfg.vol.left / 100); \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
578 ptr++; \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
579 *ptr = type2##_TO_##endian(type2##_FROM_##endian(*ptr) * \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
580 alsa_cfg.vol.right / 100); \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
581 ptr++; \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
582 } \ |
61 | 583 } while (0) |
584 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
585 #define MONO_ADJUST(type, type2, endian) \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
586 do { \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
587 type *ptr = data; \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
588 for (i = 0; i < length; i += 2) \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
589 { \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
590 *ptr = type2##_TO_##endian(type2##_FROM_## endian(*ptr) * \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
591 vol / 100); \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
592 ptr++; \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
593 } \ |
61 | 594 } while (0) |
595 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
596 #define VOLUME_ADJUST(type, type2, endian) \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
597 do { \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
598 if (channels == 2) \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
599 STEREO_ADJUST(type, type2, endian); \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
600 else \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
601 MONO_ADJUST(type, type2, endian); \ |
61 | 602 } while (0) |
603 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
604 #define STEREO_ADJUST8(type) \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
605 do { \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
606 type *ptr = data; \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
607 for (i = 0; i < length; i += 2) \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
608 { \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
609 *ptr = *ptr * alsa_cfg.vol.left / 100; \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
610 ptr++; \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
611 *ptr = *ptr * alsa_cfg.vol.right / 100; \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
612 ptr++; \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
613 } \ |
61 | 614 } while (0) |
615 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
616 #define MONO_ADJUST8(type) \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
617 do { \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
618 type *ptr = data; \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
619 for (i = 0; i < length; i++) \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
620 { \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
621 *ptr = *ptr * vol / 100; \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
622 ptr++; \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
623 } \ |
61 | 624 } while (0) |
625 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
626 #define VOLUME_ADJUST8(type) \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
627 do { \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
628 if (channels == 2) \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
629 STEREO_ADJUST8(type); \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
630 else \ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
631 MONO_ADJUST8(type); \ |
61 | 632 } while (0) |
633 | |
634 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
635 static void volume_adjust(void* data, int length, AFormat fmt, int channels) |
61 | 636 { |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
637 int i, vol; |
61 | 638 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
639 if ((alsa_cfg.vol.left == 100 && alsa_cfg.vol.right == 100) || |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
640 (channels == 1 && |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
641 (alsa_cfg.vol.left == 100 || alsa_cfg.vol.right == 100))) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
642 return; |
61 | 643 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
644 vol = MAX(alsa_cfg.vol.left, alsa_cfg.vol.right); |
61 | 645 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
646 switch (fmt) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
647 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
648 case FMT_S16_LE: |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
649 VOLUME_ADJUST(gint16, GINT16, LE); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
650 break; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
651 case FMT_U16_LE: |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
652 VOLUME_ADJUST(guint16, GUINT16, LE); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
653 break; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
654 case FMT_S16_BE: |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
655 VOLUME_ADJUST(gint16, GINT16, BE); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
656 break; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
657 case FMT_U16_BE: |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
658 VOLUME_ADJUST(guint16, GUINT16, BE); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
659 break; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
660 case FMT_S8: |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
661 VOLUME_ADJUST8(gint8); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
662 break; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
663 case FMT_U8: |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
664 VOLUME_ADJUST8(guint8); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
665 break; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
666 default: |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
667 g_warning("volue_adjust(): unhandled format: %d", fmt); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
668 break; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
669 } |
61 | 670 } |
671 | |
672 | |
673 /* transfer data to audio h/w; length is given in bytes | |
674 * | |
675 * data can be modified via effect plugin, rate conversion or | |
676 * software volume before passed to audio h/w | |
677 */ | |
678 static void alsa_do_write(gpointer data, int length) | |
679 { | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
680 EffectPlugin *ep = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
681 int new_freq; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
682 int new_chn; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
683 AFormat f; |
61 | 684 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
685 if (paused) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
686 return; |
61 | 687 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
688 new_freq = inputf->rate; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
689 new_chn = inputf->channels; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
690 f = inputf->xmms_format; |
61 | 691 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
692 if (effects_enabled() && (ep = get_current_effect_plugin()) && |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
693 ep->query_format) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
694 ep->query_format(&f, &new_freq, &new_chn); |
61 | 695 |
701
d539e5c5f730
[svn] Fixes of the remaining GCC 4.1 warnings from external contributor Diego "Flameeyes" Petteno (Gentoo).
chainsaw
parents:
517
diff
changeset
|
696 if (f != effectf->xmms_format || (unsigned int)new_freq != effectf->rate || |
d539e5c5f730
[svn] Fixes of the remaining GCC 4.1 warnings from external contributor Diego "Flameeyes" Petteno (Gentoo).
chainsaw
parents:
517
diff
changeset
|
697 (unsigned int)new_chn != effectf->channels) |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
698 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
699 debug("Changing audio format for effect plugin"); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
700 g_free(effectf); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
701 effectf = snd_format_from_xmms(f, new_freq, new_chn); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
702 if (alsa_reopen(effectf) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
703 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
704 /* fatal error... */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
705 alsa_close(); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
706 return; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
707 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
708 } |
61 | 709 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
710 if (ep) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
711 length = ep->mod_samples(&data, length, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
712 inputf->xmms_format, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
713 inputf->rate, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
714 inputf->channels); |
61 | 715 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
716 if (alsa_convert_func != NULL) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
717 length = alsa_convert_func(convertb, &data, length); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
718 if (alsa_stereo_convert_func != NULL) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
719 length = alsa_stereo_convert_func(convertb, &data, length); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
720 if (alsa_frequency_convert_func != NULL) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
721 length = alsa_frequency_convert_func(convertb, &data, length, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
722 effectf->rate, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
723 outputf->rate); |
61 | 724 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
725 if (alsa_cfg.soft_volume) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
726 volume_adjust(data, length, outputf->xmms_format, outputf->channels); |
61 | 727 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
728 alsa_write_audio(data, length); |
61 | 729 } |
730 | |
731 /* write callback */ | |
732 void alsa_write(gpointer data, int length) | |
733 { | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
734 int cnt; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
735 char *src = (char *)data; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
736 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
737 remove_prebuffer = FALSE; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
738 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
739 alsa_total_written += length; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
740 while (length > 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
741 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
742 int wr; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
743 cnt = MIN(length, thread_buffer_size - wr_index); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
744 memcpy(thread_buffer + wr_index, src, cnt); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
745 wr = (wr_index + cnt) % thread_buffer_size; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
746 wr_index = wr; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
747 length -= cnt; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
748 src += cnt; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
749 } |
61 | 750 } |
751 | |
752 /* transfer data to audio h/w via normal write */ | |
753 static void alsa_write_audio(char *data, int length) | |
754 { | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
755 snd_pcm_sframes_t written_frames; |
61 | 756 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
757 while (length > 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
758 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
759 int frames = snd_pcm_bytes_to_frames(alsa_pcm, length); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
760 written_frames = snd_pcm_writei(alsa_pcm, data, frames); |
61 | 761 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
762 if (written_frames > 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
763 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
764 int written = snd_pcm_frames_to_bytes(alsa_pcm, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
765 written_frames); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
766 length -= written; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
767 data += written; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
768 alsa_hw_written += written; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
769 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
770 else |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
771 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
772 int err = alsa_handle_error((int)written_frames); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
773 if (err < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
774 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
775 g_warning("alsa_write_audio(): write error: %s", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
776 snd_strerror(-err)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
777 break; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
778 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
779 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
780 } |
61 | 781 } |
782 | |
783 /* transfer audio data from thread buffer to h/w */ | |
784 static void alsa_write_out_thread_data(void) | |
785 { | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
786 gint length, cnt, avail; |
61 | 787 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
788 length = MIN(hw_period_size_in, get_thread_buffer_filled()); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
789 avail = snd_pcm_frames_to_bytes(alsa_pcm, alsa_get_avail()); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
790 length = MIN(length, avail); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
791 while (length > 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
792 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
793 int rd; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
794 cnt = MIN(length, thread_buffer_size - rd_index); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
795 alsa_do_write(thread_buffer + rd_index, cnt); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
796 rd = (rd_index + cnt) % thread_buffer_size; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
797 rd_index = rd; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
798 length -= cnt; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
799 } |
61 | 800 } |
801 | |
802 /* audio thread loop */ | |
803 /* FIXME: proper lock? */ | |
804 static void *alsa_loop(void *arg) | |
805 { | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
806 int npfds = snd_pcm_poll_descriptors_count(alsa_pcm); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
807 struct pollfd *pfds; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
808 unsigned short *revents; |
61 | 809 |
1275
847d9a218f66
[svn] - use mutex locking to make alsa stay happy with dmix
nenolod
parents:
1150
diff
changeset
|
810 g_mutex_lock(alsa_mutex); |
847d9a218f66
[svn] - use mutex locking to make alsa stay happy with dmix
nenolod
parents:
1150
diff
changeset
|
811 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
812 if (npfds <= 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
813 goto _error; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
814 pfds = alloca(sizeof(*pfds) * npfds); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
815 revents = alloca(sizeof(*revents) * npfds); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
816 while (going && alsa_pcm) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
817 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
818 if (get_thread_buffer_filled() > prebuffer_size) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
819 prebuffer = FALSE; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
820 if (!paused && !prebuffer && |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
821 get_thread_buffer_filled() > hw_period_size_in) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
822 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
823 snd_pcm_poll_descriptors(alsa_pcm, pfds, npfds); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
824 if (poll(pfds, npfds, 10) > 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
825 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
826 /* |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
827 * need to check revents. poll() with |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
828 * dmix returns a postive value even |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
829 * if no data is available |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
830 */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
831 int i; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
832 snd_pcm_poll_descriptors_revents(alsa_pcm, pfds, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
833 npfds, revents); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
834 for (i = 0; i < npfds; i++) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
835 if (revents[i] & POLLOUT) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
836 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
837 alsa_write_out_thread_data(); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
838 break; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
839 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
840 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
841 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
842 else |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
843 xmms_usleep(10000); |
61 | 844 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
845 if (pause_request != paused) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
846 alsa_do_pause(pause_request); |
61 | 847 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
848 if (flush_request != -1) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
849 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
850 alsa_do_flush(flush_request); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
851 flush_request = -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
852 prebuffer = TRUE; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
853 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
854 } |
61 | 855 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
856 _error: |
1275
847d9a218f66
[svn] - use mutex locking to make alsa stay happy with dmix
nenolod
parents:
1150
diff
changeset
|
857 g_mutex_unlock(alsa_mutex); |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
858 alsa_close_pcm(); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
859 g_free(thread_buffer); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
860 thread_buffer = NULL; |
215 | 861 g_thread_exit(NULL); |
246
acae8fa925c3
[svn] Add casts to callbacks in signal handlers to avoid warning. GCC would like a return statement too.
chainsaw
parents:
215
diff
changeset
|
862 return(NULL); |
61 | 863 } |
864 | |
865 /* open callback */ | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
866 int alsa_open(AFormat fmt, int rate, int nch) |
61 | 867 { |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
868 debug("Opening device"); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
869 inputf = snd_format_from_xmms(fmt, rate, nch); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
870 effectf = snd_format_from_xmms(fmt, rate, nch); |
61 | 871 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
872 if (alsa_cfg.debug) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
873 snd_output_stdio_attach(&logs, stdout, 0); |
61 | 874 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
875 if (alsa_setup(inputf) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
876 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
877 alsa_close(); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
878 return 0; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
879 } |
61 | 880 |
1275
847d9a218f66
[svn] - use mutex locking to make alsa stay happy with dmix
nenolod
parents:
1150
diff
changeset
|
881 g_mutex_lock(alsa_mutex); |
847d9a218f66
[svn] - use mutex locking to make alsa stay happy with dmix
nenolod
parents:
1150
diff
changeset
|
882 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
883 if (!mixer) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
884 alsa_setup_mixer(); |
61 | 885 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
886 convertb = xmms_convert_buffers_new(); |
61 | 887 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
888 output_time_offset = 0; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
889 alsa_total_written = alsa_hw_written = 0; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
890 going = TRUE; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
891 paused = FALSE; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
892 prebuffer = TRUE; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
893 remove_prebuffer = FALSE; |
61 | 894 |
1150 | 895 thread_buffer_size = (guint64)cfg.output_buffer_size * inputf->bps / 1000; |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
896 if (thread_buffer_size < hw_buffer_size) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
897 thread_buffer_size = hw_buffer_size * 2; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
898 if (thread_buffer_size < 8192) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
899 thread_buffer_size = 8192; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
900 prebuffer_size = thread_buffer_size / 2; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
901 if (prebuffer_size < 8192) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
902 prebuffer_size = 8192; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
903 thread_buffer_size += hw_buffer_size; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
904 thread_buffer_size -= thread_buffer_size % hw_period_size; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
905 thread_buffer = g_malloc0(thread_buffer_size); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
906 wr_index = rd_index = 0; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
907 pause_request = FALSE; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
908 flush_request = -1; |
1275
847d9a218f66
[svn] - use mutex locking to make alsa stay happy with dmix
nenolod
parents:
1150
diff
changeset
|
909 |
847d9a218f66
[svn] - use mutex locking to make alsa stay happy with dmix
nenolod
parents:
1150
diff
changeset
|
910 g_mutex_unlock(alsa_mutex); |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
911 |
215 | 912 audio_thread = g_thread_create((GThreadFunc)alsa_loop, NULL, TRUE, NULL); |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
913 return 1; |
61 | 914 } |
915 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
916 static struct snd_format * snd_format_from_xmms(AFormat fmt, int rate, int channels) |
61 | 917 { |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
918 struct snd_format *f = g_malloc(sizeof(struct snd_format)); |
701
d539e5c5f730
[svn] Fixes of the remaining GCC 4.1 warnings from external contributor Diego "Flameeyes" Petteno (Gentoo).
chainsaw
parents:
517
diff
changeset
|
919 size_t i; |
61 | 920 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
921 f->xmms_format = fmt; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
922 f->format = SND_PCM_FORMAT_UNKNOWN; |
61 | 923 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
924 for (i = 0; i < sizeof(format_table) / sizeof(format_table[0]); i++) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
925 if (format_table[i].xmms == fmt) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
926 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
927 f->format = format_table[i].alsa; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
928 break; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
929 } |
61 | 930 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
931 /* Get rid of _NE */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
932 for (i = 0; i < sizeof(format_table) / sizeof(format_table[0]); i++) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
933 if (format_table[i].alsa == f->format) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
934 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
935 f->xmms_format = format_table[i].xmms; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
936 break; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
937 } |
61 | 938 |
939 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
940 f->rate = rate; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
941 f->channels = channels; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
942 f->sample_bits = snd_pcm_format_physical_width(f->format); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
943 f->bps = (rate * f->sample_bits * channels) >> 3; |
61 | 944 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
945 return f; |
61 | 946 } |
947 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
948 static int format_from_alsa(snd_pcm_format_t fmt) |
61 | 949 { |
701
d539e5c5f730
[svn] Fixes of the remaining GCC 4.1 warnings from external contributor Diego "Flameeyes" Petteno (Gentoo).
chainsaw
parents:
517
diff
changeset
|
950 size_t i; |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
951 for (i = 0; i < sizeof(format_table) / sizeof(format_table[0]); i++) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
952 if (format_table[i].alsa == fmt) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
953 return format_table[i].xmms; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
954 g_warning("Unsupported format: %s", snd_pcm_format_name(fmt)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
955 return -1; |
61 | 956 } |
957 | |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
958 static int alsa_setup(struct snd_format *f) |
61 | 959 { |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
960 int err; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
961 snd_pcm_hw_params_t *hwparams; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
962 snd_pcm_sw_params_t *swparams; |
400 | 963 uint alsa_buffer_time; |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
964 unsigned int alsa_period_time; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
965 snd_pcm_uframes_t alsa_buffer_size, alsa_period_size; |
61 | 966 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
967 debug("alsa_setup"); |
61 | 968 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
969 alsa_convert_func = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
970 alsa_stereo_convert_func = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
971 alsa_frequency_convert_func = NULL; |
61 | 972 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
973 g_free(outputf); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
974 outputf = snd_format_from_xmms(f->xmms_format, f->rate, f->channels); |
61 | 975 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
976 debug("Opening device: %s", alsa_cfg.pcm_device); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
977 /* FIXME: Can snd_pcm_open() return EAGAIN? */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
978 if ((err = snd_pcm_open(&alsa_pcm, alsa_cfg.pcm_device, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
979 SND_PCM_STREAM_PLAYBACK, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
980 SND_PCM_NONBLOCK)) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
981 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
982 g_warning("alsa_setup(): Failed to open pcm device (%s): %s", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
983 alsa_cfg.pcm_device, snd_strerror(-err)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
984 alsa_pcm = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
985 g_free(outputf); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
986 outputf = NULL; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
987 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
988 } |
61 | 989 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
990 /* doesn't care about non-blocking */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
991 /* snd_pcm_nonblock(alsa_pcm, 0); */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
992 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
993 if (alsa_cfg.debug) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
994 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
995 snd_pcm_info_t *info; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
996 int alsa_card, alsa_device, alsa_subdevice; |
61 | 997 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
998 snd_pcm_info_alloca(&info); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
999 snd_pcm_info(alsa_pcm, info); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1000 alsa_card = snd_pcm_info_get_card(info); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1001 alsa_device = snd_pcm_info_get_device(info); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1002 alsa_subdevice = snd_pcm_info_get_subdevice(info); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1003 printf("Card %i, Device %i, Subdevice %i\n", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1004 alsa_card, alsa_device, alsa_subdevice); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1005 } |
61 | 1006 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1007 snd_pcm_hw_params_alloca(&hwparams); |
61 | 1008 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1009 if ((err = snd_pcm_hw_params_any(alsa_pcm, hwparams)) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1010 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1011 g_warning("alsa_setup(): No configuration available for " |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1012 "playback: %s", snd_strerror(-err)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1013 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1014 } |
61 | 1015 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1016 if ((err = snd_pcm_hw_params_set_access(alsa_pcm, hwparams, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1017 SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1018 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1019 g_warning("alsa_setup(): Cannot set direct write mode: %s", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1020 snd_strerror(-err)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1021 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1022 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1023 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1024 if ((err = snd_pcm_hw_params_set_format(alsa_pcm, hwparams, outputf->format)) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1025 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1026 /* |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1027 * Try if one of these format work (one of them should work |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1028 * on almost all soundcards) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1029 */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1030 snd_pcm_format_t formats[] = {SND_PCM_FORMAT_S16_LE, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1031 SND_PCM_FORMAT_S16_BE, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1032 SND_PCM_FORMAT_U8}; |
701
d539e5c5f730
[svn] Fixes of the remaining GCC 4.1 warnings from external contributor Diego "Flameeyes" Petteno (Gentoo).
chainsaw
parents:
517
diff
changeset
|
1033 size_t i; |
61 | 1034 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1035 for (i = 0; i < sizeof(formats) / sizeof(formats[0]); i++) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1036 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1037 if (snd_pcm_hw_params_set_format(alsa_pcm, hwparams, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1038 formats[i]) == 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1039 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1040 outputf->format = formats[i]; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1041 break; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1042 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1043 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1044 if (outputf->format != f->format) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1045 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1046 outputf->xmms_format = |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1047 format_from_alsa(outputf->format); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1048 debug("Converting format from %d to %d", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1049 f->xmms_format, outputf->xmms_format); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1050 alsa_convert_func = |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1051 xmms_convert_get_func(outputf->xmms_format, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1052 f->xmms_format); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1053 if (alsa_convert_func == NULL) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1054 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1055 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1056 else |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1057 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1058 g_warning("alsa_setup(): Sample format not " |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1059 "available for playback: %s", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1060 snd_strerror(-err)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1061 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1062 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1063 } |
61 | 1064 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1065 snd_pcm_hw_params_set_channels_near(alsa_pcm, hwparams, &outputf->channels); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1066 if (outputf->channels != f->channels) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1067 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1068 debug("Converting channels from %d to %d", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1069 f->channels, outputf->channels); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1070 alsa_stereo_convert_func = |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1071 xmms_convert_get_channel_func(outputf->xmms_format, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1072 outputf->channels, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1073 f->channels); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1074 if (alsa_stereo_convert_func == NULL) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1075 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1076 } |
61 | 1077 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1078 snd_pcm_hw_params_set_rate_near(alsa_pcm, hwparams, &outputf->rate, 0); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1079 if (outputf->rate == 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1080 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1081 g_warning("alsa_setup(): No usable samplerate available."); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1082 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1083 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1084 if (outputf->rate != f->rate) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1085 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1086 debug("Converting samplerate from %d to %d", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1087 f->rate, outputf->rate); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1088 alsa_frequency_convert_func = |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1089 xmms_convert_get_frequency_func(outputf->xmms_format, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1090 outputf->channels); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1091 if (alsa_frequency_convert_func == NULL) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1092 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1093 } |
61 | 1094 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1095 outputf->sample_bits = snd_pcm_format_physical_width(outputf->format); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1096 outputf->bps = (outputf->rate * outputf->sample_bits * outputf->channels) >> 3; |
61 | 1097 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1098 alsa_buffer_time = alsa_cfg.buffer_time * 1000; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1099 if ((err = snd_pcm_hw_params_set_buffer_time_near(alsa_pcm, hwparams, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1100 &alsa_buffer_time, 0)) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1101 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1102 g_warning("alsa_setup(): Set buffer time failed: %s.", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1103 snd_strerror(-err)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1104 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1105 } |
61 | 1106 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1107 alsa_period_time = alsa_cfg.period_time * 1000; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1108 if ((err = snd_pcm_hw_params_set_period_time_near(alsa_pcm, hwparams, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1109 &alsa_period_time, 0)) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1110 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1111 g_warning("alsa_setup(): Set period time failed: %s.", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1112 snd_strerror(-err)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1113 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1114 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1115 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1116 if (snd_pcm_hw_params(alsa_pcm, hwparams) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1117 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1118 if (alsa_cfg.debug) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1119 snd_pcm_hw_params_dump(hwparams, logs); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1120 g_warning("alsa_setup(): Unable to install hw params"); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1121 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1122 } |
61 | 1123 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1124 if ((err = snd_pcm_hw_params_get_buffer_size(hwparams, &alsa_buffer_size)) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1125 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1126 g_warning("alsa_setup(): snd_pcm_hw_params_get_buffer_size() " |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1127 "failed: %s", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1128 snd_strerror(-err)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1129 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1130 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1131 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1132 if ((err = snd_pcm_hw_params_get_period_size(hwparams, &alsa_period_size, 0)) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1133 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1134 g_warning("alsa_setup(): snd_pcm_hw_params_get_period_size() " |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1135 "failed: %s", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1136 snd_strerror(-err)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1137 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1138 } |
61 | 1139 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1140 alsa_can_pause = snd_pcm_hw_params_can_pause(hwparams); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1141 |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1142 snd_pcm_sw_params_alloca(&swparams); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1143 snd_pcm_sw_params_current(alsa_pcm, swparams); |
61 | 1144 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1145 /* This has effect for non-mmap only */ |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1146 if ((err = snd_pcm_sw_params_set_start_threshold(alsa_pcm, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1147 swparams, alsa_buffer_size - alsa_period_size) < 0)) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1148 g_warning("alsa_setup(): setting start " |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1149 "threshold failed: %s", snd_strerror(-err)); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1150 if (snd_pcm_sw_params(alsa_pcm, swparams) < 0) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1151 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1152 g_warning("alsa_setup(): Unable to install sw params"); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1153 return -1; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1154 } |
61 | 1155 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1156 if (alsa_cfg.debug) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1157 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1158 snd_pcm_sw_params_dump(swparams, logs); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1159 snd_pcm_dump(alsa_pcm, logs); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1160 } |
61 | 1161 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1162 hw_buffer_size = snd_pcm_frames_to_bytes(alsa_pcm, alsa_buffer_size); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1163 hw_period_size = snd_pcm_frames_to_bytes(alsa_pcm, alsa_period_size); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1164 if (inputf->bps != outputf->bps) |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1165 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1166 int align = (inputf->sample_bits * inputf->channels) / 8; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1167 hw_buffer_size_in = ((guint64)hw_buffer_size * inputf->bps + |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1168 outputf->bps/2) / outputf->bps; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1169 hw_period_size_in = ((guint64)hw_period_size * inputf->bps + |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1170 outputf->bps/2) / outputf->bps; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1171 hw_buffer_size_in -= hw_buffer_size_in % align; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1172 hw_period_size_in -= hw_period_size_in % align; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1173 } |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1174 else |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1175 { |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1176 hw_buffer_size_in = hw_buffer_size; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1177 hw_period_size_in = hw_period_size; |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1178 } |
61 | 1179 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1180 debug("Device setup: buffer time: %i, size: %i.", alsa_buffer_time, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1181 hw_buffer_size); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1182 debug("Device setup: period time: %i, size: %i.", alsa_period_time, |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1183 hw_period_size); |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1184 debug("bits per sample: %i; frame size: %i; Bps: %i", |
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1185 snd_pcm_format_physical_width(outputf->format), |
249
a4566101cab4
[svn] Add two missing casts and update the player buffer description from XMMS to Audacious.
chainsaw
parents:
246
diff
changeset
|
1186 (int)snd_pcm_frames_to_bytes(alsa_pcm, 1), outputf->bps); |
61 | 1187 |
211
0b48662886e9
[svn] Sync ALSA plugin with enhancements/patches from Fatal (XMMS cvs)
nenolod
parents:
61
diff
changeset
|
1188 return 0; |
61 | 1189 } |
517
55dc40ff1aff
[svn] Add tell_audio(AFormat *, gint *, gint *), for retrieving audio
nenolod
parents:
400
diff
changeset
|
1190 |
55dc40ff1aff
[svn] Add tell_audio(AFormat *, gint *, gint *), for retrieving audio
nenolod
parents:
400
diff
changeset
|
1191 void alsa_tell(AFormat * fmt, gint * rate, gint * nch) |
55dc40ff1aff
[svn] Add tell_audio(AFormat *, gint *, gint *), for retrieving audio
nenolod
parents:
400
diff
changeset
|
1192 { |
55dc40ff1aff
[svn] Add tell_audio(AFormat *, gint *, gint *), for retrieving audio
nenolod
parents:
400
diff
changeset
|
1193 (*fmt) = inputf->xmms_format; |
55dc40ff1aff
[svn] Add tell_audio(AFormat *, gint *, gint *), for retrieving audio
nenolod
parents:
400
diff
changeset
|
1194 (*rate) = inputf->rate; |
55dc40ff1aff
[svn] Add tell_audio(AFormat *, gint *, gint *), for retrieving audio
nenolod
parents:
400
diff
changeset
|
1195 (*nch) = inputf->channels; |
55dc40ff1aff
[svn] Add tell_audio(AFormat *, gint *, gint *), for retrieving audio
nenolod
parents:
400
diff
changeset
|
1196 } |