]> code.delx.au - pulseaudio/blob - polyp/cli-text.c
add simple hardware auto detection module
[pulseaudio] / polyp / cli-text.c
1 /* $Id$ */
2
3 /***
4 This file is part of polypaudio.
5
6 polypaudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
10
11 polypaudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with polypaudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <assert.h>
27 #include <string.h>
28
29 #include "cli-text.h"
30 #include "module.h"
31 #include "client.h"
32 #include "sink.h"
33 #include "source.h"
34 #include "sink-input.h"
35 #include "source-output.h"
36 #include "strbuf.h"
37 #include "sample-util.h"
38 #include "scache.h"
39 #include "autoload.h"
40 #include "xmalloc.h"
41 #include "volume.h"
42
43 char *pa_module_list_to_string(pa_core *c) {
44 pa_strbuf *s;
45 pa_module *m;
46 uint32_t idx = PA_IDXSET_INVALID;
47 assert(c);
48
49 s = pa_strbuf_new();
50 assert(s);
51
52 pa_strbuf_printf(s, "%u module(s) loaded.\n", pa_idxset_size(c->modules));
53
54 for (m = pa_idxset_first(c->modules, &idx); m; m = pa_idxset_next(c->modules, &idx))
55 pa_strbuf_printf(s, " index: %u\n\tname: <%s>\n\targument: <%s>\n\tused: %i\n\tauto unload: %s\n", m->index, m->name, m->argument, m->n_used, m->auto_unload ? "yes" : "no");
56
57 return pa_strbuf_tostring_free(s);
58 }
59
60 char *pa_client_list_to_string(pa_core *c) {
61 pa_strbuf *s;
62 pa_client *client;
63 uint32_t idx = PA_IDXSET_INVALID;
64 assert(c);
65
66 s = pa_strbuf_new();
67 assert(s);
68
69 pa_strbuf_printf(s, "%u client(s) logged in.\n", pa_idxset_size(c->clients));
70
71 for (client = pa_idxset_first(c->clients, &idx); client; client = pa_idxset_next(c->clients, &idx)) {
72 pa_strbuf_printf(s, " index: %u\n\tname: <%s>\n\tdriver: <%s>\n", client->index, client->name, client->driver);
73
74 if (client->owner)
75 pa_strbuf_printf(s, "\towner module: <%u>\n", client->owner->index);
76 }
77
78 return pa_strbuf_tostring_free(s);
79 }
80
81 char *pa_sink_list_to_string(pa_core *c) {
82 pa_strbuf *s;
83 pa_sink *sink;
84 uint32_t idx = PA_IDXSET_INVALID;
85 assert(c);
86
87 s = pa_strbuf_new();
88 assert(s);
89
90 pa_strbuf_printf(s, "%u sink(s) available.\n", pa_idxset_size(c->sinks));
91
92 for (sink = pa_idxset_first(c->sinks, &idx); sink; sink = pa_idxset_next(c->sinks, &idx)) {
93 char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
94
95 pa_strbuf_printf(
96 s,
97 " %c index: %u\n"
98 "\tname: <%s>\n"
99 "\tdriver: <%s>\n"
100 "\tvolume: <%s>\n"
101 "\tlatency: <%0.0f usec>\n"
102 "\tmonitor_source: <%u>\n"
103 "\tsample spec: <%s>\n"
104 "\tchannel map: <%s>\n",
105 c->default_sink_name && !strcmp(sink->name, c->default_sink_name) ? '*' : ' ',
106 sink->index, sink->name,
107 sink->driver,
108 pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink, PA_MIXER_HARDWARE)),
109 (double) pa_sink_get_latency(sink),
110 sink->monitor_source->index,
111 pa_sample_spec_snprint(ss, sizeof(ss), &sink->sample_spec),
112 pa_channel_map_snprint(cm, sizeof(cm), &sink->channel_map));
113
114 if (sink->owner)
115 pa_strbuf_printf(s, "\towner module: <%u>\n", sink->owner->index);
116 if (sink->description)
117 pa_strbuf_printf(s, "\tdescription: <%s>\n", sink->description);
118 }
119
120 return pa_strbuf_tostring_free(s);
121 }
122
123 char *pa_source_list_to_string(pa_core *c) {
124 pa_strbuf *s;
125 pa_source *source;
126 uint32_t idx = PA_IDXSET_INVALID;
127 assert(c);
128
129 s = pa_strbuf_new();
130 assert(s);
131
132 pa_strbuf_printf(s, "%u source(s) available.\n", pa_idxset_size(c->sources));
133
134 for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) {
135 char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
136
137
138 pa_strbuf_printf(
139 s,
140 " %c index: %u\n"
141 "\tname: <%s>\n"
142 "\tdriver: <%s>\n"
143 "\tlatency: <%0.0f usec>\n"
144 "\tsample spec: <%s>\n"
145 "\tchannel map: <%s>\n",
146 c->default_source_name && !strcmp(source->name, c->default_source_name) ? '*' : ' ',
147 source->index,
148 source->name,
149 source->driver,
150 (double) pa_source_get_latency(source),
151 pa_sample_spec_snprint(ss, sizeof(ss), &source->sample_spec),
152 pa_channel_map_snprint(cm, sizeof(cm), &source->channel_map));
153
154 if (source->monitor_of)
155 pa_strbuf_printf(s, "\tmonitor_of: <%u>\n", source->monitor_of->index);
156 if (source->owner)
157 pa_strbuf_printf(s, "\towner module: <%u>\n", source->owner->index);
158 if (source->description)
159 pa_strbuf_printf(s, "\tdescription: <%s>\n", source->description);
160 }
161
162 return pa_strbuf_tostring_free(s);
163 }
164
165
166 char *pa_source_output_list_to_string(pa_core *c) {
167 pa_strbuf *s;
168 pa_source_output *o;
169 uint32_t idx = PA_IDXSET_INVALID;
170 static const char* const state_table[] = {
171 "RUNNING",
172 "CORKED",
173 "DISCONNECTED"
174 };
175 assert(c);
176
177 s = pa_strbuf_new();
178 assert(s);
179
180 pa_strbuf_printf(s, "%u source outputs(s) available.\n", pa_idxset_size(c->source_outputs));
181
182 for (o = pa_idxset_first(c->source_outputs, &idx); o; o = pa_idxset_next(c->source_outputs, &idx)) {
183 char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
184
185 assert(o->source);
186
187 pa_strbuf_printf(
188 s,
189 " index: %u\n"
190 "\tname: '%s'\n"
191 "\tdriver: <%s>\n"
192 "\tstate: %s\n"
193 "\tsource: <%u> '%s'\n"
194 "\tsample spec: <%s>\n"
195 "\tchannel map: <%s>\n"
196 "\tresample method: %s\n",
197 o->index,
198 o->name,
199 o->driver,
200 state_table[o->state],
201 o->source->index, o->source->name,
202 pa_sample_spec_snprint(ss, sizeof(ss), &o->sample_spec),
203 pa_channel_map_snprint(cm, sizeof(cm), &o->channel_map),
204 pa_resample_method_to_string(pa_source_output_get_resample_method(o)));
205 if (o->owner)
206 pa_strbuf_printf(s, "\towner module: <%u>\n", o->owner->index);
207 if (o->client)
208 pa_strbuf_printf(s, "\tclient: <%u> '%s'\n", o->client->index, o->client->name);
209 }
210
211 return pa_strbuf_tostring_free(s);
212 }
213
214 char *pa_sink_input_list_to_string(pa_core *c) {
215 pa_strbuf *s;
216 pa_sink_input *i;
217 uint32_t idx = PA_IDXSET_INVALID;
218 static const char* const state_table[] = {
219 "RUNNING",
220 "CORKED",
221 "DISCONNECTED"
222 };
223
224 assert(c);
225 s = pa_strbuf_new();
226 assert(s);
227
228 pa_strbuf_printf(s, "%u sink input(s) available.\n", pa_idxset_size(c->sink_inputs));
229
230 for (i = pa_idxset_first(c->sink_inputs, &idx); i; i = pa_idxset_next(c->sink_inputs, &idx)) {
231 char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
232
233 assert(i->sink);
234
235 pa_strbuf_printf(
236 s,
237 " index: %u\n"
238 "\tname: <%s>\n"
239 "\tdriver: <%s>\n"
240 "\tstate: %s\n"
241 "\tsink: <%u> '%s'\n"
242 "\tvolume: <%s>\n"
243 "\tlatency: <%0.0f usec>\n"
244 "\tsample spec: <%s>\n"
245 "\tchannel map: <%s>\n"
246 "\tresample method: %s\n",
247 i->index,
248 i->name,
249 i->driver,
250 state_table[i->state],
251 i->sink->index, i->sink->name,
252 pa_cvolume_snprint(cv, sizeof(cv), pa_sink_input_get_volume(i)),
253 (double) pa_sink_input_get_latency(i),
254 pa_sample_spec_snprint(ss, sizeof(ss), &i->sample_spec),
255 pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
256 pa_resample_method_to_string(pa_sink_input_get_resample_method(i)));
257
258 if (i->owner)
259 pa_strbuf_printf(s, "\towner module: <%u>\n", i->owner->index);
260 if (i->client)
261 pa_strbuf_printf(s, "\tclient: <%u> '%s'\n", i->client->index, i->client->name);
262 }
263
264 return pa_strbuf_tostring_free(s);
265 }
266
267 char *pa_scache_list_to_string(pa_core *c) {
268 pa_strbuf *s;
269 assert(c);
270
271 s = pa_strbuf_new();
272 assert(s);
273
274 pa_strbuf_printf(s, "%u cache entries available.\n", c->scache ? pa_idxset_size(c->scache) : 0);
275
276 if (c->scache) {
277 pa_scache_entry *e;
278 uint32_t idx = PA_IDXSET_INVALID;
279
280 for (e = pa_idxset_first(c->scache, &idx); e; e = pa_idxset_next(c->scache, &idx)) {
281 double l = 0;
282 char ss[PA_SAMPLE_SPEC_SNPRINT_MAX] = "n/a", cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
283
284 if (e->memchunk.memblock) {
285 pa_sample_spec_snprint(ss, sizeof(ss), &e->sample_spec);
286 pa_channel_map_snprint(cm, sizeof(cm), &e->channel_map);
287 l = (double) e->memchunk.length / pa_bytes_per_second(&e->sample_spec);
288 }
289
290 pa_strbuf_printf(
291 s,
292 " name: <%s>\n"
293 "\tindex: <%u>\n"
294 "\tsample spec: <%s>\n"
295 "\tchannel map: <%s>\n"
296 "\tlength: <%u>\n"
297 "\tduration: <%0.1fs>\n"
298 "\tvolume: <%s>\n"
299 "\tlazy: %s\n"
300 "\tfilename: %s\n",
301 e->name,
302 e->index,
303 ss,
304 cm,
305 e->memchunk.memblock ? e->memchunk.length : 0,
306 l,
307 pa_cvolume_snprint(cv, sizeof(cv), &e->volume),
308 e->lazy ? "yes" : "no",
309 e->filename ? e->filename : "n/a");
310 }
311 }
312
313 return pa_strbuf_tostring_free(s);
314 }
315
316 char *pa_autoload_list_to_string(pa_core *c) {
317 pa_strbuf *s;
318 assert(c);
319
320 s = pa_strbuf_new();
321 assert(s);
322
323 pa_strbuf_printf(s, "%u autoload entries available.\n", c->autoload_hashmap ? pa_hashmap_size(c->autoload_hashmap) : 0);
324
325 if (c->autoload_hashmap) {
326 pa_autoload_entry *e;
327 void *state = NULL;
328
329 while ((e = pa_hashmap_iterate(c->autoload_hashmap, &state, NULL))) {
330 pa_strbuf_printf(
331 s, " name: <%s>\n\ttype: <%s>\n\tindex: <%u>\n\tmodule_name: <%s>\n\targuments: <%s>\n",
332 e->name,
333 e->type == PA_NAMEREG_SOURCE ? "source" : "sink",
334 e->index,
335 e->module,
336 e->argument);
337
338 }
339 }
340
341 return pa_strbuf_tostring_free(s);
342 }
343
344 char *pa_full_status_string(pa_core *c) {
345 pa_strbuf *s;
346 int i;
347
348 s = pa_strbuf_new();
349
350 for (i = 0; i < 8; i++) {
351 char *t = NULL;
352
353 switch (i) {
354 case 0:
355 t = pa_sink_list_to_string(c);
356 break;
357 case 1:
358 t = pa_source_list_to_string(c);
359 break;
360 case 2:
361 t = pa_sink_input_list_to_string(c);
362 break;
363 case 3:
364 t = pa_source_output_list_to_string(c);
365 break;
366 case 4:
367 t = pa_client_list_to_string(c);
368 break;
369 case 5:
370 t = pa_module_list_to_string(c);
371 break;
372 case 6:
373 t = pa_scache_list_to_string(c);
374 break;
375 case 7:
376 t = pa_autoload_list_to_string(c);
377 break;
378 }
379
380 pa_strbuf_puts(s, t);
381 pa_xfree(t);
382 }
383
384 return pa_strbuf_tostring_free(s);
385 }