source: contrib/API/tools/unimix.c@ 578

Last change on this file since 578 was 578, checked in by David Azarewicz, 11 years ago

API updates

File size: 14.6 KB
Line 
1#define INCL_DOS
2#define INCL_DOSERRORS
3#include <os2.h>
4#include <stdlib.h>
5#include <stdio.h>
6#include <string.h>
7
8#include "uniaud.h"
9
10typedef struct DumpFileHeader {
11 char ID[10]; // "UNIMIXDUMP"
12 unsigned char driver[16]; /* Driver name */
13 int controls; // number of controls
14} DumpFileHeader;
15
16char DUMPID[10] = "UNIMIXDUMP";
17
18int pcms_num[MAX_CARDS] = {0}; // number of pcm instances
19int cards_num = 0; // number of cards
20
21POSS32_DEVCAPS pcmcaps[MAX_CARDS] = {0}; // pointer to pcm caps
22
23UniaudCardInfo *CardInfo[MAX_CARDS] = {0};
24
25
26int SaveDump(int card_id, char *fname)
27{
28 DumpFileHeader dfh;
29 int ctls = 0;
30 int i = 0;
31 UniaudControlValue *ctl_val = NULL;
32 FILE *f = NULL;
33 UniaudControl *pCtl = NULL;
34
35 if (!fname) return -1;
36 f = fopen(fname, "wb");
37 if (!f) return -1;
38 memcpy(&dfh.ID,&DUMPID,sizeof(DUMPID));
39 memcpy(&dfh.driver,&CardInfo[card_id]->driver,sizeof(CardInfo[card_id]->driver));
40
41 ctls = uniaud_mixer_get_ctls_number(card_id);
42 dfh.controls = ctls;
43
44 fwrite(&dfh,sizeof(dfh),1,f); // writing header
45 pCtl = (UniaudControl * )uniaud_mixer_get_ctl_list(card_id);
46 if (pCtl)
47 {
48 ctl_val = (UniaudControlValue *)malloc(sizeof(UniaudControlValue));
49 for(i=1; i<=ctls; i++)
50 {
51 memset(ctl_val,0,sizeof(UniaudControlValue));
52 uniaud_mixer_get_ctl_val(card_id, pCtl->numid, ctl_val);
53 fwrite(ctl_val,sizeof(UniaudControlValue),1,f); // writing values
54 pCtl++;
55 } // for
56 }
57 if (ctl_val) free(ctl_val);
58 fclose(f);
59 return 0;
60}
61
62int LoadDump(int card_id, char *fname)
63{
64 DumpFileHeader dfh;
65 int ctls = 0;
66 int i = 0;
67 UniaudControlValue *ctl_val = NULL;
68 FILE *f = NULL;
69 UniaudControl *pCtl = NULL;
70
71 if (!fname) return -1;
72 f = fopen(fname, "rb");
73 if (!f) return -1;
74
75 fread(&dfh, sizeof(dfh),1,f);
76 if ((memcmp(&dfh.ID,&DUMPID,sizeof(DUMPID)) != 0) ||
77 (memcmp(&dfh.driver,&CardInfo[card_id]->driver,sizeof(CardInfo[card_id]->driver)) != 0))
78 {
79 fclose(f);
80 return -2;
81 }
82
83 ctls = uniaud_mixer_get_ctls_number(card_id);
84
85 if (dfh.controls!=ctls)
86 {
87 // invalid controls count
88 fclose(f);
89 return -3;
90 }
91
92 pCtl = (UniaudControl * )uniaud_mixer_get_ctl_list(card_id);
93
94 if (pCtl)
95 {
96 ctl_val = (UniaudControlValue *)malloc(sizeof(UniaudControlValue));
97 for(i=1; i<=ctls; i++)
98 {
99 fread(ctl_val,sizeof(UniaudControlValue),1,f); // writing values
100 if (pCtl->numid != ctl_val->id.numid) continue;
101 if (uniaud_mixer_put_ctl_val(card_id, pCtl->numid, ctl_val))
102 {
103 // invalid controls count
104 fclose(f);
105 return -4;
106 }
107 pCtl++;
108 } // for
109 }
110 if (ctl_val) free(ctl_val);
111 fclose(f);
112 return 0;
113}
114
115
116void Usage(void)
117{
118 printf("Usage:\n");
119 printf(" -dev<num> - card to work (default=0)\n");
120 printf(" -id<num> - use control num (for list or set value). Begins from 1\n");
121 printf(" -cnt<num> - set value for count number <num> in control. Begins from 0\n");
122 printf(" -val<num> - set value for control\n");
123 printf(" -card - show card info\n");
124 printf(" -pcms - show PCM instances info\n");
125 printf(" -list - full (id,name,bounds,value) control(s) list\n");
126 printf(" -names - just control(s) name(s) and ID\n");
127 printf(" -get - get value switch. uses with -id and/or -cnt\n");
128 printf(" -powerget - get power state\n");
129 printf(" -powerset<num> - set power state\n");
130 printf(" -save<file> - save dump of all values of all controls to file\n");
131 printf(" -load<file> - load dump from file to all values of all controls\n");
132 printf("\nAll arguments are processed in order. -dev, -id, and -cnt simply set a value\n");
133 printf("that is retained until changed. All other arguments perform a command.\n");
134 printf("Example: unimix -id5 -cnt0 -val15 -cnt1 -val16 -list\n");
135 printf("sets id5 cnt0 to 15, then sets id5 cnt1 to 16, then lists id5\n");
136
137}
138
139int ShowCardInfo(int CardId, UniaudCardInfo *cInfo)
140{
141 if (!cInfo) return -1;
142
143 printf("Card info for adapter %d:\n", CardId);
144 printf(" num: %i\n",cInfo->card);
145 printf(" id: %s\n",cInfo->id);
146 printf(" driver: %s\n",cInfo->driver);
147 printf(" name: %s\n",cInfo->name);
148 printf(" longname: %s\n",cInfo->longname);
149 printf(" mixer: %s\n",cInfo->mixername);
150 printf(" componenets: %s\n",cInfo->components);
151 return 0;
152}
153
154int ShowPCMInstanceInfo(int CardId, POSS32_DEVCAPS pcaps, int pcms)
155{
156 int i;
157 POSS32_DEVCAPS pcaps1 = pcaps;
158
159 if (!pcaps || pcms <= 0) return -1;
160
161 printf("PCM Instance Info for adapter %d\n", CardId);
162
163 for (i=0; i<pcms; i++) {
164 printf("PCM No %i info:\n", i);
165 printf("PCM dev name: [%s] mixer [%s]\n",pcaps1->szDeviceName, pcaps1->szMixerName);
166 printf(" PLAY\n");
167 printf(" streams: %i\n",pcaps1->waveOutCaps.nrStreams);
168 printf(" channels: from %i to %i\n",pcaps1->waveOutCaps.ulMinChannels,
169 pcaps1->waveOutCaps.ulMaxChannels);
170 printf(" rates: from %i to %i\n",pcaps1->waveOutCaps.ulMinRate,
171 pcaps1->waveOutCaps.ulMaxRate);
172 printf(" RECORD\n");
173 printf(" streams: %i\n",pcaps1->waveInCaps.nrStreams);
174 printf(" channels: from %i to %i\n",pcaps1->waveInCaps.ulMinChannels,
175 pcaps1->waveInCaps.ulMaxChannels);
176 printf(" rates: from %i to %i\n",pcaps1->waveInCaps.ulMinRate,
177 pcaps1->waveInCaps.ulMaxRate);
178 printf("\n");
179 pcaps1++;
180 }
181 return 0;
182}
183
184int PrintControl(UniaudControlInfo *ctl_info, UniaudControlValue *ctl_val)
185{
186 int i;
187
188 if (ctl_info == NULL || ctl_val == NULL) return -1;
189
190 printf("\nControl ID: %i\n", ctl_info->id.numid);
191 printf("Interface: ");
192 switch(ctl_info->id.iface) {
193 case SNDRV_CTL_ELEM_IFACE_CARD:
194 printf("global control\n");
195 break;
196 case SNDRV_CTL_ELEM_IFACE_HWDEP:
197 printf("hardware dependent device\n");
198 break;
199 case SNDRV_CTL_ELEM_IFACE_MIXER:
200 printf("virtual mixer device\n");
201 break;
202 case SNDRV_CTL_ELEM_IFACE_PCM:
203 printf("PCM device\n");
204 break;
205 case SNDRV_CTL_ELEM_IFACE_RAWMIDI:
206 printf("RawMidi device\n");
207 break;
208 case SNDRV_CTL_ELEM_IFACE_TIMER:
209 printf("timer device\n");
210 break;
211 case SNDRV_CTL_ELEM_IFACE_SEQUENCER:
212 printf("sequencer client\n");
213 break;
214 }
215 printf("Device(client): %i, subdevice (substream) %i\n", ctl_info->id.device, ctl_info->id.subdevice);
216 printf("Name: [%s]\n",ctl_info->id.name);
217 printf("Index: %i\n", ctl_info->id.index);
218
219 printf("Element type: ");
220 switch(ctl_info->type) {
221 case SNDRV_CTL_ELEM_TYPE_NONE:
222 printf("invalid\n");
223 break;
224 case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
225 printf("boolean type\n");
226 break;
227 case SNDRV_CTL_ELEM_TYPE_INTEGER:
228 printf("integer type\n");
229 break;
230 case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
231 printf("enumerated type\n");
232 break;
233 case SNDRV_CTL_ELEM_TYPE_BYTES:
234 printf("byte array\n");
235 break;
236 case SNDRV_CTL_ELEM_TYPE_IEC958:
237 printf("IEC958 (S/PDIF) setup\n");
238 break;
239 case SNDRV_CTL_ELEM_TYPE_INTEGER64:
240 printf("64-bit integer type\n");
241 break;
242 }
243
244 printf("Count of values: %i\n", ctl_info->count);
245 printf("Value: \n");
246 switch(ctl_info->type) {
247 case SNDRV_CTL_ELEM_TYPE_BOOLEAN:
248 case SNDRV_CTL_ELEM_TYPE_INTEGER:
249 printf(" Bounds: min: %i, max: %i, step: %i\n",
250 ctl_info->value.integer.min,
251 ctl_info->value.integer.max,
252 ctl_info->value.integer.step);
253 for (i=0; i < ctl_info->count; i++)
254 printf(" value %d: %i\n",i, ctl_val->value.integer.value[i]);
255 break;
256 case SNDRV_CTL_ELEM_TYPE_INTEGER64:
257 printf(" Bounds: min: %i, max: %i, step: %i\n",
258 ctl_info->value.integer64.min,
259 ctl_info->value.integer64.max,
260 ctl_info->value.integer64.step);
261 for (i=0; i < ctl_info->count; i++)
262 printf(" value %d: %i\n",i, ctl_val->value.integer64.value[i]);
263 break;
264 case SNDRV_CTL_ELEM_TYPE_ENUMERATED:
265 printf(" Bounds: items: %i, item: %i, name: [%s]\n",
266 ctl_info->value.enumerated.items,
267 ctl_info->value.enumerated.item,
268 ctl_info->value.enumerated.name);
269 for (i=0; i < ctl_info->count; i++)
270 printf(" value %d: %i\n",i, ctl_val->value.enumerated.item[i]);
271#if 0
272 if (ctl_val->value.enumerated.data_ptr)
273 printf("data [%s]\n", ctl_val->value.enumerated.data_ptr);
274 printf("data[] [%s]\n", ctl_val->value.enumerated.data);
275#endif
276 break;
277 case SNDRV_CTL_ELEM_TYPE_BYTES:
278 break;
279 case SNDRV_CTL_ELEM_TYPE_IEC958:
280 printf(" AES0=0x%02x,AES1=0x%02x,AES2=0x%02x,AES3=0x%02x\n",
281 ctl_val->value.iec958.status[0],
282 ctl_val->value.iec958.status[1],
283 ctl_val->value.iec958.status[2],
284 ctl_val->value.iec958.status[3]);
285 break;
286 }
287
288 return 0;
289}
290
291int unimix_show_controls(int card_id, int ctl_id, int just_names)
292{
293 int ctls, i;
294 UniaudControlValue *ctl_val = NULL;
295 UniaudControlInfo *ctl_info = NULL;
296 UniaudControl *pCtl = NULL;
297
298 ctls = uniaud_mixer_get_ctls_number(card_id);
299
300 pCtl = (UniaudControl * )uniaud_mixer_get_ctl_list(card_id);
301
302 printf("Control list for adapter %d\n", card_id);
303
304 if (pCtl) {
305 ctl_val = (UniaudControlValue *)malloc(sizeof(UniaudControlValue));
306 ctl_info = (UniaudControlInfo *)malloc(sizeof(UniaudControlInfo));
307 for(i=0; i<ctls; i++) {
308 memset(ctl_val, 0, sizeof(UniaudControlValue));
309 memset(ctl_info, 0, sizeof(UniaudControlInfo));
310 uniaud_mixer_get_ctl_info(card_id, pCtl->numid, ctl_info);
311 uniaud_mixer_get_ctl_val(card_id, pCtl->numid, ctl_val);
312 if ((ctl_id && pCtl->numid == ctl_id) || (ctl_id == 0)) {
313 if (just_names)
314 printf("ID: %i, name: [%s]\n", pCtl->numid, pCtl->name);
315 else
316 PrintControl(ctl_info, ctl_val);
317 }
318 pCtl++;
319 }
320 free(ctl_info);
321 free(ctl_val);
322 }
323 return 0;
324}
325
326int main (int argc, char *argv[])
327{
328 int iArgNum;
329 int iParmCardId;
330 ULONG ulParmId;
331 int iParmVal;
332 int iParmCnt;
333 char *fname; // dump file name
334 int iTmp;
335 int i;
336 ULONG ulRc;
337
338 printf("Command line mixer for UNIAUD32. Version 1.1\n");
339
340 if (argc < 2) {
341 Usage();
342 return 1;
343 }
344
345 iTmp = uniaud_get_version();
346
347 switch (iTmp) {
348 case -2:
349 printf("Error: uniaud not detected\n");
350 return 1;
351 break;
352 case -1:
353 printf("Error: uniaud error\n");
354 return 1;
355 break;
356 default:
357 if (iTmp < 192) {
358 printf("Error: unsupported version of uniaud\n");
359 return 1;
360 } else
361 printf("Detected UNIAUD version %1d.%02d.%02d\n", iTmp/10000, (iTmp / 100) % 100, iTmp % 100 );
362 }
363
364 cards_num = uniaud_get_cards();
365 printf("Detected %i audio adapter(s)\n", cards_num);
366 if (!cards_num) return 1;
367
368 for(i=0; i<cards_num; i++) {
369 CardInfo[i] = malloc(sizeof(UniaudCardInfo));
370 if (!CardInfo[i]) {
371 printf("Malloc error: CardInfo\n");
372 return 1;
373 }
374 if (uniaud_get_card_info(i, CardInfo[i]) < 0) {
375 printf("Error: unable to get card info for adapter %d\n", i);
376 }
377 //ShowCardInfo(CardInfo[i]);
378 pcms_num[i] = uniaud_get_pcm_instances(i);
379 if (pcms_num[i] <= 0) {
380 printf("Error: invalid number of PCM instances for adapter %d\n", i);
381 } else {
382 pcmcaps[i] = (POSS32_DEVCAPS)malloc(sizeof(OSS32_DEVCAPS)*pcms_num[i]);
383 if (!pcmcaps[i]) {
384 printf("Malloc error: pcmcaps\n");
385 return 1;
386 }
387 if (uniaud_pcm_get_caps(i, pcmcaps[i]) < 0) {
388 printf("Error: unable to get PCM instances for adapter %d\n", i);
389 }
390 }
391 }
392 //printf("control %i changed\n", uniaud_mixer_wait());
393
394 //printf("sz = %i\n", sizeof(struct sndrv_ctl_elem_info));
395
396 ulParmId = 0;
397 iParmVal = 0;
398 iParmCnt = 0;
399 iParmCardId = 0;
400 for(iArgNum = 1; iArgNum < argc; iArgNum++) {
401 if (strncmp(argv[iArgNum], "-dev", 4) == 0) {
402 iParmCardId = atoi(argv[iArgNum] + 4);
403 continue;
404 }
405 if (strncmp(argv[iArgNum], "-id", 3) == 0) {
406 ulParmId = atoi(argv[iArgNum] + 3);
407 continue;
408 }
409 if (strncmp(argv[iArgNum], "-cnt", 4) == 0) {
410 iParmCnt = atoi(argv[iArgNum] + 4);
411 continue;
412 }
413 if (strncmp(argv[iArgNum], "-get", 4) == 0) {
414 printf("Getting ID:%i, cnt:%i...",ulParmId, iParmCnt);
415 iTmp = uniaud_mixer_get_value(iParmCardId, ulParmId, iParmCnt);
416 printf("val=%i\n", iTmp);
417 continue;
418 }
419 if (strncmp(argv[iArgNum], "-val", 4) == 0) {
420 iParmVal = atoi(argv[iArgNum] + 4);
421 printf("Setting Adapter: %i, ID:%i, cnt:%i, val:%i...",iParmCardId, ulParmId, iParmCnt, iParmVal);
422 ulRc=uniaud_mixer_put_value(iParmCardId, ulParmId, iParmVal, iParmCnt);
423 if (ulRc) printf("Failed\n");
424 else printf("Success\n");
425 continue;
426 }
427 if (strncmp(argv[iArgNum], "-save", 5) == 0) {
428 fname = argv[iArgNum] + 5;
429 if (!*fname) {
430 printf("Missing file name for save\n");
431 continue;
432 }
433 printf("Saving settings to file %s...", fname);
434 if (SaveDump(0, fname) < 0) printf("Failed\n");
435 else printf("Success\n");
436 continue;
437 }
438 if (strncmp(argv[iArgNum], "-load", 5) == 0) {
439 fname = argv[iArgNum] + 5;
440 if (!*fname) {
441 printf("Missing file name for save\n");
442 continue;
443 }
444 printf("Loading settings from file %s...", fname);
445 if (LoadDump(0, fname) < 0) printf("Failed\n");
446 else printf("Success\n");
447 continue;
448 }
449 if (strcmp(argv[iArgNum], "-list") == 0) {
450 unimix_show_controls(iParmCardId, ulParmId, 0);
451 continue;
452 }
453 if (strcmp(argv[iArgNum], "-card") == 0) {
454 ShowCardInfo(iParmCardId, CardInfo[iParmCardId]);
455 continue;
456 }
457 if (strcmp(argv[iArgNum], "-pcms") == 0) {
458 ShowPCMInstanceInfo(iParmCardId, pcmcaps[iParmCardId], pcms_num[iParmCardId]);
459 continue;
460 }
461 if (strcmp(argv[iArgNum], "-names") == 0) {
462 unimix_show_controls(iParmCardId, ulParmId, 1);
463 continue;
464 }
465 if (strncmp(argv[iArgNum], "-powerset", 9) == 0) {
466 iTmp = atoi(argv[iArgNum] + 4);
467 printf("Setting power state for adapter %d: %x...", iParmCardId, iTmp);
468 ulRc = uniaud_mixer_set_power_state(iParmCardId, (unsigned long *)&iTmp);
469 if (ulRc) printf("Failed\n");
470 else printf("Success\n");
471 continue;
472 }
473 if (strncmp(argv[iArgNum], "-powerget", 9) == 0) {
474 printf("Getting power state for adapter %d: ...", iParmCardId);
475 uniaud_mixer_get_power_state(iParmCardId, (unsigned long *)&iTmp);
476 printf("power state=%x\n", iTmp);
477 continue;
478 }
479 }
480
481 return 0;
482}
Note: See TracBrowser for help on using the repository browser.