annotate Plugins/Output/OSS/audio.c @ 731:9783edaae2b5 trunk

[svn] - revert OSS warning squashing as the patch created more problems than it solved
author nenolod
date Mon, 27 Feb 2006 15:02:04 -0800
parents d539e5c5f730
children 3c2bb116f4db
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
61
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
1 /* BMP - Cross-platform multimedia player
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
2 * Copyright (C) 2003-2004 BMP development team.
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
3 *
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
4 * Based on XMMS:
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
5 * Copyright (C) 1998-2003 XMMS development team.
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
6 *
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
7 * This program is free software; you can redistribute it and/or modify
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
8 * it under the terms of the GNU General Public License as published by
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
9 * the Free Software Foundation; either version 2 of the License, or
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
10 * (at your option) any later version.
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
11 *
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
12 * This program is distributed in the hope that it will be useful,
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
15 * GNU General Public License for more details.
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
16 *
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
17 * You should have received a copy of the GNU General Public License
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
18 * along with this program; if not, write to the Free Software
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
20 */
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
21
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
22 #include <glib.h>
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
23 #include <libaudacious/util.h>
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
24 #include <string.h>
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
25
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
26 #include <unistd.h>
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
27 #include <fcntl.h>
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
28 #include <errno.h>
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
29 #include <sys/ioctl.h>
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
30 #include <sys/time.h>
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
31
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
32 #include "OSS.h"
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
33
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
34
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
35 #define NFRAGS 32
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
36
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
37 static gint fd = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
38 static char *buffer;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
39 static gboolean going, prebuffer, paused, unpause, do_pause, remove_prebuffer;
731
9783edaae2b5 [svn] - revert OSS warning squashing as the patch created more problems than it solved
nenolod
parents: 701
diff changeset
40 static gint device_buffer_used, buffer_size, prebuffer_size, blk_size;
61
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
41 static gint rd_index = 0, wr_index = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
42 static gint output_time_offset = 0;
731
9783edaae2b5 [svn] - revert OSS warning squashing as the patch created more problems than it solved
nenolod
parents: 701
diff changeset
43 static guint64 written = 0, output_bytes = 0;
61
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
44 static gint flush;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
45 static gint fragsize, device_buffer_size;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
46 static gchar *device_name;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
47 static GThread *buffer_thread;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
48 static gboolean realtime, select_works;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
49
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
50 static int (*oss_convert_func) (void **data, int length);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
51 static int (*oss_stereo_convert_func) (void **data, int length, int fmt);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
52
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
53 struct format_info {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
54 union {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
55 AFormat xmms;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
56 int oss;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
57 } format;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
58 int frequency;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
59 int channels;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
60 int bps;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
61 };
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
62
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
63
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
64 /*
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
65 * The format of the data from the input plugin
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
66 * This will never change during a song.
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
67 */
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
68 struct format_info input;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
69
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
70 /*
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
71 * The format we get from the effect plugin.
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
72 * This will be different from input if the effect plugin does
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
73 * some kind of format conversion.
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
74 */
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
75 struct format_info effect;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
76
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
77 /*
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
78 * The format of the data we actually send to the soundcard.
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
79 * This might be different from effect if we need to resample or do
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
80 * some other format conversion.
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
81 */
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
82 struct format_info output;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
83
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
84
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
85 static void
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
86 oss_calc_device_buffer_used(void)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
87 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
88 audio_buf_info buf_info;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
89 if (paused)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
90 device_buffer_used = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
91 else if (!ioctl(fd, SNDCTL_DSP_GETOSPACE, &buf_info))
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
92 device_buffer_used =
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
93 (buf_info.fragstotal * buf_info.fragsize) - buf_info.bytes;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
94 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
95
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
96
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
97 static gint oss_downsample(gpointer ob, guint length, guint speed,
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
98 guint espeed);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
99
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
100 static int
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
101 oss_calc_bitrate(int oss_fmt, int rate, int channels)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
102 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
103 int bitrate = rate * channels;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
104
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
105 if (oss_fmt == AFMT_U16_BE || oss_fmt == AFMT_U16_LE ||
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
106 oss_fmt == AFMT_S16_BE || oss_fmt == AFMT_S16_LE)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
107 bitrate *= 2;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
108
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
109 return bitrate;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
110 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
111
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
112 static int
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
113 oss_get_format(AFormat fmt)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
114 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
115 int format = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
116
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
117 switch (fmt) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
118 case FMT_U8:
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
119 format = AFMT_U8;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
120 break;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
121 case FMT_S8:
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
122 format = AFMT_S8;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
123 break;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
124 case FMT_U16_LE:
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
125 format = AFMT_U16_LE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
126 break;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
127 case FMT_U16_BE:
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
128 format = AFMT_U16_BE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
129 break;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
130 case FMT_U16_NE:
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
131 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
132 format = AFMT_U16_BE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
133 #else
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
134 format = AFMT_U16_LE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
135 #endif
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
136 break;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
137 case FMT_S16_LE:
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
138 format = AFMT_S16_LE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
139 break;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
140 case FMT_S16_BE:
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
141 format = AFMT_S16_BE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
142 break;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
143 case FMT_S16_NE:
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
144 #if (G_BYTE_ORDER == G_BIG_ENDIAN)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
145 format = AFMT_S16_BE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
146 #else
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
147 format = AFMT_S16_LE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
148 #endif
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
149 break;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
150 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
151
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
152 return format;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
153 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
154
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
155 static void
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
156 oss_setup_format(AFormat fmt, int rate, int nch)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
157 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
158 effect.format.xmms = fmt;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
159 effect.frequency = rate;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
160 effect.channels = nch;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
161 effect.bps = oss_calc_bitrate(oss_get_format(fmt), rate, nch);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
162
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
163 output.format.oss = oss_get_format(fmt);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
164 output.frequency = rate;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
165 output.channels = nch;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
166
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
167
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
168 fragsize = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
169 while ((1L << fragsize) < effect.bps / 25)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
170 fragsize++;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
171 fragsize--;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
172
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
173 device_buffer_size = ((1L << fragsize) * (NFRAGS + 1));
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
174
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
175 oss_set_audio_params();
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
176
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
177 output.bps = oss_calc_bitrate(output.format.oss, output.frequency,
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
178 output.channels);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
179 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
180
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
181
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
182 gint
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
183 oss_get_written_time(void)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
184 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
185 if (!going)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
186 return 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
187 return (written * 1000) / effect.bps;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
188 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
189
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
190 gint
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
191 oss_get_output_time(void)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
192 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
193 guint64 bytes;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
194
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
195 if (!fd || !going)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
196 return 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
197
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
198 if (realtime)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
199 oss_calc_device_buffer_used();
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
200 bytes = output_bytes < device_buffer_used ?
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
201 0 : output_bytes - device_buffer_used;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
202
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
203 return output_time_offset + ((bytes * 1000) / output.bps);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
204 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
205
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
206 static int
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
207 oss_used(void)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
208 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
209 if (realtime)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
210 return 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
211 else {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
212 if (wr_index >= rd_index)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
213 return wr_index - rd_index;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
214 return buffer_size - (rd_index - wr_index);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
215 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
216 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
217
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
218 gint
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
219 oss_playing(void)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
220 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
221 if (!going)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
222 return 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
223 if (realtime)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
224 oss_calc_device_buffer_used();
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
225 if (!oss_used() && (device_buffer_used - (3 * blk_size)) <= 0)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
226 return FALSE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
227
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
228 return TRUE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
229 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
230
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
231 gint
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
232 oss_free(void)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
233 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
234 if (!realtime) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
235 if (remove_prebuffer && prebuffer) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
236 prebuffer = FALSE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
237 remove_prebuffer = FALSE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
238 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
239 if (prebuffer)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
240 remove_prebuffer = TRUE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
241
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
242 if (rd_index > wr_index)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
243 return (rd_index - wr_index) - device_buffer_size - 1;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
244 return (buffer_size - (wr_index - rd_index)) - device_buffer_size - 1;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
245 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
246 else if (paused)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
247 return 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
248 else
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
249 return 1000000;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
250 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
251
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
252 static inline ssize_t
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
253 write_all(int fd, const void *buf, size_t count)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
254 {
731
9783edaae2b5 [svn] - revert OSS warning squashing as the patch created more problems than it solved
nenolod
parents: 701
diff changeset
255 ssize_t done = 0;
61
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
256 do {
382
a9c7793de60c [svn] fix audio corruption when doing a short write.
nenolod
parents: 61
diff changeset
257 ssize_t n = write(fd, (gchar *) buf + done, count - done);
61
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
258 if (n == -1) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
259 if (errno == EINTR)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
260 continue;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
261 else
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
262 break;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
263 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
264 done += n;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
265 } while (count > done);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
266
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
267 return done;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
268 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
269
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
270 static void
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
271 oss_write_audio(gpointer data, int length)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
272 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
273
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
274 audio_buf_info abuf_info;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
275 AFormat new_format;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
276 int new_frequency, new_channels;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
277 EffectPlugin *ep;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
278
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
279 new_format = input.format.xmms;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
280 new_frequency = input.frequency;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
281 new_channels = input.channels;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
282
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
283
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
284 ep = get_current_effect_plugin();
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
285 if (effects_enabled() && ep && ep->query_format) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
286 ep->query_format(&new_format, &new_frequency, &new_channels);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
287 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
288
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
289 if (new_format != effect.format.xmms ||
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
290 new_frequency != effect.frequency ||
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
291 new_channels != effect.channels) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
292 output_time_offset += (output_bytes * 1000) / output.bps;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
293 output_bytes = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
294 close(fd);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
295 fd = open(device_name, O_WRONLY);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
296 oss_setup_format(new_format, new_frequency, new_channels);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
297 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
298 if (effects_enabled() && ep && ep->mod_samples)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
299 length = ep->mod_samples(&data, length,
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
300 input.format.xmms,
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
301 input.frequency, input.channels);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
302 if (realtime && !ioctl(fd, SNDCTL_DSP_GETOSPACE, &abuf_info)) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
303 while (abuf_info.bytes < length) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
304 xmms_usleep(10000);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
305 if (ioctl(fd, SNDCTL_DSP_GETOSPACE, &abuf_info))
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
306 break;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
307 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
308 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
309
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
310 if (oss_convert_func != NULL)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
311 length = oss_convert_func(&data, length);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
312
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
313 if (oss_stereo_convert_func != NULL)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
314 length = oss_stereo_convert_func(&data, length, output.format.oss);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
315
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
316 if (effect.frequency == output.frequency)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
317 output_bytes += write_all(fd, data, length);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
318 else
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
319 output_bytes += oss_downsample(data, length,
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
320 effect.frequency, output.frequency);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
321 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
322
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
323 static void
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
324 swap_endian(guint16 * data, int length)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
325 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
326 int i;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
327 for (i = 0; i < length; i += 2, data++)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
328 *data = GUINT16_SWAP_LE_BE(*data);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
329 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
330
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
331 #define NOT_NATIVE_ENDIAN ((IS_BIG_ENDIAN && \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
332 (output.format.oss == AFMT_S16_LE || \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
333 output.format.oss == AFMT_U16_LE)) || \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
334 (!IS_BIG_ENDIAN && \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
335 (output.format.oss == AFMT_S16_BE || \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
336 output.format.oss == AFMT_U16_BE)))
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
337
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
338
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
339 #define RESAMPLE_STEREO(sample_type) \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
340 do { \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
341 const gint shift = sizeof (sample_type); \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
342 gint i, in_samples, out_samples, x, delta; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
343 sample_type *inptr = (sample_type *)ob, *outptr; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
344 guint nlen = (((length >> shift) * espeed) / speed); \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
345 if (nlen == 0) \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
346 break; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
347 nlen <<= shift; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
348 if (NOT_NATIVE_ENDIAN) \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
349 swap_endian(ob, length); \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
350 if(nlen > nbuffer_size) \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
351 { \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
352 nbuffer = g_realloc(nbuffer, nlen); \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
353 nbuffer_size = nlen; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
354 } \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
355 outptr = (sample_type *)nbuffer; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
356 in_samples = length >> shift; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
357 out_samples = nlen >> shift; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
358 delta = (in_samples << 12) / out_samples; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
359 for (x = 0, i = 0; i < out_samples; i++) \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
360 { \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
361 gint x1, frac; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
362 x1 = (x >> 12) << 12; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
363 frac = x - x1; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
364 *outptr++ = \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
365 (sample_type) \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
366 ((inptr[(x1 >> 12) << 1] * \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
367 ((1<<12) - frac) + \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
368 inptr[((x1 >> 12) + 1) << 1] * \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
369 frac) >> 12); \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
370 *outptr++ = \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
371 (sample_type) \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
372 ((inptr[((x1 >> 12) << 1) + 1] * \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
373 ((1<<12) - frac) + \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
374 inptr[(((x1 >> 12) + 1) << 1) + 1] * \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
375 frac) >> 12); \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
376 x += delta; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
377 } \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
378 if (NOT_NATIVE_ENDIAN) \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
379 swap_endian(nbuffer, nlen); \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
380 w = write_all(fd, nbuffer, nlen); \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
381 } while (0)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
382
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
383
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
384 #define RESAMPLE_MONO(sample_type) \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
385 do { \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
386 const gint shift = sizeof (sample_type) - 1; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
387 gint i, x, delta, in_samples, out_samples; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
388 sample_type *inptr = (sample_type *)ob, *outptr; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
389 guint nlen = (((length >> shift) * espeed) / speed); \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
390 if (nlen == 0) \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
391 break; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
392 nlen <<= shift; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
393 if (NOT_NATIVE_ENDIAN) \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
394 swap_endian(ob, length); \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
395 if(nlen > nbuffer_size) \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
396 { \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
397 nbuffer = g_realloc(nbuffer, nlen); \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
398 nbuffer_size = nlen; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
399 } \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
400 outptr = (sample_type *)nbuffer; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
401 in_samples = length >> shift; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
402 out_samples = nlen >> shift; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
403 delta = ((length >> shift) << 12) / out_samples; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
404 for (x = 0, i = 0; i < out_samples; i++) \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
405 { \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
406 gint x1, frac; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
407 x1 = (x >> 12) << 12; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
408 frac = x - x1; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
409 *outptr++ = \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
410 (sample_type) \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
411 ((inptr[x1 >> 12] * ((1<<12) - frac) + \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
412 inptr[(x1 >> 12) + 1] * frac) >> 12); \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
413 x += delta; \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
414 } \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
415 if (NOT_NATIVE_ENDIAN) \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
416 swap_endian(nbuffer, nlen); \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
417 w = write_all(fd, nbuffer, nlen); \
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
418 } while (0)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
419
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
420
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
421 static gint
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
422 oss_downsample(gpointer ob, guint length, guint speed, guint espeed)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
423 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
424 guint w = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
425 static gpointer nbuffer = NULL;
731
9783edaae2b5 [svn] - revert OSS warning squashing as the patch created more problems than it solved
nenolod
parents: 701
diff changeset
426 static gint nbuffer_size = 0;
61
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
427
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
428 switch (output.format.oss) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
429 case AFMT_S16_BE:
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
430 case AFMT_S16_LE:
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
431 if (output.channels == 2)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
432 RESAMPLE_STEREO(gint16);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
433 else
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
434 RESAMPLE_MONO(gint16);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
435 break;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
436 case AFMT_U16_BE:
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
437 case AFMT_U16_LE:
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
438 if (output.channels == 2)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
439 RESAMPLE_STEREO(guint16);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
440 else
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
441 RESAMPLE_MONO(guint16);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
442 break;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
443 case AFMT_S8:
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
444 if (output.channels == 2)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
445 RESAMPLE_STEREO(gint8);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
446 else
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
447 RESAMPLE_MONO(gint8);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
448 break;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
449 case AFMT_U8:
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
450 if (output.channels == 2)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
451 RESAMPLE_STEREO(guint8);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
452 else
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
453 RESAMPLE_MONO(guint8);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
454 break;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
455 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
456 return w;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
457 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
458
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
459 void
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
460 oss_write(gpointer ptr, int length)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
461 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
462 int cnt, off = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
463
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
464 if (!realtime) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
465 remove_prebuffer = FALSE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
466
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
467 written += length;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
468 while (length > 0) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
469 cnt = MIN(length, buffer_size - wr_index);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
470 memcpy(buffer + wr_index, (char *) ptr + off, cnt);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
471 wr_index = (wr_index + cnt) % buffer_size;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
472 length -= cnt;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
473 off += cnt;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
474 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
475 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
476 else {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
477 if (paused)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
478 return;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
479 oss_write_audio(ptr, length);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
480 written += length;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
481 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
482 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
483
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
484 void
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
485 oss_close(void)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
486 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
487 if (!going)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
488 return;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
489 going = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
490 if (!realtime)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
491 g_thread_join(buffer_thread);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
492 else {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
493 ioctl(fd, SNDCTL_DSP_RESET, 0);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
494 close(fd);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
495 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
496 g_free(device_name);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
497 oss_free_convert_buffer();
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
498 wr_index = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
499 rd_index = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
500 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
501
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
502 void
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
503 oss_flush(gint time)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
504 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
505 if (!realtime) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
506 flush = time;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
507 while (flush != -1)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
508 xmms_usleep(10000);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
509 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
510 else {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
511 ioctl(fd, SNDCTL_DSP_RESET, 0);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
512 close(fd);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
513 fd = open(device_name, O_WRONLY);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
514 oss_set_audio_params();
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
515 output_time_offset = time;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
516 written = ((guint64) time * input.bps) / 1000;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
517 output_bytes = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
518 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
519 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
520
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
521 void
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
522 oss_pause(short p)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
523 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
524 if (!realtime) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
525 if (p == TRUE)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
526 do_pause = TRUE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
527 else
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
528 unpause = TRUE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
529 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
530 else
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
531 paused = p;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
532
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
533 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
534
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
535 gpointer
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
536 oss_loop(gpointer arg)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
537 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
538 gint length, cnt;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
539 fd_set set;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
540 struct timeval tv;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
541
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
542 while (going) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
543 if (oss_used() > prebuffer_size)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
544 prebuffer = FALSE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
545 if (oss_used() > 0 && !paused && !prebuffer) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
546 tv.tv_sec = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
547 tv.tv_usec = 10000;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
548 FD_ZERO(&set);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
549 FD_SET(fd, &set);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
550 if (!select_works || (select(fd + 1, NULL, &set, NULL, &tv) > 0)) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
551 length = MIN(blk_size, oss_used());
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
552 while (length > 0) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
553 cnt = MIN(length, buffer_size - rd_index);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
554 oss_write_audio(buffer + rd_index, cnt);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
555 rd_index = (rd_index + cnt) % buffer_size;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
556 length -= cnt;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
557 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
558 if (!oss_used())
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
559 ioctl(fd, SNDCTL_DSP_POST, 0);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
560 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
561 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
562 else
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
563 xmms_usleep(10000);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
564 oss_calc_device_buffer_used();
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
565 if (do_pause && !paused) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
566 do_pause = FALSE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
567 paused = TRUE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
568 /*
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
569 * We lose some data here that is sent to the
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
570 * soundcard, but not yet played. I don't
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
571 * think this is worth fixing.
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
572 */
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
573 ioctl(fd, SNDCTL_DSP_RESET, 0);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
574 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
575 else if (unpause && paused) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
576 unpause = FALSE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
577 close(fd);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
578 fd = open(device_name, O_WRONLY);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
579 oss_set_audio_params();
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
580 paused = FALSE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
581 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
582
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
583 if (flush != -1) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
584 /*
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
585 * This close and open is a work around of a
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
586 * bug that exists in some drivers which cause
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
587 * the driver to get fucked up by a reset
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
588 */
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
589
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
590 ioctl(fd, SNDCTL_DSP_RESET, 0);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
591 close(fd);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
592 fd = open(device_name, O_WRONLY);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
593 oss_set_audio_params();
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
594 output_time_offset = flush;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
595 written = ((guint64) flush * input.bps) / 1000;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
596 rd_index = wr_index = output_bytes = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
597 flush = -1;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
598 prebuffer = TRUE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
599 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
600
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
601 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
602
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
603 ioctl(fd, SNDCTL_DSP_RESET, 0);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
604 close(fd);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
605 g_free(buffer);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
606 return NULL;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
607 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
608
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
609 void
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
610 oss_set_audio_params(void)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
611 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
612 int frag, stereo, ret;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
613 struct timeval tv;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
614 fd_set set;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
615
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
616 ioctl(fd, SNDCTL_DSP_RESET, 0);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
617 frag = (NFRAGS << 16) | fragsize;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
618 ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
619 /*
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
620 * Set the stream format. This ioctl() might fail, but should
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
621 * return a format that works if it does.
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
622 */
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
623 ioctl(fd, SNDCTL_DSP_SETFMT, &output.format.oss);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
624 if (ioctl(fd, SNDCTL_DSP_SETFMT, &output.format.oss) == -1)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
625 g_warning("SNDCTL_DSP_SETFMT ioctl failed: %s", strerror(errno));
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
626
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
627 stereo = output.channels - 1;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
628 ioctl(fd, SNDCTL_DSP_STEREO, &stereo);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
629 output.channels = stereo + 1;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
630
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
631 oss_stereo_convert_func = oss_get_stereo_convert_func(output.channels,
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
632 effect.channels);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
633
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
634 if (ioctl(fd, SNDCTL_DSP_SPEED, &output.frequency) == -1)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
635 g_warning("SNDCTL_DSP_SPEED ioctl failed: %s", strerror(errno));
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
636
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
637 if (ioctl(fd, SNDCTL_DSP_GETBLKSIZE, &blk_size) == -1)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
638 blk_size = 1L << fragsize;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
639
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
640 oss_convert_func =
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
641 oss_get_convert_func(output.format.oss,
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
642 oss_get_format(effect.format.xmms));
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
643
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
644 /*
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
645 * Stupid hack to find out if the driver support selects, some
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
646 * drivers won't work properly without a select and some won't
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
647 * work with a select :/
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
648 */
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
649
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
650 tv.tv_sec = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
651 tv.tv_usec = 50000;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
652 FD_ZERO(&set);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
653 FD_SET(fd, &set);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
654 ret = select(fd + 1, NULL, &set, NULL, &tv);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
655 if (ret > 0)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
656 select_works = TRUE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
657 else
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
658 select_works = FALSE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
659 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
660
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
661 gint
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
662 oss_open(AFormat fmt, gint rate, gint nch)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
663 {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
664
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
665 if (oss_cfg.use_alt_audio_device && oss_cfg.alt_audio_device)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
666 device_name = g_strdup(oss_cfg.alt_audio_device);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
667 else {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
668 if (oss_cfg.audio_device > 0)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
669 device_name =
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
670 g_strdup_printf("%s%d", DEV_DSP, oss_cfg.audio_device);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
671 else
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
672 device_name = g_strdup(DEV_DSP);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
673 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
674
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
675 fd = open(device_name, O_WRONLY);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
676
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
677 if (fd == -1) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
678 g_warning("oss_open(): Failed to open audio device (%s): %s",
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
679 device_name, strerror(errno));
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
680 g_free(device_name);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
681 return 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
682 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
683
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
684 input.format.xmms = fmt;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
685 input.frequency = rate;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
686 input.channels = nch;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
687 input.bps = oss_calc_bitrate(oss_get_format(fmt), rate, nch);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
688
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
689 oss_setup_format(fmt, rate, nch);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
690
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
691 realtime = xmms_check_realtime_priority();
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
692
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
693 if (!realtime) {
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
694 buffer_size = (oss_cfg.buffer_size * input.bps) / 1000;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
695 if (buffer_size < 8192)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
696 buffer_size = 8192;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
697 prebuffer_size = (buffer_size * oss_cfg.prebuffer) / 100;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
698 if (buffer_size - prebuffer_size < 4096)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
699 prebuffer_size = buffer_size - 4096;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
700
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
701 buffer_size += device_buffer_size;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
702 buffer = g_malloc0(buffer_size);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
703 }
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
704 flush = -1;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
705 prebuffer = TRUE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
706 wr_index = rd_index = output_time_offset = written = output_bytes = 0;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
707 paused = FALSE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
708 do_pause = FALSE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
709 unpause = FALSE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
710 remove_prebuffer = FALSE;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
711
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
712 going = 1;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
713 if (!realtime)
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
714 buffer_thread = g_thread_create(oss_loop, NULL, TRUE, NULL);
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
715 return 1;
fa848bd484d8 [svn] Move plugins to Plugins/
nenolod
parents:
diff changeset
716 }
517
55dc40ff1aff [svn] Add tell_audio(AFormat *, gint *, gint *), for retrieving audio
nenolod
parents: 382
diff changeset
717
55dc40ff1aff [svn] Add tell_audio(AFormat *, gint *, gint *), for retrieving audio
nenolod
parents: 382
diff changeset
718 void oss_tell(AFormat * fmt, gint * rate, gint * nch)
55dc40ff1aff [svn] Add tell_audio(AFormat *, gint *, gint *), for retrieving audio
nenolod
parents: 382
diff changeset
719 {
55dc40ff1aff [svn] Add tell_audio(AFormat *, gint *, gint *), for retrieving audio
nenolod
parents: 382
diff changeset
720 (*fmt) = input.format.xmms;
55dc40ff1aff [svn] Add tell_audio(AFormat *, gint *, gint *), for retrieving audio
nenolod
parents: 382
diff changeset
721 (*rate) = input.frequency;
55dc40ff1aff [svn] Add tell_audio(AFormat *, gint *, gint *), for retrieving audio
nenolod
parents: 382
diff changeset
722 (*nch) = input.channels;
55dc40ff1aff [svn] Add tell_audio(AFormat *, gint *, gint *), for retrieving audio
nenolod
parents: 382
diff changeset
723 }