11 #include <sys/ioctl.h>
14 #ifdef HAVE_OSS_INCLUDE_IN_SYS
15 # include <sys/soundcard.h>
17 # ifdef HAVE_OSS_INCLUDE_IN_ROOT
18 # include <soundcard.h>
20 # ifdef HAVE_OSS_INCLUDE_IN_MACHINE
21 # include <machine/soundcard.h>
23 # error "What to include?"
24 # endif /* HAVE_OSS_INCLUDE_IN_MACHINE */
25 # endif /* HAVE_OSS_INCLUDE_IN_ROOT */
26 #endif /* HAVE_OSS_INCLUDE_IN_SYS */
28 typedef struct _Probe Probe;
39 typedef struct _Range Range;
46 static gboolean probe_check (Probe * probe);
47 static int check_rate (Probe * probe, int irate);
48 static void add_range (GQueue * queue, int min, int max);
49 static void add_rate (GArray * array, int rate);
50 static int int_compare (gconstpointer a, gconstpointer b);
53 main (int argc, char *argv[])
59 fd = open ("/dev/dsp", O_RDWR);
65 probe = g_new0 (Probe, 1);
67 probe->format = AFMT_S16_LE;
68 probe->n_channels = 2;
71 g_array_sort (probe->rates, int_compare);
72 for (i = 0; i < probe->rates->len; i++) {
73 g_print ("%d\n", g_array_index (probe->rates, int, i));
76 g_array_free (probe->rates, TRUE);
80 probe = g_new0 (Probe, 1);
82 probe->format = AFMT_S16_LE;
83 probe->n_channels = 1;
86 for (i = 0; i < probe->rates->len; i++) {
87 g_print ("%d\n", g_array_index (probe->rates, int, i));
90 probe = g_new0 (Probe, 1);
92 probe->format = AFMT_U8;
93 probe->n_channels = 2;
96 for (i = 0; i < probe->rates->len; i++) {
97 g_print ("%d\n", g_array_index (probe->rates, int, i));
100 probe = g_new0 (Probe, 1);
102 probe->format = AFMT_U8;
103 probe->n_channels = 1;
106 for (i = 0; i < probe->rates->len; i++) {
107 g_print ("%d\n", g_array_index (probe->rates, int, i));
115 probe_check (Probe * probe)
120 gboolean checking_exact_rates = TRUE;
122 gboolean result = TRUE;
124 ranges = g_queue_new ();
126 probe->rates = g_array_new (FALSE, FALSE, sizeof (int));
128 probe->min = check_rate (probe, 1000);
130 probe->max = check_rate (probe, 100000);
132 add_range (ranges, probe->min + 1, probe->max - 1);
134 while ((range = g_queue_pop_head (ranges))) {
140 g_print ("checking [%d,%d]\n", range->min, range->max);
142 mid = (range->min + range->max) / 2;
143 mid_ret = check_rate (probe, mid);
146 if (mid == mid_ret && checking_exact_rates) {
147 int max_exact_matches = 100;
150 if (exact_rates > max_exact_matches) {
151 g_print ("got %d exact rates, assuming all are exact\n",
158 checking_exact_rates = FALSE;
161 /* Assume that the rate is arithmetically rounded to the nearest
163 if (mid == mid_ret) {
168 min1 = mid - (mid_ret - mid);
172 max1 = mid + (mid - mid_ret);
176 add_range (ranges, range->min, min1);
177 add_range (ranges, max1, range->max);
182 while ((range = g_queue_pop_head (ranges))) {
185 g_queue_free (ranges);
191 add_range (GQueue * queue, int min, int max)
193 g_print ("trying to add [%d,%d]\n", min, max);
195 Range *range = g_new0 (Range, 1);
200 g_queue_push_tail (queue, range);
201 //g_queue_push_head (queue, range);
206 check_rate (Probe * probe, int irate)
213 format = probe->format;
214 n_channels = probe->n_channels;
216 ioctl (probe->fd, SNDCTL_DSP_SETFMT, &format);
217 ioctl (probe->fd, SNDCTL_DSP_CHANNELS, &n_channels);
218 ioctl (probe->fd, SNDCTL_DSP_SPEED, &rate);
220 g_print ("rate %d -> %d\n", irate, rate);
222 if (rate == irate - 1 || rate == irate + 1) {
225 add_rate (probe->rates, rate);
230 add_rate (GArray * array, int rate)
235 for (i = 0; i < array->len; i++) {
236 val = g_array_index (array, int, i);
241 g_print ("supported rate: %d\n", rate);
242 g_array_append_val (array, rate);
246 int_compare (gconstpointer a, gconstpointer b)
248 const int *va = (const int *) a;
249 const int *vb = (const int *) b;