1 // Copyright (c) <2012> <Leif Asbrink>
2 //
3 // Permission is hereby granted, free of charge, to any person
4 // obtaining a copy of this software and associated documentation
5 // files (the "Software"), to deal in the Software without restriction,
6 // including without limitation the rights to use, copy, modify,
7 // merge, publish, distribute, sublicense, and/or sell copies of
8 // the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
16 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
21 // OR OTHER DEALINGS IN THE SOFTWARE.
22
23
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <string.h>
27 #include <pthread.h>
28 #include <semaphore.h>
29 #include "globdef.h"
30 #include "uidef.h"
31 #include "sigdef.h"
32 #include "fft1def.h"
33 #include "fft2def.h"
34 #include "fft3def.h"
35 #include "conf.h"
36 #include "lconf.h"
37 #include "screendef.h"
38 #include "sdrdef.h"
39 #include "vernr.h"
40 #include "rusage.h"
41 #include "thrdef.h"
42 #include "hwaredef.h"
43 #include "ldef.h"
44 #include "txdef.h"
45 #include "options.h"
46 #include "keyboard_def.h"
47 #include "padef.h"
48
49
50
51
52 #define ABOVE_MAX_SPEED 768000
53 #define MAX_COLUMN 80
54
55 #define DEVFLAG_R 1
56 #define DEVFLAG_W 2
57 #define DEVFLAG_RW 4
58 #if HAVE_OSS == 1
59 char dev_name[sizeof(SND_DEV)+2];
60 #endif
61 int devmodes[3]={O_RDONLY,O_WRONLY,O_RDWR};
62 char *devmode_txt[3]={"RDONLY","WRONLY","RDWR"};
63 #define DEVMODE_RDONLY 0
64 #define DEVMODE_WRONLY 1
65 #define DEVMODE_RDWR 2
66
67 double round(double x);
68 void thread_test_rxad(void);
69 void thread_test_rxda(void);
70 void thread_test_txda(void);
71
72 int soundcard_test_block_count[MAX_IOTEST];
73 int soundcard_test_cmd_flag[MAX_IOTEST];
74 pthread_t thread_identifier_soundcard_test[MAX_IOTEST];
75 ROUTINE thread_iotest[MAX_IOTEST]={thread_test_rxad, //0
76 thread_test_rxda, //1
77 thread_test_txda}; //2
78
79 int dev_flag[MAX_DEVNAMES];
80 int dev_rd_channels[MAX_DEVNAMES];
81 int dev_max_rd_speed[MAX_DEVNAMES];
82 int dev_min_rd_speed[MAX_DEVNAMES];
83 int dev_rd_bytes[MAX_DEVNAMES];
84 int dev_wr_channels[MAX_DEVNAMES];
85 int dev_max_wr_speed[MAX_DEVNAMES];
86 int dev_min_wr_speed[MAX_DEVNAMES];
87 int dev_wr_bytes[MAX_DEVNAMES];
88 char blanks[60];
89
90 char *wish_anyway="Do you wish to try to use it anyway (Y/N)?";
91 char *rx_logfile_name="soundboard_rx_init.log";
92 char *intrate_string=" interrupt rate: ";
93 int low_speeds[MAX_LOWSPEED]={1,5000,6000,8000,11025,16000,
94 22050,24000,48000,96000};
95
96 int zrw; // untested return value for OSS
97 void fix_prio(int no);
98
99
100 #if (ALSA_PRESENT == 1)
101 // alsa definitions start
102
103 #include <alsa/asoundlib.h>
104 #define MAX_ALSADEV 24
105 snd_pcm_t *rx_ad_handle, *rx_da_handle;
106 snd_pcm_t *tx_ad_handle, *tx_da_handle;
107
108 int alsa_dev_seq_nmbr;
109 char alsa_dev_soundcard_name [256];
110 char alsa_dev_name [64];
111 char alsa_dev_hw_pcm_name[MAX_ALSADEV];
112 char alsa_dev_plughw_pcm_name[MAX_ALSADEV];
113
114 unsigned int alsa_dev_min_rate[MAX_ALSADEV];
115 unsigned int alsa_dev_max_rate[MAX_ALSADEV];
116 int alsa_dev_min_channels;
117 int alsa_dev_max_channels;
118 int alsa_dev_min_bytes;
119 int alsa_dev_max_bytes;
120
121
122
edit_soundcard_name(char * s)123 void edit_soundcard_name(char *s)
124 {
125 int i,j,k,l;
126 // We are called with a string with a high number of blanks in the text.
127 // minimise the blanks and limit total text string length to max 51
128 i=(int)strlen(s);
129 j=0;
130 again:;
131 while(s[j] != ' ')j++;
132 if (j >= i) goto finish;
133 k=j;
134 while(s[k] == ' ')k++;
135 if (k >= i) goto finish;
136 l=k;
137 while(s[l] != ' ' && l < i)
138 {
139 j=j+1;
140 s[j]=s[l];
141 if (j != l)s[l]=' ';
142 l++;
143 }
144 if (l<i) goto again;
145 finish:;
146 j++;
147 if(j>51)j=51;
148 s[j]='\0';
149 }
150
alsa_get_dev_names(int n)151 int alsa_get_dev_names(int n)
152 {
153 //This routine returns alsa_dev_hw_pcm_name
154 // alsa_dev_plughw_pcm_name
155 // alsa_dev_soundcard_name
156 // alsa_dev_name
157 // alsa_dev_seq_nmbr
158 //for a valid sequence number n on input.
159 //This routine is not "thread safe"
160 //n must be positive and less than MAX_ALSADEV
161
162 //Returncode is negative if n invalid,
163 // if alsa errors
164 // if no device found for input sequence number.
165 snd_ctl_t *handle;
166 snd_ctl_card_info_t *info;
167 snd_pcm_info_t *pcminfo;
168
169 int err, idx, dev, dev_seq_nmbr;
170 char str[128];
171 int retcode;
172
173 alsa_dev_seq_nmbr=0;
174 sprintf(alsa_dev_hw_pcm_name ," ");
175 sprintf(alsa_dev_plughw_pcm_name," ");
176 sprintf(alsa_dev_soundcard_name," ");
177 sprintf(alsa_dev_name," ");
178 idx=-1;
179 dev_seq_nmbr=0;
180 retcode=-10;
181 if(n < 0 || n >= MAX_ALSADEV)
182 {
183 retcode=-6;
184 goto exit_3;
185 }
186 snd_ctl_card_info_malloc(&info);
187 snd_pcm_info_malloc(&pcminfo);
188 while (1) // loop trough all cards
189 {
190 err=snd_card_next(&idx);
191 if(err < 0)
192 {
193 SNDLOG"alsa_get_dev_names:snd_card_next error: %s\n", snd_strerror(err));
194 retcode=-5;
195 goto exit_2;
196 }
197 if(idx < 0) // no more cards available
198 {
199 SNDLOG"alsa_get_dev_pcm_name:end of available card/devices reached\n");
200 retcode=-1;
201 goto exit_2;
202 }
203 sprintf(str, "hw:CARD=%i", idx);
204 SNDLOG"Testing %s\n",str);
205 err=snd_ctl_open( &handle, str, 0);
206 if(err < 0)
207 {
208 SNDLOG"alsa_get_dev_names:snd_ctl_open error: %s\n", snd_strerror(err));
209 retcode=-4;
210 goto exit_2;
211 }
212 err=snd_ctl_card_info(handle, info);
213 if(err < 0)
214 {
215 SNDLOG"alsa_get_dev_names:HW info error: %s\n", snd_strerror(err));
216 retcode=-3;
217 goto exit_1;
218 }
219 dev=-1;
220 while (1) // loop trough all devices for this card
221 {
222 err=snd_ctl_pcm_next_device(handle, &dev);
223 if(err < 0)
224 {
225 SNDLOG"alsa_get_dev_names:PCM next device error: %s\n", snd_strerror(err));
226 retcode=-2;
227 goto exit_1;
228 }
229 if(dev < 0) // no more devices available for this card, get next card
230 {
231 snd_ctl_close(handle);
232 break;
233 }
234 // check first if device has valid pcminfo,
235 //if not, go to next device without incrementing dev seq nmbr
236 snd_pcm_info_set_device(pcminfo, (unsigned int)dev);
237 snd_pcm_info_set_subdevice(pcminfo, 0);
238 snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
239 if((err=snd_ctl_pcm_info(handle, pcminfo))<0)
240 {
241 snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
242 if((err=snd_ctl_pcm_info(handle, pcminfo))<0) goto next_device;
243 }
244 //if valid, check if match with n
245 if(dev_seq_nmbr == n)
246 {
247 // if match with n, get all device name-info and exit loop
248 alsa_dev_seq_nmbr=dev_seq_nmbr;
249 sprintf(alsa_dev_hw_pcm_name ,"hw:%i,%i", idx,dev);
250 sprintf(alsa_dev_plughw_pcm_name,"plughw:%i,%i", idx,dev);
251 snd_pcm_info_set_device(pcminfo, (unsigned int)dev);
252 snd_pcm_info_set_subdevice(pcminfo, 0);
253 snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
254 err=snd_ctl_pcm_info(handle, pcminfo);
255 if(err==0)
256 {
257 sprintf(alsa_dev_name," %s, %s",snd_ctl_card_info_get_name(info),snd_pcm_info_get_id(pcminfo));
258 }
259 else
260 {
261 snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
262 err=snd_ctl_pcm_info(handle, pcminfo);
263 if(err==0)
264 {
265 sprintf(alsa_dev_name," %s, %s",snd_ctl_card_info_get_name(info),snd_pcm_info_get_id(pcminfo));
266 }
267 else
268 {
269 SNDLOG"alsa_get_dev_names:snd_ctl_pcm_info error: %s\n", snd_strerror(err));
270 retcode=-7;
271 goto exit_1;
272 }
273 }
274 sprintf(alsa_dev_soundcard_name," %s",snd_ctl_card_info_get_longname(info));
275 edit_soundcard_name(alsa_dev_soundcard_name);
276 SNDLOG"device found: alsa_dev_plughw_pcm_name=%s \n", alsa_dev_plughw_pcm_name);
277 retcode=0;
278 goto exit_1;
279 }
280 // if no match with n, increment seq nbr of valid devices
281 dev_seq_nmbr= dev_seq_nmbr+1;
282 //get next device
283 next_device:;
284 } // end while loop through devices
285 } // end while loop through cards
286 exit_1:;
287 snd_ctl_close(handle);
288 exit_2:;
289 snd_ctl_card_info_free(info);
290 snd_pcm_info_free (pcminfo);
291 exit_3:;
292 SNDLOG"(alsa_get_dev_pcm_name: n=%i, retcode =%d) \n\n",n,retcode);
293 return retcode;
294 }
295
296
alsar_get_dev_pcm_names(int n,void * al_dev_plughw_pcm_name,void * al_dev_hw_pcm_name)297 int alsar_get_dev_pcm_names (int n,
298 void *al_dev_plughw_pcm_name,
299 void *al_dev_hw_pcm_name )
300 {
301 //Threadsafe version of alsa_get_dev_names
302 //with limited functionality:
303 //This routine returns only dev_plughw_pcm_name and dev_hw_pcm_name
304 //for a valid sequence number n on input.
305 //n must be positive and less than MAX_ALSADEV
306 //Returncode is negative if n invalid,
307 // if alsa errors
308 // if no device found for input sequence number.
309 snd_ctl_t *handle;
310 snd_ctl_card_info_t *info;
311 snd_pcm_info_t *pcminfo;
312 int err, idx, dev, dev_seq_nmbr;
313 char str[128];
314 int retcode ;
315 retcode=-10;
316 alsa_dev_seq_nmbr=0;
317 sprintf((char *)(al_dev_plughw_pcm_name)," ");
318 sprintf((char *)(al_dev_hw_pcm_name)," ");
319 if(n < 0 || n >= MAX_ALSADEV)
320 {
321 retcode=-6;
322 goto exit_3;
323 }
324 idx=-1;
325 dev_seq_nmbr=0;
326 snd_ctl_card_info_malloc(&info);
327 snd_pcm_info_malloc(&pcminfo);
328 while (1) // loop through cards
329 {
330 err=snd_card_next(&idx);
331 if(err < 0)
332 {
333 SNDLOG"alsar_get_dev_pcm_name:snd_card_next error: %s\n", snd_strerror(err));
334 retcode=-5;
335 goto exit_2;
336 }
337 if(idx < 0) // no more cards available
338 {
339 SNDLOG"alsar_get_dev_pcm_name:end of available card/devices reached\n");
340 retcode=-1;
341 goto exit_2;
342 }
343 sprintf(str, "hw:CARD=%i", idx);
344 SNDLOG"Testing %s\n",str);
345 err=snd_ctl_open( &handle, str, 0);
346 if(err < 0)
347 {
348 SNDLOG"alsar_get_dev_pcm_name:snd_ctl_open error: %s\n", snd_strerror(err));
349 retcode=-4;
350 goto exit_2;
351 }
352 err=snd_ctl_card_info(handle, info);
353 if(err < 0)
354 {
355 SNDLOG"alsar_get_dev_pcm_name:HW info error: %s\n", snd_strerror(err));
356 retcode=-3;
357 goto exit_1;
358 }
359 dev=-1;
360 while (1) // loop through all devices for this card
361 {
362 err=snd_ctl_pcm_next_device(handle, &dev);
363 if(err < 0)
364 {
365 SNDLOG"alsar_get_dev_pcm_name:PCM next device error: %s\n", snd_strerror(err));
366 retcode=-2;
367 goto exit_1;
368 }
369 if(dev < 0) // no more devices available for this card
370 {
371 snd_ctl_close(handle);
372 break;
373 }
374 // check first if device has valid pcminfo,
375 //if not, go to next device without incrementing dev seq nmbr
376 snd_pcm_info_set_device(pcminfo, (unsigned int)dev);
377 snd_pcm_info_set_subdevice(pcminfo, 0);
378 snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_CAPTURE);
379 err=snd_ctl_pcm_info(handle, pcminfo);
380 if(err<0)
381 {
382 snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK);
383 err=snd_ctl_pcm_info(handle, pcminfo);
384 if(err<0) goto next_device;
385 }
386
387 //if valid, check if match with n
388 if(dev_seq_nmbr == n)
389 {
390 // if match with n, get limited device name-info and exit loop
391 alsa_dev_seq_nmbr=dev_seq_nmbr;
392 sprintf((char*)(al_dev_hw_pcm_name) ,"hw:%i,%i", idx,dev);
393 sprintf((char *)(al_dev_plughw_pcm_name),"plughw:%i,%i", idx,dev);
394 SNDLOG"device found: dev_plughw_pcm_name=%s\n",((char *)(al_dev_plughw_pcm_name)));
395 retcode=0;
396 goto exit_1;
397 }
398 // if no match with n, increment seq nmbr of valid devices
399 dev_seq_nmbr= dev_seq_nmbr+1;
400 // get next_device
401 next_device:;
402 } // end while loop through devices
403 } // end while loop through cards
404 exit_1:;
405 snd_ctl_close(handle);
406 exit_2:;
407 snd_ctl_card_info_free(info);
408 snd_pcm_info_free (pcminfo);
409 exit_3:;
410 SNDLOG"(alsar_get_dev_pcm_name: n=%i, retcode =%d) \n\n",n,retcode);
411 return retcode;
412 }
413
414
415
alsa_get_dev_native_capabilities(int n,int mode)416 int alsa_get_dev_native_capabilities(int n,int mode)
417 {
418 // This single threaded routine returns the native hw capabilities of a given
419 // soundcard/device n, in either capture or playback mode (mode input parameter).
420 // This is done by opening the device with a pcm_name=hw:n,0 and
421 // querying hw_params
422 // Returncode is negative if
423 // device does not exist
424 // alsa error
425
426 snd_pcm_t *wk_handle;
427 snd_pcm_hw_params_t *hw_params;
428 unsigned int val;
429 int err, dir;
430
431 dir=0;
432 alsa_dev_min_rate[n]=0;
433 alsa_dev_max_rate[n]=0;
434 alsa_dev_min_channels=0;
435 alsa_dev_max_channels=0;
436 alsa_dev_min_bytes=0;
437 alsa_dev_max_bytes=0;
438
439 if((err=alsa_get_dev_names (n)) < 0 ) {
440 SNDLOG"alsa_get_dev_native_capabilities: alsa_get_dev_id failed\n" );
441 return -1;
442 }
443 if((err=snd_pcm_open(&wk_handle, alsa_dev_hw_pcm_name, mode, 0)) < 0) {
444 SNDLOG"alsa_get_dev_native_capabilities: open failed,%s\n",alsa_dev_hw_pcm_name );
445 return -2;
446 }
447 if((err=snd_pcm_hw_params_malloc(&hw_params)) < 0) {
448 SNDLOG"alsa_get_dev_native_capabilities: snd_pcm_hw_params_malloc failed\n" );
449 snd_pcm_close(wk_handle);
450 return -3;
451 }
452 if((err=snd_pcm_hw_params_any(wk_handle, hw_params)) < 0) {
453 SNDLOG"alsa_get_dev_native_capabilities: snd_pcm_hw_params_any failed\n" );
454 snd_pcm_hw_params_free (hw_params);
455 snd_pcm_close(wk_handle);
456 return -4;
457 }
458 // get sampling rate
459 if((err= snd_pcm_hw_params_get_rate_max (hw_params, &val, &dir)) < 0){
460 SNDLOG"alsa_get_dev_native_capabilities: snd_pcm_hw_params_get_rate_max failed\n" );
461 snd_pcm_hw_params_free (hw_params);
462 snd_pcm_close(wk_handle);
463 return -5;
464 }
465 alsa_dev_max_rate[n]=(int)val;
466
467 if((err= snd_pcm_hw_params_get_rate_min (hw_params, &val, &dir)) < 0) {
468 SNDLOG"alsa_get_dev_native_capabilities: snd_pcm_hw_params_get_rate_min failed\n" );
469 snd_pcm_hw_params_free (hw_params);
470 snd_pcm_close(wk_handle);
471 return -6;
472 }
473 alsa_dev_min_rate[n]=(int)val;
474
475 // get # channels
476 if((err= snd_pcm_hw_params_get_channels_max(hw_params, &val)) < 0) {
477 SNDLOG"alsa_get_dev_native_capabilities: snd_pcm_hw_params_get_channels_max failed\n" );
478 snd_pcm_hw_params_free (hw_params);
479 snd_pcm_close(wk_handle);
480 return -7;
481 }
482 alsa_dev_max_channels=(int)val;
483
484 if((err= snd_pcm_hw_params_get_channels_min(hw_params, &val)) < 0){
485 SNDLOG"alsa_get_dev_native_capabilities: snd_pcm_hw_params_get_channels_min failed\n" );
486 snd_pcm_hw_params_free (hw_params);
487 snd_pcm_close(wk_handle);
488 return -8;
489 }
490 alsa_dev_min_channels=(int)val;
491
492 // get min # of bytes
493 if((err=snd_pcm_hw_params_test_format (wk_handle, hw_params,SND_PCM_FORMAT_U8)) == 0)
494 {
495 alsa_dev_min_bytes=1;
496 }
497 else
498 {
499 if((err=snd_pcm_hw_params_test_format (wk_handle, hw_params,SND_PCM_FORMAT_S16_LE)) == 0)
500 {
501 alsa_dev_min_bytes=2;
502 }
503 else
504 {
505 if((err=snd_pcm_hw_params_test_format (wk_handle, hw_params,SND_PCM_FORMAT_S32_LE)) == 0)
506 {
507 alsa_dev_min_bytes=4;
508 }
509 else {
510 SNDLOG"alsa_get_dev_native_capabilities: snd_pcm_hw_params_test_format failed\n" );
511 //probably an alsa error, assume 2 bytes
512 alsa_dev_min_bytes=2;
513 }
514 }
515 }
516 // get max # of bytes
517 if((err=snd_pcm_hw_params_test_format (wk_handle, hw_params,SND_PCM_FORMAT_S32_LE)) == 0)
518 {
519 alsa_dev_max_bytes=4;
520 }
521 else
522 {
523 if((err=snd_pcm_hw_params_test_format (wk_handle, hw_params,SND_PCM_FORMAT_S16_LE)) == 0)
524 {
525 alsa_dev_max_bytes=2;
526 }
527 else
528 {
529 if((err=snd_pcm_hw_params_test_format (wk_handle, hw_params,SND_PCM_FORMAT_U8)) == 0)
530 {
531 alsa_dev_max_bytes=1;
532 }
533 else{
534 SNDLOG"alsa_get_dev_native_capabilities: snd_pcm_hw_params_test_format failed\n" );
535 //probably an alsa error, assume 2 bytes
536 alsa_dev_max_bytes=2;
537 }
538 }
539 }
540 snd_pcm_hw_params_free (hw_params);
541 snd_pcm_close(wk_handle);
542 return 0;
543 }
544
alsar_get_dev_native_capabilities(int n,int mode,int * al_dev_min_rate,int * al_dev_max_rate,int * al_dev_min_channels,int * al_dev_max_channels,int * al_dev_min_bytes,int * al_dev_max_bytes)545 int alsar_get_dev_native_capabilities(int n,
546 int mode,
547 int *al_dev_min_rate,
548 int *al_dev_max_rate,
549 int *al_dev_min_channels,
550 int *al_dev_max_channels,
551 int *al_dev_min_bytes,
552 int *al_dev_max_bytes
553 )
554 {
555 // threadsafe version of alsa_get_dev_native_capabilities
556 // This routine returns the native hw capabilities of a given
557 // soundcard/device n, in capture or playback mode (mode input parameter).
558 // This is done by opening the device with a pcm_name=hw:n,0 and
559 // querying hw_params
560 // Returncode is negative if
561 // device does not exist
562 // alsa error
563
564 snd_pcm_t *wk_handle;
565 snd_pcm_hw_params_t *hw_params;
566 unsigned int val;
567 int err, dir;
568 char dev_plughw_pcm_name[MAX_ALSADEV];
569 char dev_hw_pcm_name[MAX_ALSADEV];
570
571 dir=0;
572
573 *al_dev_min_rate=0;
574 *al_dev_max_rate=0;
575 *al_dev_min_channels=0;
576 *al_dev_max_channels=0;
577 *al_dev_min_bytes=0;
578 *al_dev_max_bytes=0;
579
580 //check if valid device
581 if (( alsar_get_dev_pcm_names(n,dev_plughw_pcm_name,dev_hw_pcm_name))< 0 )
582 {
583 SNDLOG"alsar_get_dev_native_capabilities: alsar_get_dev_plughw_pcm_name failed\n" );
584 return -1;
585 }
586 if((err=snd_pcm_open(&wk_handle, dev_hw_pcm_name, mode, 0)) < 0) {
587 SNDLOG"alsar_get_dev_native_capabilities: open failed,%s\n",dev_hw_pcm_name );
588 return -2;
589 }
590 if((err=snd_pcm_hw_params_malloc (&hw_params)) < 0) {
591 SNDLOG"alsar_get_dev_native_capabilities: snd_pcm_hw_params_malloc failed\n" );
592 snd_pcm_close(wk_handle);
593 return -3;
594 }
595 if((err=snd_pcm_hw_params_any(wk_handle, hw_params)) < 0) {
596 SNDLOG"alsar_get_dev_native_capabilities: snd_pcm_hw_params_any failed\n" );
597 snd_pcm_hw_params_free (hw_params);
598 snd_pcm_close(wk_handle);
599 return -4;
600 }
601 // get max sampling rate
602 if((err= snd_pcm_hw_params_get_rate_max (hw_params, &val, &dir)) < 0){
603 SNDLOG"alsar_get_dev_native_capabilities: snd_pcm_hw_params_get_rate_max failed\n" );
604 snd_pcm_hw_params_free (hw_params);
605 snd_pcm_close(wk_handle);
606 return -5;
607 }
608 *al_dev_max_rate=(int)val;
609
610 // get min sampling rate
611 if((err= snd_pcm_hw_params_get_rate_min (hw_params, &val, &dir)) < 0) {
612 SNDLOG"alsar_get_dev_native_capabilities: snd_pcm_hw_params_get_rate_min failed\n" );
613 snd_pcm_hw_params_free (hw_params);
614 snd_pcm_close(wk_handle);
615 return -6;
616 }
617 *al_dev_min_rate=(int)val;
618
619 // get max # channels
620 if((err= snd_pcm_hw_params_get_channels_max(hw_params, &val)) < 0) {
621 SNDLOG"alsar_get_dev_native_capabilities: snd_pcm_hw_params_get_channels_max failed\n" );
622 snd_pcm_hw_params_free (hw_params);
623 snd_pcm_close(wk_handle);
624 return -4;
625 }
626 *al_dev_max_channels=(int)val;
627
628 // get min # channels
629 if((err= snd_pcm_hw_params_get_channels_min(hw_params, &val)) < 0){
630 SNDLOG"alsar_get_dev_native_capabilities: snd_pcm_hw_params_get_channels_min failed\n" );
631 snd_pcm_hw_params_free (hw_params);
632 snd_pcm_close(wk_handle);
633 return -8;
634 }
635 *al_dev_min_channels=(int)val;
636
637 // get min # of bytes
638 if((err=snd_pcm_hw_params_test_format (wk_handle, hw_params,SND_PCM_FORMAT_U8)) == 0)
639 {
640 *al_dev_min_bytes=1;
641 }
642 else
643 {
644 if((err=snd_pcm_hw_params_test_format (wk_handle, hw_params,SND_PCM_FORMAT_S16_LE)) == 0)
645 {
646 *al_dev_min_bytes=2;
647 }
648 else
649 {
650 if((err=snd_pcm_hw_params_test_format (wk_handle, hw_params,SND_PCM_FORMAT_S32_LE)) == 0)
651 {
652 *al_dev_min_bytes=4;
653 }
654 else {
655 SNDLOG"alsar_get_dev_native_capabilities: snd_pcm_hw_params_test_format failed\n" );
656 //probably an alsa error, assume 2 bytes
657 *al_dev_min_bytes=2;
658 }
659 }
660 }
661 // get max # of bytes
662 if((err=snd_pcm_hw_params_test_format (wk_handle, hw_params,SND_PCM_FORMAT_S32_LE)) == 0)
663 {
664 *al_dev_max_bytes=4;
665 }
666 else
667 {
668 if((err=snd_pcm_hw_params_test_format (wk_handle, hw_params,SND_PCM_FORMAT_S16_LE)) == 0)
669 {
670 *al_dev_max_bytes=2;
671 }
672 else
673 {
674 if((err=snd_pcm_hw_params_test_format (wk_handle, hw_params,SND_PCM_FORMAT_U8)) == 0)
675 {
676 *al_dev_max_bytes=1;
677 }
678 else{
679 SNDLOG"alsar_get_dev_native_capabilities: snd_pcm_hw_params_test_format failed\n" );
680 //probably an alsa error, assume 2 bytes
681 *al_dev_max_bytes=2;
682 }
683 }
684 }
685 snd_pcm_hw_params_free (hw_params);
686 snd_pcm_close(wk_handle);
687 return 0;
688 }
689
alsa_get_native_samplerate(int n,int mode,int * line,unsigned int * returned_sampling_rate)690 int alsa_get_native_samplerate (int n,
691 int mode,
692 int *line,
693 unsigned int *returned_sampling_rate)
694 {
695 (void) line;
696 (void) returned_sampling_rate;
697 int err,i,k,id;
698 unsigned int val;
699 char s[80];
700 char dev_hw_pcm_name[MAX_ALSADEV];
701 char dev_plughw_pcm_name[MAX_ALSADEV];
702 unsigned int native_sampling_rate[MAX_ALSADEV];
703 snd_pcm_t *wk_handle;
704 snd_pcm_hw_params_t *hw_params;
705 // 0 terminated list
706 static unsigned int standardSampleRates[] = {8000, 9600,
707 11025, 12000, 16000, 22050, 24000, 32000,
708 44100, 48000, 50000,88200, 96000, 119466, 192000,
709 224000, 448000, 0};
710 unsigned int sample_rates[32];
711 unsigned int smin, smax;
712 err=alsar_get_dev_pcm_names(n,dev_plughw_pcm_name,dev_hw_pcm_name);
713 if (err!=0) return -1;
714 err=snd_pcm_hw_params_malloc (&hw_params);
715 if (err!=0) return -2;
716 err=snd_pcm_open(&wk_handle, dev_hw_pcm_name, mode, 0);
717 if (err!=0)
718 {
719 snd_pcm_hw_params_free (hw_params);
720 return -3;
721 }
722 clear_screen();
723 line[0]=2;
724 sprintf(s,"This is a native ALSA device.");
725 lir_text(1,line[0], s);
726 line[0]+=1;
727 sprintf(s,"Select sampling rate by line number from list:");
728 lir_text(1,line[0], s);
729 line[0]+=2;
730 i=0;
731 smin=alsa_dev_min_rate[n];
732 smax=alsa_dev_max_rate[n];
733 if(smin == smax)
734 {
735 smin=0;
736 }
737 while(standardSampleRates[i] != 0 )
738 {
739 if(smax == standardSampleRates[i])smax=0;
740 if(smin == standardSampleRates[i])smin=0;
741 sample_rates[i]=standardSampleRates[i];
742 i++;
743 }
744 if(smin != 0)
745 {
746 sample_rates[i]=smin;
747 i++;
748 }
749 if(smax > 0)
750 {
751 sample_rates[i]=smax;
752 i++;
753 }
754 sample_rates[i]=0;
755 i=0;
756 k=0;
757 while(sample_rates[i] != 0 )
758 {
759 val=(unsigned int)sample_rates[i];
760 err=snd_pcm_hw_params_any(wk_handle, hw_params);
761 if (err!=0)
762 {
763 snd_pcm_close(wk_handle);
764 snd_pcm_hw_params_free (hw_params);
765 return -4;
766 }
767 err=snd_pcm_hw_params_set_rate(wk_handle,hw_params,val, 0);
768 if(err == 0)
769 {
770 sprintf(s,"%2d -> %6d ",k,val);
771 lir_text(1,line[0],s);
772 native_sampling_rate[k]= val;
773 line[0]++;
774 k++;
775 }
776 i++;
777 }
778 line[0]++;
779 sprintf(s,"Enter line number >");
780 lir_text(1,line[0],s);
781 id=lir_get_integer(21,line[0],2, 0, k-1);
782 *returned_sampling_rate=native_sampling_rate[id];
783 snd_pcm_close(wk_handle);
784 snd_pcm_hw_params_free (hw_params);
785 return 0;
786 }
787
select_alsadev(int open_mode,int * line)788 int select_alsadev(int open_mode, int *line)
789 {
790 //display available devices for a specific mode and return sequence number of selected device
791 char s[200];
792 int i, err;
793 line[0]++;
794 sprintf(s,"device soundcard-device-name device sample-rate channels bytes");
795 SNDLOG"%s\n",s);
796 lir_text(0,line[0],s);
797 line[0]++;
798 sprintf(s,"seq-no (soundcard-name) pcm-name min / max min/max min/max");
799 SNDLOG"%s\n",s);
800 lir_text(0,line[0],s);
801 line[0]++;
802 sprintf(s,"------ -------------------------------------------------- ---------- ----------- ------- ------- " );
803 SNDLOG"%s\n",s);
804 lir_text(0,line[0],s);
805 line[0]++;
806 for(i=0; i<MAX_ALSADEV; i++)
807 {
808 err=alsa_get_dev_names(i);
809 if(err == -1) goto end_alsa_get_dev_names;
810 if(err == 0)
811 {
812 err=alsa_get_dev_native_capabilities(i, open_mode);
813 if(err == 0)
814 {
815 line[0]++;
816 sprintf(s,"%i", alsa_dev_seq_nmbr);
817 lir_text(2,line[0],s);
818 sprintf(s,"%s", alsa_dev_name);
819 lir_text(6,line[0],s);
820 sprintf(s,"(%s)", alsa_dev_soundcard_name);
821 lir_text(20,line[0]+1,s);
822 sprintf(s,"%s", alsa_dev_plughw_pcm_name);
823 lir_text(59,line[0],s);
824 sprintf(s,"%i/%i", alsa_dev_min_rate[i], alsa_dev_max_rate[i]);
825 lir_text(72,line[0],s);
826 sprintf(s,"%i/%i ", alsa_dev_min_channels, alsa_dev_max_channels);
827 lir_text(86,line[0],s);
828 sprintf(s,"%i/%i ", alsa_dev_min_bytes, alsa_dev_max_bytes);
829 lir_text(96,line[0],s);
830 sprintf(s," %i %s (%s) %s %i/%i %i/%i %i/%i ",
831 alsa_dev_seq_nmbr, alsa_dev_name, alsa_dev_soundcard_name,
832 alsa_dev_plughw_pcm_name, alsa_dev_min_rate[i],
833 alsa_dev_max_rate[i],alsa_dev_min_channels,
834 alsa_dev_max_channels, alsa_dev_min_bytes,
835 alsa_dev_max_bytes );
836 line[0]+=2;
837 SNDLOG"%s\n",s);
838 }
839 }
840 }
841 end_alsa_get_dev_names:;
842 again:;
843 sprintf(s,"Enter selected device-seq-nmbr >" );
844 SNDLOG"%s\n",s);
845 line[0]=line[0]+2;
846 lir_text(0,line[0],s);
847 i=lir_get_integer(33, line[0], 2, 0,MAX_ALSADEV-1);
848 if(kill_all_flag)return -1;
849 sprintf(s,"User selected %i",i);
850 SNDLOG"%s\n",s);
851 err=alsa_get_dev_names (i);
852 if(err < 0)
853 {
854 lir_text(37,line[0],"invalid device-seq-nmbr, try again");
855 sprintf(s,"invalid device-seq-nmbr, try again");
856 SNDLOG"%s\n",s);
857 goto again;
858 }
859 err=alsa_get_dev_native_capabilities(i,open_mode);
860 if(err != 0)
861 {
862 lir_text(37,line[0],"incompatible capabilities, try again");
863 sprintf(s,"incompatible capabilities, try again");
864 SNDLOG"%s\n",s);
865 goto again;
866 }
867 lir_text(37,line[0],blanks);
868 line[0]++;
869 return i;
870 }
871
chk_open_alsa(int no,int bytes,int speed,int channels,int mode)872 int chk_open_alsa(int no, int bytes, int speed, int channels, int mode)
873 {
874 int err;
875 char dev_plughw_pcm_name[MAX_ALSADEV];
876 char dev_hw_pcm_name[MAX_ALSADEV];
877
878 int al_dev_min_rate;
879 int al_dev_max_rate;
880 int al_dev_min_channels;
881 int al_dev_max_channels;
882 int al_dev_min_bytes;
883 int al_dev_max_bytes;
884 //check if device exists
885 err= alsar_get_dev_pcm_names(no,dev_plughw_pcm_name,dev_hw_pcm_name);
886 if( err < 0 )return -1;
887 //check capabilities of device
888 err=alsar_get_dev_native_capabilities( no,
889 mode,
890 &al_dev_min_rate,
891 &al_dev_max_rate,
892 &al_dev_min_channels,
893 &al_dev_max_channels,
894 &al_dev_min_bytes,
895 &al_dev_max_bytes);
896 if( err != 0 )return -2;
897 if( speed < al_dev_min_rate )return -4;
898 if( speed > al_dev_max_rate )return -5;
899 if( channels > al_dev_max_channels )return -7;
900 if( bytes < al_dev_min_bytes )return -8;
901 if( bytes > al_dev_max_bytes )return -9;
902 return 0;
903 }
904
alsa_errors(int err)905 void alsa_errors(int err)
906 {
907 char s[80];
908 switch (err)
909 {
910 case EIO:
911 lirerr(1169);
912 return;
913
914 default:
915 sprintf(s,"ALSA error code: %d",err);
916 clear_screen();
917 lir_text(0,0,s);
918 lir_text(0,2,press_any_key);
919 await_keyboard();
920 lirerr(1127);
921 return;
922 }
923 }
924
925
926
alsaread(snd_pcm_t * handle,char * buf,snd_pcm_uframes_t frames)927 int alsaread(snd_pcm_t *handle, char *buf, snd_pcm_uframes_t frames)
928 {
929 int k, err;
930 xx:;
931 err=snd_pcm_readi(handle, buf, frames);
932 if(kill_all_flag)return FALSE;
933 k=0;
934 if((unsigned int)err != frames)
935 {
936 if(err == -EPIPE) // EPIPE, try recovery
937 {
938 k++;
939 err= snd_pcm_recover(handle, err, 0);
940 if(err < 0)
941 {
942 lirerr(1108); // recovery failed
943 return FALSE;
944 }
945 lir_sleep(3000);
946 if(k < 5)goto xx;
947 return FALSE;
948 }
949 else
950 {
951 if(err < 0)
952 {
953 alsa_errors(-err);
954 return FALSE;
955 }
956 else
957 {
958 // We had a short read. Wait for the device to recover.
959 // Then read remaining bytes.
960 k=err;
961 err=0;
962 while(err == 0)
963 {
964 // Split the wait in 100 ms intervals and check whether ESC has
965 // been pressed. In case the CPU is really busy we could be
966 // waiting here for a very long time.
967 err=snd_pcm_wait(handle, 100);
968 lir_sched_yield();
969 if(kill_all_flag)return FALSE;
970 }
971 if(err > 0)
972 {
973 read_more:;
974 err=snd_pcm_readi(handle, &buf[k], frames-(long unsigned int)k);
975 }
976 if((unsigned int)err != frames-(long unsigned int)k)
977 {
978 if(err == -EPIPE) // EPIPE, try recovery
979 {
980 err= snd_pcm_recover(handle, err, 0);
981 if(err < 0)lirerr(1108); // recovery failed
982 return FALSE;
983 }
984 else
985 {
986 if(err < 0)
987 {
988 alsa_errors(-err);
989 return FALSE;
990 }
991 else
992 {
993 k+=err;
994 goto read_more;
995 }
996 }
997 }
998 }
999 }
1000 }
1001 return TRUE;
1002 }
1003
1004 #endif
1005
lir_tx_adread(char * buf)1006 void lir_tx_adread(char *buf)
1007 {
1008 #if (ALSA_PRESENT == 1)
1009 int err;
1010 char s[40];
1011 #endif
1012 int nread;
1013 #if (ALSA_PRESENT == 1)
1014 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
1015 {
1016 err=alsaread(tx_ad_handle, buf, (snd_pcm_uframes_t) snd[TXAD].block_frames);
1017 if(err == FALSE)
1018 {
1019 no_of_tx_overrun_errors++;
1020 sprintf(s,"TX%s%d",overrun_error_msg,no_of_tx_overrun_errors);
1021 wg_error(s,WGERR_TXIN);
1022 }
1023 }
1024 else
1025 #endif
1026 {
1027 nread=read(tx_audio_in, buf, (size_t)snd[TXAD].block_bytes);
1028 if(nread != snd[TXAD].block_bytes)lirerr(1283);
1029 }
1030 }
1031
thread_rx_adinput(void)1032 void thread_rx_adinput(void)
1033 {
1034 #if RUSAGE_OLD == TRUE
1035 int local_workload_counter;
1036 #endif
1037 double read_start_time,total_reads;
1038 short int *rxin_isho2;
1039 int *rxin_int1, *rxin_int2;
1040 int rxin_local_workload_reset;
1041 #if (ALSA_PRESENT == 1)
1042 int err;
1043 char s[40];
1044 #endif
1045 int i;
1046 int timing_loop_counter,timing_loop_counter_max,initial_skip_flag;
1047 #if OSNUM == OSNUM_LINUX
1048 fix_prio(THREAD_RX_ADINPUT);
1049 clear_thread_times(THREAD_RX_ADINPUT);
1050 #endif
1051 #if RUSAGE_OLD == TRUE
1052 local_workload_counter=workload_counter;
1053 #endif
1054 // Open the hware_command thread in case we are using the WSE units.
1055 if( allow_wse_parport != 0)
1056 {
1057 linrad_thread_create(THREAD_HWARE_COMMAND);
1058 }
1059 if(screen_loop_counter_max==0)screen_loop_counter_max=1;
1060
1061 if(thread_command_flag[THREAD_SCREEN] != THRFLAG_NOT_ACTIVE)
1062 {
1063 while(thread_status_flag[THREAD_SCREEN]!=THRFLAG_ACTIVE &&
1064 thread_status_flag[THREAD_SCREEN]!=THRFLAG_IDLE &&
1065 thread_status_flag[THREAD_SCREEN]!=THRFLAG_SEM_WAIT)
1066 {
1067 if(thread_command_flag[THREAD_RX_ADINPUT] ==
1068 THRFLAG_KILL)goto rx_adin_init_error;
1069 lir_sleep(10000);
1070 }
1071 }
1072 sys_func(THRFLAG_OPEN_RX_SNDIN);
1073 if(kill_all_flag) goto rx_adin_init_error;
1074 if(lir_rxin_status != LIR_OK)goto rx_adin_init_error;
1075 update_extio_rx_freq();
1076 update_extio_rx_gain();
1077 #include "timing_setup.c"
1078 thread_status_flag[THREAD_RX_ADINPUT]=THRFLAG_ACTIVE;
1079 while(!kill_all_flag &&
1080 thread_command_flag[THREAD_RX_ADINPUT] == THRFLAG_ACTIVE)
1081 {
1082 #include "input_speed.c"
1083 #if RUSAGE_OLD == TRUE
1084 if(local_workload_counter != workload_counter)
1085 {
1086 local_workload_counter=workload_counter;
1087 make_thread_times(THREAD_RX_ADINPUT);
1088 }
1089 #endif
1090 if ( (ui.use_alsa&PORTAUDIO_RX_IN) != 0)
1091 {
1092 rxin_isho=(short int*)(&timf1_char[timf1p_pa]);
1093 pa_rx_input();
1094 }
1095 else
1096 {
1097 rxin_isho=(short int*)(&timf1_char[timf1p_pa]);
1098 if(ui.rx_addev_no < 256)
1099 {
1100 #if (ALSA_PRESENT == 1)
1101 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
1102 {
1103 err=alsaread(rx_ad_handle,
1104 (char*)rxin_isho, (snd_pcm_uframes_t)snd[RXAD].block_frames);
1105 if(kill_all_flag) goto rxadin_error_exit;
1106 if(err == FALSE)
1107 {
1108 no_of_rx_overrun_errors++;
1109 sprintf(s,"RX%s%d",overrun_error_msg,no_of_rx_overrun_errors);
1110 wg_error(s,WGERR_RXIN);
1111 }
1112 }
1113 else
1114 #endif
1115 {
1116 zrw=read(rx_audio_in, rxin_isho, (size_t)snd[RXAD].block_bytes);
1117 }
1118 }
1119 else
1120 {
1121 rxin_isho2=(short int*)(&timf1_char[timf1p_pa]);
1122 zrw=read(rx_audio_in, rxin_isho, (size_t)(snd[RXAD].block_bytes>>1));
1123 zrw=read(rx_audio_in2, rxin_isho2, (size_t)(snd[RXAD].block_bytes>>1));
1124 if( (ui.rx_input_mode&DWORD_INPUT) == 0)
1125 {
1126 for(i=snd[RXAD].block_frames-1; i>=0; i--)
1127 {
1128 rxin_isho[4*i ]=rxin_isho[2*i ];
1129 rxin_isho[4*i+1]=rxin_isho[2*i+1];
1130 rxin_isho[4*i+2]=rxin_isho2[2*i ];
1131 rxin_isho[4*i+3]=rxin_isho2[2*i+1];
1132 }
1133 }
1134 else
1135 {
1136 rxin_int1=(int*)rxin_isho;
1137 rxin_int2=(int*)rxin_isho2;
1138 for(i=snd[RXAD].block_frames-1; i>=0; i--)
1139 {
1140 rxin_int1[4*i ]=rxin_int1[2*i ];
1141 rxin_int1[4*i+1]=rxin_int1[2*i+1];
1142 rxin_int1[4*i+2]=rxin_int2[2*i ];
1143 rxin_int1[4*i+3]=rxin_int2[2*i+1];
1144 }
1145 }
1146 }
1147 }
1148 finish_rx_read();
1149 if(kill_all_flag) goto rxadin_error_exit;
1150 }
1151 rxadin_error_exit:;
1152 /* Maybe needed with OSS in RDWR mode ????
1153 while( rx_audio_out == rx_audio_in ||
1154 tx_audio_out == rx_audio_in)
1155 {
1156 lir_sleep(10000);
1157 }
1158 */
1159 close_rx_sndin();
1160 rx_adin_init_error:;
1161 if( allow_wse_parport != 0)
1162 {
1163 linrad_thread_stop_and_join(THREAD_HWARE_COMMAND);
1164 }
1165 thread_status_flag[THREAD_RX_ADINPUT]=THRFLAG_RETURNED;
1166 while(thread_command_flag[THREAD_RX_ADINPUT] != THRFLAG_NOT_ACTIVE)
1167 {
1168 lir_sleep(1000);
1169 }
1170 }
1171
thread_test_rxda(void)1172 void thread_test_rxda(void)
1173 {
1174 int i;
1175 genparm[DA_OUTPUT_SPEED]=ui.rx_min_da_speed;
1176 if(genparm[DA_OUTPUT_SPEED] < 8000)genparm[DA_OUTPUT_SPEED]=8000;
1177 rx_daout_bytes=ui.rx_max_da_bytes;
1178 rx_daout_channels=ui.rx_max_da_channels;
1179 snd[RXDA].framesize=rx_daout_bytes*rx_daout_channels;
1180 snd[RXDA].block_frames=(int)((float)genparm[DA_OUTPUT_SPEED]*.025F);
1181 make_power_of_two(&snd[RXDA].block_frames);
1182 snd[RXDA].block_bytes=snd[RXDA].block_frames*snd[RXDA].framesize;
1183 min_delay_time=0.025F;
1184 daout=malloc((size_t)(8*snd[RXDA].block_bytes));
1185 daout_pa=0;
1186 daout_px=0;
1187 for(i=0; i<4*snd[RXDA].block_bytes; i++)
1188 {
1189 daout[daout_pa]=0;
1190 daout_pa++;
1191 }
1192 daout_bufmask=8*snd[RXDA].block_bytes-1;
1193 daout_pa*=2;
1194 open_rx_sndout();
1195 if(kill_all_flag)return;
1196 while(!kill_all_flag &&
1197 soundcard_test_cmd_flag[RXDA] == THRFLAG_ACTIVE)
1198 {
1199 // Write data to the output device.
1200 lir_rx_dawrite();
1201 soundcard_test_block_count[RXDA]++;
1202 }
1203 close_rx_sndout();
1204 free(daout);
1205 }
1206
thread_test_txda(void)1207 void thread_test_txda(void)
1208 {
1209 char *buf;
1210 int i;
1211 snd[TXDA].framesize=ui.tx_da_bytes*ui.tx_da_channels;
1212 snd[TXDA].block_bytes=(1000+ui.tx_da_speed)*snd[TXDA].framesize/1000;
1213 make_power_of_two((int*)&snd[TXDA].block_bytes);
1214 open_tx_sndout();
1215 if(kill_all_flag)return;
1216 buf=malloc((size_t)snd[TXDA].block_bytes);
1217 if(buf == NULL)
1218 {
1219 lirerr(1245231);
1220 return;
1221 }
1222 for(i=0; i<snd[TXDA].block_bytes; i++)
1223 {
1224 buf[i]=0;
1225 }
1226 while(!kill_all_flag &&
1227 soundcard_test_cmd_flag[TXDA] == THRFLAG_ACTIVE)
1228 {
1229 // Write data to the output device.
1230 lir_tx_dawrite(buf);
1231 soundcard_test_block_count[TXDA]++;
1232 }
1233 close_tx_sndout();
1234 free(buf);
1235 }
1236
thread_test_rxad(void)1237 void thread_test_rxad(void)
1238 {
1239 char *buf;
1240 #if (ALSA_PRESENT == 1)
1241 int err;
1242 #endif
1243 snd[RXAD].block_frames=ui.rx_ad_speed/50;
1244 make_power_of_two((int*)(&snd[RXAD].block_frames));
1245 snd[RXAD].interrupt_rate=(float)(ui.rx_ad_speed)/(float)snd[RXAD].block_frames;
1246 snd[RXAD].framesize=2*ui.rx_ad_channels;
1247 if( (ui.rx_input_mode&DWORD_INPUT) != 0) snd[RXAD].framesize*=2;
1248 snd[RXAD].block_bytes=snd[RXAD].framesize*snd[RXAD].block_frames;
1249 timf1_bytes=8*snd[RXAD].block_bytes;
1250 timf1_bytemask=timf1_bytes-1;
1251 timf1_char=malloc((size_t)timf1_bytes);
1252 if(timf1_char==NULL)
1253 {
1254 lirerr(23658);
1255 return;
1256 }
1257 timf1p_sdr=0;
1258 timf1p_pa=0;
1259 open_rx_sndin(FALSE);
1260 if(kill_all_flag)
1261 {
1262 free(timf1_char);
1263 return;
1264 }
1265 buf=malloc((size_t)snd[RXAD].block_bytes);
1266 if(buf == NULL)
1267 {
1268 lirerr(1233231);
1269 free(timf1_char);
1270 return;
1271 }
1272 while(!kill_all_flag && soundcard_test_cmd_flag[RXAD] == THRFLAG_ACTIVE)
1273 {
1274 if ( (ui.use_alsa&PORTAUDIO_RX_IN) != 0)
1275 {
1276 timf1p_pa=(timf1p_pa+snd[RXAD].block_bytes)&timf1_bytemask;
1277 pa_rx_input();
1278 }
1279 else
1280 {
1281 if(ui.rx_addev_no < 256)
1282 {
1283 #if (ALSA_PRESENT == 1)
1284 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
1285 {
1286 err=alsaread(rx_ad_handle, buf,
1287 (snd_pcm_uframes_t)snd[RXAD].block_frames);
1288 if(err != TRUE)
1289 {
1290 lir_text(0,screen_last_line-1,"ERROR");
1291 }
1292 }
1293 else
1294 #endif
1295 {
1296 zrw=read(rx_audio_in, buf, (size_t)snd[RXAD].block_bytes);
1297 }
1298 }
1299 else
1300 {
1301 zrw=read(rx_audio_in, buf, (size_t)(snd[RXAD].block_bytes>>1));
1302 zrw=read(rx_audio_in2, buf, (size_t)(snd[RXAD].block_bytes>>1));
1303 }
1304 }
1305 soundcard_test_block_count[RXAD]++;
1306 }
1307 //*********************ööööööööööööö*********************
1308 //this may be needed in RDWR mode with OSS.
1309 //while( !kill_all_flag &&
1310 // (rx_audio_out == rx_audio_in ||
1311 // tx_audio_out == rx_audio_in))lir_sleep(10000);
1312
1313 close_rx_sndin();
1314 free(timf1_char);
1315 free(buf);
1316 }
1317
lir_tx_output_samples(void)1318 int lir_tx_output_samples(void)
1319 {
1320 #if (ALSA_PRESENT == 1)
1321 int err;
1322 char s[40];
1323 snd_pcm_sframes_t frame_avail;
1324 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
1325 {
1326 //Try to synchronize stream position with hardware
1327 err=snd_pcm_hwsync(tx_da_handle);
1328 if(err != 0)
1329 {
1330 if(err == -EPIPE) // underrun, try to recover
1331 {
1332 no_of_tx_underrun_errors++;
1333 sprintf(s,"TX%s%d",underrun_error_msg,no_of_tx_underrun_errors);
1334 wg_error(s,WGERR_TXOUT);
1335 snd_pcm_prepare(tx_da_handle);
1336 err=snd_pcm_hwsync(tx_da_handle);
1337 if(err < 0)
1338 {
1339 // lirerr(872315); // accept error, we have to live with less accurate data in frame_avail
1340 }
1341 }
1342 else
1343 {
1344 // lirerr(872316); // accept error, we have to live with less accurate data in frame_avail
1345 }
1346 }
1347 frame_avail= snd_pcm_avail_update(tx_da_handle);
1348 if(frame_avail < 0)
1349 {
1350 // lirerr(872317);
1351 return 0;
1352 }
1353 return (int)(snd[TXDA].tot_frames-frame_avail);
1354 }
1355 else
1356 #endif
1357 {
1358 #if HAVE_OSS == 1
1359 if(ioctl(tx_audio_out,SNDCTL_DSP_GETOSPACE, &tx_da_info) == -1)
1360 lirerr(872313);
1361 return snd[TXDA].tot_frames-tx_da_info.bytes/snd[TXDA].framesize;
1362 #endif
1363 }
1364 return 0;
1365 }
1366
lir_tx_input_samples(void)1367 int lir_tx_input_samples(void)
1368 {
1369 #if (ALSA_PRESENT == 1)
1370 int err;
1371 char s[40];
1372 snd_pcm_sframes_t frame_avail;
1373 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
1374 {
1375 //Synchronize stream position with hardware
1376 err=snd_pcm_hwsync(tx_ad_handle);
1377 {
1378 if(err == -EPIPE) // underrun, try to recover
1379 {
1380 no_of_tx_overrun_errors++;
1381 sprintf(s,"TX%s%d",overrun_error_msg,no_of_tx_overrun_errors);
1382 wg_error(s,WGERR_TXIN);
1383 snd_pcm_prepare(tx_ad_handle);
1384 err=snd_pcm_hwsync(tx_ad_handle);
1385 if(err < 0)
1386 {
1387 // lirerr(872318); // recovery failed, we have to live with less accurate data in frame_avail
1388 }
1389 }
1390 else
1391 {
1392 // lirerr(872319); // snd_pcm_hwsync failed with unknown error, we have to live with less accurate data in frame_avail
1393 }
1394 }
1395 frame_avail= snd_pcm_avail_update(tx_ad_handle);
1396 if(frame_avail < 0)
1397 {
1398 // lirerr(872314); //accept a lesser optimal solution
1399 return 0;
1400 }
1401
1402 return (int)frame_avail;
1403
1404 }
1405 else
1406 #endif
1407 {
1408 #if HAVE_OSS == 1
1409 if(ioctl(tx_audio_in,SNDCTL_DSP_GETISPACE, &tx_ad_info) == -1)lirerr(872314);
1410 return tx_ad_info.bytes/snd[TXAD].framesize;
1411 #endif
1412 }
1413 return 0;
1414 }
1415
lir_empty_da_device_buffer(void)1416 void lir_empty_da_device_buffer(void)
1417 {
1418 if( (ui.use_alsa&PORTAUDIO_RX_OUT) != 0)
1419 {
1420 return;
1421 }
1422 if(rx_audio_out == -1)return;
1423 if(rx_audio_in == rx_audio_out &&
1424 rx_input_thread == THREAD_RX_ADINPUT)return;
1425 if(tx_audio_in == rx_audio_out)return;
1426 #if (ALSA_PRESENT == 1)
1427 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
1428 {
1429 snd_pcm_drop(rx_da_handle);
1430 snd_pcm_prepare(rx_da_handle);
1431 }
1432 else
1433 #endif
1434 {
1435 #if HAVE_OSS== 1
1436 if(ioctl(rx_audio_out,SNDCTL_DSP_GETOSPACE, &rx_da_info) == -1)
1437 {
1438 lirerr(1077);
1439 return;
1440 }
1441 if(rx_da_info.fragstotal - rx_da_info.fragments <= 4)
1442 {
1443 zrw=write(rx_audio_out,&daout[daout_px],(size_t)snd[RXDA].block_bytes);
1444 }
1445 if(ioctl(rx_audio_out,SNDCTL_DSP_RESET,0)==-1)
1446 {
1447 lirerr(1205);
1448 return;
1449 }
1450 #endif
1451 }
1452 }
1453
lir_tx_dawrite(char * buf)1454 void lir_tx_dawrite(char *buf)
1455 {
1456 #if (ALSA_PRESENT == 1)
1457 int err;
1458 char s[40];
1459 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
1460 {
1461 err=snd_pcm_writei(tx_da_handle, buf,
1462 (snd_pcm_uframes_t)snd[TXDA].block_frames);
1463 if(err != snd[TXDA].block_frames)
1464 {
1465 if(err == -EPIPE) // underrun try to recover
1466 {
1467 no_of_tx_underrun_errors++;
1468 sprintf(s,"TX%s%d",underrun_error_msg,no_of_tx_underrun_errors);
1469 wg_error(s,WGERR_TXOUT);
1470 err= snd_pcm_recover(tx_da_handle, err, 0);
1471 if(err < 0)
1472 {
1473 lirerr(1140); // recovery failed
1474 }
1475 }
1476 else
1477 {
1478 if(err > 0 && err < (long) (snd[TXDA].block_frames ) )
1479 {
1480 lirerr(1328); // short write
1481 }
1482 else
1483 {
1484 lirerr(1329); // catch all other errors
1485 }
1486 }
1487 }
1488 }
1489 else
1490 #endif
1491 {
1492 #if HAVE_OSS == 1
1493 zrw=write(tx_audio_out,buf,(size_t)snd[TXDA].block_bytes);
1494 #else
1495 zrw=buf[0];
1496 #endif
1497 }
1498 }
1499
lir_rx_dawrite(void)1500 void lir_rx_dawrite(void)
1501 {
1502 #if (ALSA_PRESENT == 1)
1503 int err;
1504 char s[40];
1505 int i, retry;
1506 #endif
1507 #if (HAVE_OSS == 1 || ALSA_PRESENT == 1)
1508 int wrbytes;
1509 #endif
1510 int bytes_written, bytes_to_write;
1511 int cnt;
1512 if( (ui.use_alsa&PORTAUDIO_RX_OUT) != 0)
1513 {
1514 // We assume Portaudio is always OK.
1515 lir_sched_yield();
1516 return;
1517 }
1518 bytes_written=0;
1519 bytes_to_write=snd[RXDA].block_bytes;
1520 cnt=0;
1521 while(bytes_to_write > 0)
1522 {
1523 #if (ALSA_PRESENT == 1)
1524 if(daout_px+bytes_to_write > daout_bufmask)
1525 {
1526 wrbytes=daout_bufmask+1-daout_px;
1527 }
1528 else
1529 {
1530 wrbytes=bytes_to_write;
1531 }
1532 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
1533 {
1534 i=wrbytes/snd[RXDA].framesize;
1535 err=snd_pcm_writei(rx_da_handle, &daout[daout_px],(snd_pcm_uframes_t)i);
1536 if(err == i)
1537 {
1538 bytes_written=wrbytes;
1539 }
1540 else
1541 {
1542 if(err < 0)
1543 {
1544 retry=0;
1545 if(err == -EPIPE) // underrun, try to recover
1546 {
1547 if(count_rx_underrun_flag)
1548 {
1549 no_of_rx_underrun_errors++;
1550 sprintf(s,"RX%s%d",underrun_error_msg,no_of_rx_underrun_errors);
1551 wg_error(s,WGERR_RXOUT);
1552 }
1553 recover:;
1554 err= snd_pcm_recover(rx_da_handle, err, 0);
1555 }
1556 if(err == -EBUSY)
1557 {
1558 retry++;
1559 if(retry < 15)
1560 {
1561 lir_sleep(1000);
1562 goto recover;
1563 }
1564 }
1565 if(err == -EBADFD)
1566 {
1567 close_rx_sndout();
1568 open_rx_sndout();
1569 if(kill_all_flag) return;
1570 }
1571 }
1572 else
1573 {
1574 if(err > 0 && err < (long) (snd[RXDA].block_frames ) )
1575 {
1576 bytes_written=err*snd[RXDA].framesize;
1577 }
1578 else
1579 {
1580 lirerr(1332); // catch all other errors
1581 }
1582 }
1583 }
1584 }
1585 else
1586 #endif
1587 {
1588 #if HAVE_OSS == 1
1589 if(daout_px+bytes_to_write > daout_bufmask)
1590 {
1591 wrbytes=daout_bufmask+1-daout_px;
1592 }
1593 else
1594 {
1595 wrbytes=bytes_to_write;
1596 }
1597 bytes_written=write(rx_audio_out,&daout[daout_px],(size_t)wrbytes);
1598 if(bytes_written < 0)
1599 {
1600 lir_sched_yield();
1601 if(ioctl(rx_audio_out,SNDCTL_DSP_RESET,0)==-1)
1602 {
1603 lirerr(1205001);
1604 return;
1605 }
1606 close_rx_sndout();
1607 lir_sched_yield();
1608 open_rx_sndout();
1609 lir_sched_yield();
1610 bytes_written=write(rx_audio_out,&daout[daout_px], (size_t)wrbytes);
1611 if(bytes_written < 0)
1612 {
1613 lirerr(1205002);
1614 return;
1615 }
1616 }
1617 #endif
1618 }
1619 daout_px=(daout_px+bytes_written)&daout_bufmask;
1620 bytes_to_write-=bytes_written;
1621 cnt++;
1622 if(cnt>10)
1623 {
1624 lirerr(1331);
1625 }
1626 }
1627 }
1628
sndlog_sync(void)1629 void sndlog_sync(void)
1630 {
1631 fflush(sndlog);
1632 //sync();
1633 }
1634
1635 #if HAVE_OSS == 1
make_devname(int nn,char * ss)1636 void make_devname(int nn, char* ss)
1637 {
1638 char s[80];
1639 int n;
1640 n=nn&255;
1641 // This routine is greatly simplified July 2006 thanks to Diane Bruce, VA3DB.
1642 sprintf(s,"%s",SND_DEV);
1643 if(s[0] == 'u')
1644 {
1645 lirerr(1200);
1646 return;
1647 }
1648 if(n>MAX_DEVNAMES)
1649 {
1650 lirerr(1255);
1651 return;
1652 }
1653 if(n+2 == MAX_DEVNAMES)
1654 {
1655 sprintf(ss, "%s", SND_DEV);
1656 }
1657 else
1658 {
1659 sprintf(ss, "%s%d", SND_DEV, n);
1660 }
1661 }
1662 #endif
1663
close_rx_sndin(void)1664 void close_rx_sndin(void)
1665 {
1666 #if (ALSA_PRESENT == 1)
1667 int err;
1668 #endif
1669 if(ui.use_extio != 0 && ui.extio_type != 4)return;
1670 if( (ui.use_alsa&PORTAUDIO_RX_IN) != 0)
1671 {
1672 close_portaudio_rxad();
1673 return;
1674 }
1675 if(rx_audio_in != -1)
1676 {
1677 if(rx_audio_out == rx_audio_in)
1678 {
1679 close_rx_sndout();
1680 }
1681 #if (ALSA_PRESENT == 1)
1682 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
1683 {
1684 err=snd_pcm_close(rx_ad_handle);
1685 if(err < 0)
1686 {
1687 lirerr(1005);
1688 return;
1689 }
1690 }
1691 else
1692 #endif
1693 {
1694 if(close(rx_audio_in) == -1)
1695 {
1696 lirerr(1005);
1697 return;
1698 }
1699 }
1700 if(ui.rx_addev_no > 255)
1701 {
1702 if(close(rx_audio_in2) == -1)lirerr(1173);
1703 }
1704 }
1705 rx_audio_in=-1;
1706 }
1707
open_tx_sndin(void)1708 void open_tx_sndin(void)
1709 {
1710 #if (ALSA_PRESENT == 1)
1711 float t1;
1712 int i, j;
1713 unsigned int val;
1714 static snd_pcm_format_t format;
1715 snd_pcm_hw_params_t *hw_ad_params;
1716 int err, resample;
1717 #endif
1718 #if HAVE_OSS == 1
1719 char ss[sizeof(SND_DEV)+2];
1720 int frag;
1721 float t2;
1722 int m, k;
1723 #endif
1724 snd[TXAD].block_frames=snd[TXAD].block_bytes/snd[TXAD].framesize;
1725 if(snd[TXAD].block_frames<8)snd[TXAD].block_frames=8;
1726 snd[TXAD].interrupt_rate=(float)(ui.tx_ad_speed)/(float)snd[TXAD].block_frames;
1727 while(snd[TXAD].interrupt_rate > ui.max_dma_rate)
1728 {
1729 snd[TXAD].interrupt_rate/=2;
1730 snd[TXAD].block_bytes*=2;
1731 snd[TXAD].block_frames*=2;
1732 }
1733 while(snd[TXAD].interrupt_rate < ui.min_dma_rate && snd[TXAD].block_frames>8)
1734 {
1735 snd[TXAD].interrupt_rate*=2;
1736 snd[TXAD].block_bytes/=2;
1737 snd[TXAD].block_frames/=2;
1738 }
1739 DEB"\nTXin%sDesired %f",intrate_string,snd[TXAD].interrupt_rate);
1740 if(ui.tx_addev_no == ui.rx_dadev_no && ui.rx_damode == O_RDWR)
1741 {
1742 while(rx_audio_out == -1)
1743 {
1744 lir_sleep(10000);
1745 }
1746 tx_audio_in=rx_audio_out;
1747 return;
1748 }
1749 #if (ALSA_PRESENT == 1)
1750 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
1751 {
1752 char tx_input_plughw_pcm_name [MAX_ALSADEV];
1753 char tx_input_hw_pcm_name [MAX_ALSADEV];
1754 err=chk_open_alsa(ui.tx_addev_no,
1755 ui.tx_ad_bytes,
1756 ui.tx_ad_speed,
1757 ui.tx_ad_channels,
1758 SND_PCM_STREAM_CAPTURE);
1759 if(err != 0)
1760 {
1761 lirerr(1153); //chk_open tx_input failed
1762 return;
1763 }
1764 //get plughw_pcm_name corresponding with ui definition
1765 alsar_get_dev_pcm_names(ui.tx_addev_no,tx_input_plughw_pcm_name,tx_input_hw_pcm_name);
1766 err=snd_pcm_open(&tx_ad_handle, tx_input_plughw_pcm_name,
1767 SND_PCM_STREAM_CAPTURE,0);
1768 if(err < 0)
1769 {
1770 lirerr(1333); // open tx_input failed
1771 return;
1772 }
1773 // use tx_audio_in as switch for compatibility reasons with the existing OSS logic */
1774 // do not think this is used any more (May 2010)
1775 tx_audio_in=1;
1776 //alsa housekeeping
1777 err=snd_pcm_hw_params_malloc(&hw_ad_params);
1778 if(err < 0)
1779 {
1780 lirerr(1272);
1781 return;
1782 }
1783 err=snd_pcm_hw_params_any(tx_ad_handle, hw_ad_params);
1784 if(err < 0)
1785 {
1786 lirerr(1282);
1787 return;
1788 }
1789 // Interleaved mode
1790 err=snd_pcm_hw_params_set_access(tx_ad_handle, hw_ad_params,
1791 SND_PCM_ACCESS_RW_INTERLEAVED);
1792 if(err< 0)
1793 {
1794 lirerr(1294);
1795 return;
1796 }
1797 // Set sample format
1798 if(ui.tx_ad_bytes == 2)
1799 {
1800 format=SND_PCM_FORMAT_S16_LE;
1801 }
1802 else
1803 {
1804 format=SND_PCM_FORMAT_S32_LE;
1805 }
1806 err=snd_pcm_hw_params_set_format(tx_ad_handle, hw_ad_params,format);
1807 if(err < 0)
1808 {
1809 lirerr(1295);
1810 return;
1811 }
1812 // Set number of ad_channels
1813 err=snd_pcm_hw_params_set_channels(tx_ad_handle,
1814 hw_ad_params, (unsigned int)ui.tx_ad_channels);
1815 if(err < 0)
1816 {
1817 lirerr(1296);
1818 return;
1819 }
1820 // Set sample rate
1821 // first set hardware resample
1822 resample=1;
1823 err=snd_pcm_hw_params_set_rate_resample(tx_ad_handle,
1824 hw_ad_params, (unsigned int)resample);
1825 if(err < 0)
1826 {
1827 lirerr(1298);
1828 return;
1829 }
1830 // now set sample rate
1831 val=(unsigned int)ui.tx_ad_speed;
1832 err=snd_pcm_hw_params_set_rate_near(tx_ad_handle,hw_ad_params, &val, 0);
1833 if(err < 0)
1834 {
1835 lirerr(1299);
1836 return;
1837 }
1838 t1=(float)(val)/(float)ui.tx_ad_speed;
1839 if(t1 > 1.05 || t1 < 0.95)
1840 {
1841 lirerr(1012);
1842 return;
1843 }
1844 ui.tx_ad_speed=(int)val;
1845 // Set period size:
1846 // We want the period_size to match txad.block_fragments
1847 i=snd[TXAD].block_frames;
1848 j=0;
1849 periodset:;
1850 err=snd_pcm_hw_params_set_period_size(tx_ad_handle,hw_ad_params,
1851 (snd_pcm_uframes_t)snd[TXAD].block_frames, 0);
1852 if(err < 0)
1853 {
1854 if(j==0)
1855 {
1856 snd[TXAD].block_frames/=2;
1857 if(snd[TXAD].block_frames > 32)goto periodset;
1858 j=1;
1859 snd[TXAD].block_frames=i;
1860 }
1861 snd[TXAD].block_frames*=2;
1862 if(snd[TXAD].block_frames < 8192)goto periodset;
1863 lirerr(1318);
1864 return;
1865 }
1866 // Write all the parameters to the driver
1867 err=snd_pcm_hw_params(tx_ad_handle, hw_ad_params);
1868 if(err < 0)
1869 {
1870 lirerr(1301);
1871 return;
1872 }
1873 // free the memory for the hardware parameter structure
1874 snd_pcm_hw_params_free(hw_ad_params);
1875 i=snd[TXAD].block_frames;
1876 make_power_of_two(&i);
1877 if(i != (int)snd[TXAD].block_frames)
1878 {
1879 lirerr(1149);
1880 return;
1881 }
1882 snd[TXAD].interrupt_rate=
1883 (float)(ui.tx_ad_speed)/(float)snd[TXAD].block_frames;
1884 DEB"\nTXin%sActual %f",intrate_string,snd[TXAD].interrupt_rate);
1885 }
1886 else
1887 #endif
1888 {
1889 #if HAVE_OSS == 1
1890 make_devname(ui.tx_addev_no, ss);
1891 if(kill_all_flag)return;
1892 tx_audio_in=open( ss ,O_RDONLY|O_EXCL, 0);
1893 if(tx_audio_in == -1)
1894 {
1895 lirerr(1260);
1896 return;
1897 }
1898 // We want the fragment size to match snd[TXAD].block_bytes.
1899 frag=0;
1900 m=snd[TXAD].block_bytes;
1901 while(m>1)
1902 {
1903 m>>=1;
1904 frag++;
1905 }
1906 if(frag < 5)frag=5;
1907 frag=frag|0x7fff0000;
1908 if(ioctl(tx_audio_in, SNDCTL_DSP_SETFRAGMENT, &frag) == -1)
1909 {
1910 lirerr(1262);
1911 return;
1912 }
1913 m=AFMT_S16_LE;
1914 #ifdef AFMT_S32_LE
1915 if(ui.tx_ad_bytes==4)m=AFMT_S32_LE;
1916 #else
1917 ui.tx_ad_bytes=2;
1918 #endif
1919 k=m;
1920 if(ioctl(tx_audio_in, SNDCTL_DSP_SETFMT, &m) == -1)
1921 {
1922 lirerr(231013);
1923 return;
1924 }
1925 if(m!=k)
1926 {
1927 lirerr(231014);
1928 return;
1929 }
1930 // Set number of channels
1931 k=ui.tx_ad_channels;
1932 m=k;
1933 if(ioctl(tx_audio_in, SNDCTL_DSP_CHANNELS, &m) == -1)
1934 {
1935 lirerr(231009);
1936 return;
1937 }
1938 if(m != k)
1939 {
1940 lirerr(231010);
1941 return;
1942 }
1943 m=ui.tx_ad_speed;
1944 if(ioctl(tx_audio_in, SNDCTL_DSP_SPEED, &m)==-1)
1945 {
1946 lirerr(231011);
1947 return;
1948 }
1949 t2=(float)(m)/(float)ui.tx_ad_speed;
1950 if(t2 > 1.05 || t2 < 0.95)
1951 {
1952 lirerr(231012);
1953 return;
1954 }
1955 ui.tx_ad_speed=m;
1956 // This has to be the last ioctl call before read or write!!
1957 t2=(float)(ui.tx_ad_channels*ui.tx_ad_bytes*
1958 ui.tx_ad_speed)/(float)snd[TXAD].block_bytes;
1959 DEB"\nTXin interrupt_rate: Desired %f",t2);
1960 ioctl(tx_audio_in, SNDCTL_DSP_GETBLKSIZE,&m);
1961 t2=(float)(ui.tx_ad_channels*ui.tx_ad_bytes*ui.tx_ad_speed)/(float)m;
1962 DEB" actual %f\n",t2);
1963 #endif
1964 }
1965 }
1966
close_tx_sndin(void)1967 void close_tx_sndin(void)
1968 {
1969 #if (ALSA_PRESENT == 1)
1970 int err;
1971 #endif
1972 if(tx_audio_in == -1)return;
1973 if(ui.tx_addev_no == ui.rx_dadev_no && ui.rx_damode == O_RDWR)
1974 {
1975 tx_audio_in=-1;
1976 return;
1977 }
1978 #if (ALSA_PRESENT == 1)
1979 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
1980 {
1981 err=snd_pcm_close(tx_ad_handle);
1982 if(err < 0)
1983 {
1984 lirerr(1005);
1985 return;
1986 }
1987 }
1988 else
1989 #endif
1990 {
1991 #if HAVE_OSS == 1
1992 if(close(tx_audio_in)==-1)lirerr(231037);
1993 tx_audio_in=-1;
1994 #endif
1995 }
1996 }
1997
open_tx_sndout(void)1998 void open_tx_sndout(void)
1999 {
2000 #if (ALSA_PRESENT == 1)
2001 unsigned int val;
2002 static snd_pcm_format_t format;
2003 snd_pcm_hw_params_t *hw_da_params;
2004 int ii, dir, err, resample;
2005 int i;
2006 float t1;
2007 #endif
2008 #if HAVE_OSS == 1
2009 int frag;
2010 char ss[sizeof(SND_DEV)+2];
2011 int m, k;
2012 float t2;
2013 #endif
2014 snd[TXDA].block_frames=snd[TXDA].block_bytes/snd[TXDA].framesize;
2015 if(snd[TXDA].block_frames<8)
2016 {
2017 snd[TXDA].block_frames=8;
2018 snd[TXDA].block_bytes=snd[TXDA].block_frames*snd[TXDA].framesize;
2019 }
2020 snd[TXDA].interrupt_rate=(float)(ui.tx_da_speed)/(float)snd[TXDA].block_frames;
2021 while(snd[TXDA].interrupt_rate > ui.max_dma_rate)
2022 {
2023 snd[TXDA].interrupt_rate/=2;
2024 snd[TXDA].block_bytes*=2;
2025 snd[TXDA].block_frames*=2;
2026 }
2027 while(snd[TXDA].interrupt_rate < ui.min_dma_rate && snd[TXDA].block_frames>8)
2028 {
2029 snd[TXDA].interrupt_rate*=2;
2030 snd[TXDA].block_bytes/=2;
2031 snd[TXDA].block_frames/=2;
2032 }
2033
2034 DEB"\nTXout%sDesired %f",intrate_string,snd[TXDA].interrupt_rate);
2035 #if (ALSA_PRESENT == 1)
2036 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
2037 {
2038 char tx_out_plughw_pcm_name[MAX_ALSADEV];
2039 char tx_out_hw_pcm_name[MAX_ALSADEV];
2040
2041 err=chk_open_alsa(ui.tx_dadev_no,
2042 ui.tx_da_bytes,
2043 ui.tx_da_speed,
2044 ui.tx_da_channels,
2045 SND_PCM_STREAM_PLAYBACK);
2046 if(err != 0)
2047 {
2048 lirerr(1151);
2049 return;
2050 }
2051 //get plughw_pcm_name corresponding with ui definition
2052 alsar_get_dev_pcm_names(ui.tx_dadev_no,tx_out_plughw_pcm_name,tx_out_hw_pcm_name);
2053 if((err=snd_pcm_open(&tx_da_handle, tx_out_plughw_pcm_name,
2054 SND_PCM_STREAM_PLAYBACK, 0)) < 0)
2055 {
2056 lirerr(1304);
2057 return;
2058 }
2059 // use tx_audio_out as switch for compatibility reasons with the existing OSS logic
2060 // do not think this is used any more (May 2010)
2061 tx_audio_out=1;
2062 //*********************************************************************
2063 //******************** SET PLAYBACK PARAMETERS THE ALSA WAY ******
2064 //*********************************************************************
2065 err=snd_pcm_hw_params_malloc (&hw_da_params);
2066 if(err < 0)
2067 {
2068 lirerr(1305);
2069 return;
2070 }
2071 err=snd_pcm_hw_params_any(tx_da_handle, hw_da_params);
2072 if(err < 0)
2073 {
2074 lirerr(1306);
2075 return;
2076 }
2077 // Interleaved mode
2078 err=snd_pcm_hw_params_set_access(tx_da_handle, hw_da_params,
2079 SND_PCM_ACCESS_RW_INTERLEAVED);
2080 if(err < 0)
2081 {
2082 lirerr(1307);
2083 return;
2084 }
2085 // Set sample format
2086 if(ui.tx_da_bytes == 2)
2087 {
2088 format=SND_PCM_FORMAT_S16_LE;
2089 }
2090 else
2091 {
2092 format=SND_PCM_FORMAT_S32_LE;
2093 }
2094 err=snd_pcm_hw_params_set_format(tx_da_handle, hw_da_params,format);
2095 if(err < 0)
2096 {
2097 lirerr(1308);
2098 return;
2099 }
2100 // Set number of da_channels
2101 err=snd_pcm_hw_params_set_channels(tx_da_handle,
2102 hw_da_params, (unsigned int)ui.tx_da_channels);
2103 if(err <0)
2104 {
2105 lirerr(1309);
2106 return;
2107 }
2108 // Set sample rate
2109 // first enable hardware resample
2110 resample=1;
2111 err=snd_pcm_hw_params_set_rate_resample(tx_da_handle,
2112 hw_da_params, (unsigned int)resample);
2113 if(err < 0)
2114 {
2115 lirerr(1310);
2116 return;
2117 }
2118 // now set sample rate
2119 val=(unsigned int)ui.tx_da_speed;
2120 if((err =snd_pcm_hw_params_set_rate_near(
2121 tx_da_handle,hw_da_params, &val, 0)<0))
2122 {
2123 lirerr(1311);
2124 return;
2125 }
2126 t1=(float)(val)/(float)ui.tx_da_speed;
2127 if(t1 > 1.05 || t1 < 0.95)
2128 {
2129 lirerr(1023);
2130 return;
2131 }
2132 ui.tx_da_speed=(int)val;
2133 dir=0;
2134 // obtained value is <,=,> target-value, according value of dir (-1,0,1)
2135 err=snd_pcm_hw_params_set_period_size_near(tx_da_handle, hw_da_params,
2136 (snd_pcm_uframes_t*)((void*)&snd[TXDA].block_frames), &dir);
2137 if(err < 0)
2138 {
2139 lirerr(1312);
2140 return;
2141 }
2142 // check obtained period size
2143 err=snd_pcm_hw_params_get_period_size(hw_da_params,
2144 (snd_pcm_uframes_t*)((void*)&snd[TXDA].block_frames), &dir);
2145 if(err < 0)
2146 {
2147 DEB"\nopen_tx_sndout:Unable to get period size for playback: %s\n",
2148 snd_strerror(err));
2149 lirerr(12953);
2150 return;
2151 }
2152 ii=snd[TXDA].block_frames;
2153 make_power_of_two(&ii);
2154 i=ii;
2155 if(i != snd[TXDA].block_frames)
2156 {
2157 lirerr(1148);
2158 return;
2159 }
2160 snd[TXDA].block_bytes=snd[TXDA].block_frames*snd[TXDA].framesize;
2161 snd[TXDA].interrupt_rate=(float)(ui.tx_da_speed)/(float)snd[TXDA].block_frames;
2162 // set the hw parameters
2163 err=snd_pcm_hw_params(tx_da_handle, hw_da_params);
2164 if(err < 0)
2165 {
2166 lirerr(1313);
2167 return;
2168 }
2169 // free the memory for the hardware parameter struct
2170 snd_pcm_hw_params_free (hw_da_params);
2171 snd[TXDA].block_frames= snd[TXDA].block_bytes/snd[TXDA].framesize;
2172 // get buffersize
2173 err=snd_pcm_get_params ( tx_da_handle,
2174 (snd_pcm_uframes_t*)((void*)&snd[TXDA].tot_frames),
2175 (snd_pcm_uframes_t*)((void*)&snd[TXDA].block_frames) );
2176 if(err < 0)
2177 {
2178 lirerr(1313);
2179 return;
2180 }
2181 snd[TXDA].tot_bytes=snd[TXDA].tot_frames*snd[TXDA].framesize;
2182 goto ok_exit;
2183 }
2184 else
2185 #endif
2186 {
2187 #if HAVE_OSS == 1
2188 if(ui.rx_addev_no == ui.tx_dadev_no && ui.rx_admode == O_RDWR )
2189 {
2190 m=0;
2191 while(rx_audio_in == -1)
2192 {
2193 m++;
2194 lir_sleep(30000);
2195 if(m>100)
2196 {
2197 lirerr(32963);
2198 }
2199 }
2200 snd[TXDA]=snd[RXAD];
2201 tx_audio_out=rx_audio_in;
2202 }
2203 else
2204 {
2205 make_devname(ui.tx_dadev_no, ss);
2206 if(kill_all_flag)return;
2207 tx_audio_out=open( ss, O_WRONLY|O_NONBLOCK|O_EXCL, 0);
2208 if(tx_audio_out == -1)
2209 {
2210 lirerr(1079);
2211 return;
2212 }
2213 frag=0;
2214 m=snd[TXDA].block_bytes;
2215 while(m>1)
2216 {
2217 m>>=1;
2218 frag++;
2219 }
2220 if(frag < 5)frag=5;
2221 frag=frag|0x7fff0000;
2222 if(ioctl(tx_audio_out, SNDCTL_DSP_SETFRAGMENT, &frag) == -1)
2223 {
2224 lirerr(991262);
2225 return;
2226 }
2227 m=AFMT_S16_LE;
2228 #ifdef AFMT_S32_LE
2229 if(ui.tx_da_bytes==4)m=AFMT_S32_LE;
2230 #else
2231 ui.tx_da_bytes=2;
2232 #endif
2233 k=m;
2234 if(ioctl(tx_audio_out, SNDCTL_DSP_SETFMT, &m) == -1)
2235 {
2236 lirerr(231013);
2237 return;
2238 }
2239 if(m!=k)
2240 {
2241 lirerr(231014);
2242 return;
2243 }
2244 // Set number of channels
2245 k=ui.tx_da_channels;
2246 m=k;
2247 if(ioctl(tx_audio_out, SNDCTL_DSP_CHANNELS, &m) == -1)
2248 {
2249 lirerr(231009);
2250 return;
2251 }
2252 if(m != k)
2253 {
2254 lirerr(231010);
2255 return;
2256 }
2257 m=ui.tx_da_speed;
2258 if(ioctl(tx_audio_out, SNDCTL_DSP_SPEED, &m)==-1)
2259 {
2260 lirerr(231011);
2261 return;
2262 }
2263 t2=(float)(m)/(float)ui.tx_da_speed;
2264 if(t2 > 1.05 || t2 < 0.95)
2265 {
2266 lirerr(231112);
2267 return;
2268 }
2269 ui.tx_da_speed=m;
2270 }
2271 if(ioctl(tx_audio_out,SNDCTL_DSP_GETOSPACE, &tx_da_info) == -1)
2272 lirerr(872313);
2273 snd[TXDA].tot_bytes=tx_da_info.fragstotal*tx_da_info.fragsize;
2274 snd[TXDA].tot_frames=snd[TXDA].tot_bytes/snd[TXDA].framesize;
2275 snd[TXDA].block_bytes=tx_da_info.fragsize;
2276 snd[TXDA].block_frames=snd[TXDA].block_bytes/snd[TXDA].framesize;
2277 snd[TXDA].interrupt_rate=(float)(ui.tx_da_speed)/(float)snd[TXDA].block_frames;
2278 #endif
2279 }
2280 #if (ALSA_PRESENT == 1)
2281 ok_exit:;
2282 #endif
2283 DEB"\nTXout%sActual %f",intrate_string,snd[TXDA].interrupt_rate);
2284 }
2285
close_tx_sndout(void)2286 void close_tx_sndout(void)
2287 {
2288 #if (ALSA_PRESENT == 1)
2289 int err;
2290 #endif
2291 if(tx_audio_out == -1)return;
2292 if(ui.tx_dadev_no == ui.rx_addev_no && ui.rx_admode == O_RDWR)
2293 {
2294 tx_audio_out=-1;
2295 return;
2296 }
2297 #if (ALSA_PRESENT == 1)
2298 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
2299 {
2300 snd_pcm_drop(tx_da_handle);
2301 err= snd_pcm_close(tx_da_handle);
2302 if(err < 0)lirerr(1006);
2303 }
2304 else
2305 #endif
2306 {
2307 #if HAVE_OSS == 1
2308 if(ioctl(tx_audio_out,SNDCTL_DSP_RESET,0)==-1)
2309 {
2310 lirerr(1288);
2311 }
2312 if(close(tx_audio_out)==-1)lirerr(1287);
2313 tx_audio_out=-1;
2314 #endif
2315 }
2316 }
2317
close_rx_sndout(void)2318 void close_rx_sndout(void)
2319 {
2320 #if (ALSA_PRESENT == 1)
2321 int err;
2322 #endif
2323 if(rx_audio_out == -1)
2324 {
2325 return;
2326 }
2327 if( (ui.use_alsa&PORTAUDIO_RX_OUT) != 0)
2328 {
2329 close_portaudio_rxda();
2330 goto freebuf;
2331 }
2332 #if (ALSA_PRESENT == 1)
2333 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
2334 {
2335 snd_pcm_drop(rx_da_handle);
2336 err= snd_pcm_close(rx_da_handle);
2337 if(err < 0)lirerr(1006);
2338 }
2339 else
2340 #endif
2341 {
2342 #if HAVE_OSS == 1
2343 if(rx_audio_out != rx_audio_in)
2344 {
2345 if(ioctl(rx_audio_out,SNDCTL_DSP_RESET,0)==-1)
2346 {
2347 lirerr(1026);
2348 }
2349 if(close(rx_audio_out)==-1)lirerr(1006);
2350 }
2351 #endif
2352 }
2353 freebuf:;
2354 rx_audio_out=-1;
2355 }
2356
open_rx_sndin(int report_errors)2357 int open_rx_sndin(int report_errors)
2358 {
2359 #if HAVE_OSS == 1
2360 char ss[sizeof(SND_DEV)+2];
2361 audio_buf_info ad_info;
2362 int i, j, frag;
2363 float t2;
2364 #endif
2365 #if (ALSA_PRESENT == 1)
2366 int ir;
2367 snd_pcm_format_t format;
2368 snd_pcm_hw_params_t *hw_ad_params;
2369 int k, err, resample;
2370 unsigned int val;
2371 float t1;
2372 ir=report_errors;
2373 #endif
2374 lir_rxin_status=report_errors;
2375 lir_rxin_status=LIR_OK;
2376 if(ui.use_extio != 0 && ui.extio_type != 4)return 0;
2377 if( (rx_audio_in) != -1)
2378 {
2379 if(ui.rx_admode == O_RDWR)return 0;
2380 lirerr(1000);
2381 return 0;
2382 }
2383 if( (ui.use_alsa&PORTAUDIO_RX_IN) != 0)
2384 {
2385 open_portaudio_rxad();
2386 return 0;
2387 }
2388 #if (ALSA_PRESENT == 1)
2389 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
2390 {
2391 char rx_sndin_plughw_pcm_name [MAX_ALSADEV];
2392 char rx_sndin_hw_pcm_name [MAX_ALSADEV];
2393 ir=2;
2394 if( (ui.rx_input_mode&DWORD_INPUT) != 0)ir=4;
2395 err=chk_open_alsa(ui.rx_addev_no,
2396 ir,
2397 ui.rx_ad_speed,
2398 ui.rx_ad_channels,
2399 SND_PCM_STREAM_CAPTURE);
2400 if(err != 0)
2401 {
2402 lirerr(1152); // chkopen rx_sndin failed
2403 return 0;
2404 }
2405 //get plughw_pcm_name corresponding with ui definition
2406 alsar_get_dev_pcm_names(ui.rx_addev_no,rx_sndin_plughw_pcm_name,rx_sndin_hw_pcm_name );
2407 err=snd_pcm_open(&rx_ad_handle, rx_sndin_plughw_pcm_name,
2408 SND_PCM_STREAM_CAPTURE, 0);
2409 if(err < 0)
2410 {
2411 lirerr(1271); // open rx_sndin failed
2412 return 0;
2413 }
2414 // use rx_audio_in as switch for compatibility reasons with the existing OSS logic */
2415 rx_audio_in=2;
2416 //alsa housekeeping
2417 err=snd_pcm_hw_params_malloc(&hw_ad_params);
2418 if(err < 0)
2419 {
2420 lirerr(1272);
2421 return 0;
2422 }
2423 err=snd_pcm_hw_params_any(rx_ad_handle, hw_ad_params);
2424 if(err < 0)
2425 {
2426 lirerr(1282);
2427 return 0;
2428 }
2429 // Interleaved mode
2430 err=snd_pcm_hw_params_set_access(rx_ad_handle, hw_ad_params,
2431 SND_PCM_ACCESS_RW_INTERLEAVED);
2432 if(err < 0)
2433 {
2434 lirerr(1294);
2435 return 0;
2436 }
2437 // Set sample format
2438 format=SND_PCM_FORMAT_S16_LE;
2439 if( (ui.rx_input_mode&DWORD_INPUT) != 0) format=SND_PCM_FORMAT_S32_LE;
2440 err=snd_pcm_hw_params_set_format (rx_ad_handle, hw_ad_params,format);
2441 if(err < 0)
2442 {
2443 lirerr(1295);
2444 return 0;
2445 }
2446 // Set number of ad_channels
2447 err=snd_pcm_hw_params_set_channels(rx_ad_handle, hw_ad_params,
2448 (unsigned int)ui.rx_ad_channels);
2449 if(err < 0)
2450 {
2451 lirerr(1296);
2452 return 0;
2453 }
2454 // Set sample rate
2455 // first disable hardware resample
2456 resample=0;
2457 err=snd_pcm_hw_params_set_rate_resample(rx_ad_handle,
2458 hw_ad_params,
2459 (unsigned int)resample);
2460 if(err < 0)
2461 {
2462 lirerr(1298);
2463 return 0;
2464 }
2465 // now set sample rate
2466 val=(unsigned int)ui.rx_ad_speed;
2467 err=snd_pcm_hw_params_set_rate_near(rx_ad_handle,hw_ad_params, &val, 0);
2468 if(err<0)
2469 {
2470 lirerr(1299);
2471 return 0;
2472 }
2473 t1=(float)(val)/(float)ui.rx_ad_speed;
2474 if(t1 > 1.05 || t1 < 0.95)
2475 {
2476 lirerr(1012);
2477 return 0;
2478 }
2479 ui.rx_ad_speed=(int)val;
2480 // Set period size:
2481 // We want the period_size to match snd[RXAD].block_frames
2482 val=(unsigned int)snd[RXAD].block_frames;
2483 k=1;
2484 periodset:;
2485 err=snd_pcm_hw_params_set_period_size(rx_ad_handle,hw_ad_params, val, 0);
2486 if(err<0)
2487 {
2488 if(k==1)
2489 {
2490 val/=2;
2491 if(val > 32)goto periodset;
2492 }
2493 k*=2;
2494 val=(unsigned int)(k*snd[RXAD].block_frames);
2495 if(k<=64)goto periodset;
2496 lirerr(1300);
2497 return 0;
2498 }
2499 // Write all the parameters to the driver
2500 if((err=snd_pcm_hw_params(rx_ad_handle, hw_ad_params))< 0)
2501 {
2502 lirerr(1301);
2503 return 0;
2504 }
2505 // free the memory for the hardware parameter structure
2506 snd_pcm_hw_params_free (hw_ad_params);
2507
2508 snd[RXAD].block_frames=snd[RXAD].block_bytes/snd[RXAD].framesize;
2509 return 0;
2510 }
2511 else
2512 #endif
2513 {
2514 #if HAVE_OSS == 1
2515 make_devname(ui.rx_addev_no, ss);
2516 if(kill_all_flag)return 0;
2517 rx_audio_in=open(ss ,ui.rx_admode|O_EXCL , 0);
2518 if(rx_audio_in == -1)
2519 {
2520 lirerr(1007);
2521 return 0;
2522 }
2523 if(ui.rx_addev_no > 255)
2524 {
2525 i=ui.rx_addev_no/255-1;
2526 make_devname(i, ss);
2527 if(kill_all_flag)return 0;
2528 rx_audio_in2=open( ss ,ui.rx_admode|O_EXCL , 0);
2529 if(rx_audio_in2 == -1)
2530 {
2531 lirerr(1174);
2532 return 0;
2533 }
2534 }
2535 // We want the fragment size to match snd[RXAD].block_bytes.
2536 frag=0;
2537 i=snd[RXAD].block_bytes>>1;
2538 while(i>0)
2539 {
2540 i>>=1;
2541 frag++;
2542 }
2543 if(frag < 4)frag=4;
2544 if(ui.rx_addev_no > 255)
2545 {
2546 frag--;
2547 if(frag < 4)frag=4;
2548 frag=frag|0x7fff0000;
2549 if(ioctl(rx_audio_in2, SNDCTL_DSP_SETFRAGMENT, &frag) == -1)
2550 {
2551 lirerr(1175);
2552 return 0;
2553 }
2554 }
2555 frag=frag|0x7fff0000;
2556 if(ioctl(rx_audio_in, SNDCTL_DSP_SETFRAGMENT, &frag) == -1)
2557 {
2558 lirerr(1008);
2559 return 0;
2560 }
2561 i=AFMT_S16_LE;
2562 #ifdef AFMT_S32_LE
2563 if( (ui.rx_input_mode&DWORD_INPUT) != 0)i=AFMT_S32_LE;
2564 #else
2565 if( (ui.rx_input_mode&DWORD_INPUT) != 0)
2566 {
2567 lirerr(1246);
2568 return 0;
2569 }
2570 #endif
2571 j=i;
2572 if(ioctl(rx_audio_in, SNDCTL_DSP_SETFMT, &i) == -1)
2573 {
2574 lirerr(1013);
2575 return 0;
2576 }
2577 if(i!=j)
2578 {
2579 lirerr(1014);
2580 return 0;
2581 }
2582 if(ui.rx_addev_no > 255)
2583 {
2584 j=i;
2585 if(ioctl(rx_audio_in2, SNDCTL_DSP_SETFMT, &i) == -1)
2586 {
2587 lirerr(1176);
2588 return 0;
2589 }
2590 if(i!=j)
2591 {
2592 lirerr(1177);
2593 return 0;
2594 }
2595 }
2596 // Set number of ad_channels
2597 j=ui.rx_ad_channels;
2598 if(ui.rx_addev_no > 255)j=2;
2599 i=j;
2600 if(ioctl(rx_audio_in, SNDCTL_DSP_CHANNELS, &i) == -1)
2601 {
2602 lirerr(1009);
2603 return 0;
2604 }
2605 if(i != j)
2606 {
2607 lirerr(1010);
2608 return 0;
2609 }
2610 if(ui.rx_addev_no > 255)
2611 {
2612 i=j;
2613 if(ioctl(rx_audio_in2, SNDCTL_DSP_CHANNELS, &i) == -1)
2614 {
2615 lirerr(1178);
2616 return 0;
2617 }
2618 if(i != j)
2619 {
2620 lirerr(1179);
2621 return 0;
2622 }
2623 }
2624 i=ui.rx_ad_speed;
2625 if(ioctl(rx_audio_in, SNDCTL_DSP_SPEED, &i)==-1)
2626 {
2627 lirerr(1011);
2628 return 0;
2629 }
2630 t2=(float)(i)/(float)ui.rx_ad_speed;
2631 if(t2 > 1.05 || t2 < 0.95)
2632 {
2633 lirerr(1012);
2634 return 0;
2635 }
2636 ui.rx_ad_speed=i;
2637 if(ui.rx_addev_no > 255)
2638 {
2639 if(ioctl(rx_audio_in2, SNDCTL_DSP_SPEED, &i)==-1)
2640 {
2641 lirerr(1180);
2642 return 0;
2643 }
2644 if(i != ui.rx_ad_speed)
2645 {
2646 lirerr(1181);
2647 return 0;
2648 }
2649 // Now that both devices are configured to be equal, synchronize them.
2650 i=0;
2651 if(ioctl(rx_audio_in,SNDCTL_DSP_SETTRIGGER,&i)==-1)
2652 {
2653 lirerr(1183);
2654 return 0;
2655 }
2656 i=0;
2657 if(ioctl(rx_audio_in2,SNDCTL_DSP_SETTRIGGER,&i)==-1)
2658 {
2659 lirerr(1184);
2660 return 0;
2661 }
2662 i=PCM_ENABLE_INPUT;
2663 if(ioctl(rx_audio_in,SNDCTL_DSP_SETTRIGGER,&i)==-1)
2664 {
2665 lirerr(1183);
2666 return 0;
2667 }
2668 i=PCM_ENABLE_INPUT;
2669 if(ioctl(rx_audio_in2,SNDCTL_DSP_SETTRIGGER,&i)==-1)
2670 {
2671 lirerr(1184);
2672 return 0;
2673 }
2674 }
2675 if(ioctl(rx_audio_in, SNDCTL_DSP_GETISPACE, &ad_info) == -1)
2676 {
2677 lirerr(1109);
2678 return 0;
2679 }
2680 overrun_limit=ad_info.fragstotal-1;
2681 if(ui.rx_addev_no > 255)
2682 {
2683 if(ioctl(rx_audio_in2, SNDCTL_DSP_GETISPACE, &ad_info) == -1)
2684 {
2685 lirerr(1109);
2686 return 0;
2687 }
2688 if(overrun_limit != ad_info.fragstotal-1)
2689 {
2690 lirerr(1109);
2691 }
2692 }
2693 // This has to be the last ioctl call before read or write!!
2694 ioctl(rx_audio_in,SNDCTL_DSP_GETBLKSIZE,&i);
2695 snd[RXAD].block_frames=snd[RXAD].block_bytes/snd[RXAD].framesize;
2696 #endif
2697 }
2698 return 0;
2699 }
2700
open_rx_sndout(void)2701 void open_rx_sndout(void)
2702 {
2703 #if (ALSA_PRESENT == 1)
2704 snd_pcm_hw_params_t *hw_da_params;
2705 static snd_pcm_format_t format;
2706 int err, resample, dir;
2707 unsigned int val;
2708 #endif
2709 float t1;
2710 #if HAVE_OSS == 1
2711 char cc;
2712 int frag;
2713 char ss[sizeof(SND_DEV)+2];
2714 char* tmpbuf;
2715 int j;
2716 #endif
2717 int i;
2718 lir_rxout_status=LIR_OK;
2719 snd[RXDA].framesize=rx_daout_channels*rx_daout_bytes;
2720 t1=min_delay_time;
2721 i=4;
2722 if(diskread_flag >= 2)i=1;
2723 if(t1 < fft3_blocktime/(float)i)
2724 {
2725 t1=fft3_blocktime/(float)i;
2726 }
2727 if(t1 > 1)t1=1;
2728 snd[RXDA].block_frames=(int)(0.75F*t1*(float)genparm[DA_OUTPUT_SPEED]);
2729 make_power_of_two(&snd[RXDA].block_frames);
2730 // make the minimum block 8 frames
2731 if(snd[RXDA].block_frames < 8)snd[RXDA].block_frames=8;
2732 make_power_of_two(&snd[RXDA].block_frames);
2733 snd[RXDA].interrupt_rate=(float)(genparm[DA_OUTPUT_SPEED])/
2734 (float)snd[RXDA].block_frames;
2735 while(snd[RXDA].interrupt_rate < ui.min_dma_rate && snd[RXDA].block_frames>8)
2736 {
2737 snd[RXDA].interrupt_rate*=2;
2738 snd[RXDA].block_frames/=2;
2739 }
2740 while(snd[RXDA].interrupt_rate > ui.max_dma_rate)
2741 {
2742 snd[RXDA].interrupt_rate/=2;
2743 snd[RXDA].block_frames*=2;
2744 }
2745 DEB"\nRXout interrupt_rate: Desired %f",snd[RXDA].interrupt_rate);
2746 // Allocate buffers for minimum 0.3 seconds.
2747 snd[RXDA].block_bytes=snd[RXDA].block_frames*snd[RXDA].framesize;
2748 snd[RXDA].no_of_blocks=(int)(0.3F*snd[RXDA].interrupt_rate);
2749 make_power_of_two(&snd[RXDA].no_of_blocks);
2750 if(snd[RXDA].no_of_blocks < 8)snd[RXDA].no_of_blocks=8;
2751 snd[RXDA].tot_bytes=snd[RXDA].no_of_blocks*snd[RXDA].block_bytes;
2752 snd[RXDA].tot_frames=snd[RXDA].no_of_blocks*snd[RXDA].block_frames;
2753 if(ui.rx_dadev_no == DISABLED_DEVICE_CODE)return;
2754 if( (ui.use_alsa&PORTAUDIO_RX_OUT) != 0)
2755 {
2756 open_portaudio_rxda();
2757 if(kill_all_flag)return;
2758 goto bufalloc;
2759 }
2760 if( rx_audio_out != -1)
2761 {
2762 lirerr(1015);
2763 return;
2764 }
2765 if( (ui.rx_input_mode&NO_DUPLEX) != 0 && rx_audio_in != -1)return;
2766 if(ui.rx_dadev_no == UNDEFINED_DEVICE_CODE)
2767 {
2768 if(diskread_flag >=2)
2769 {
2770 if(rx_audio_in != -1)
2771 {
2772 lirerr(9865);
2773 return;
2774 }
2775 #if (ALSA_PRESENT == 1)
2776 //*********************************************************************
2777 //******************** OPEN ALSA PLAYBACK DEVICE *********************
2778 //*********************************************************************
2779 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
2780 {
2781 char rx_out_plughw_pcm_name [MAX_ALSADEV];
2782 char rx_out_hw_pcm_name [MAX_ALSADEV];
2783 err=chk_open_alsa(ui.rx_dadev_no,
2784 rx_daout_bytes,
2785 genparm[DA_OUTPUT_SPEED],
2786 rx_daout_channels,
2787 SND_PCM_STREAM_PLAYBACK);
2788 if(err != 0)
2789 {
2790 lirerr(1151);
2791 return;
2792 }
2793
2794 //get plughw_pcm_name corresponding with ui definition
2795 alsar_get_dev_pcm_names(ui.rx_dadev_no,rx_out_plughw_pcm_name,rx_out_hw_pcm_name);
2796 if((err=snd_pcm_open(&rx_da_handle, rx_out_plughw_pcm_name,
2797 SND_PCM_STREAM_PLAYBACK, 0)) < 0)
2798 {
2799 lirerr(1303);
2800 return;
2801 }
2802 // use rx_audio_out as switch for compatibility with the existing OSS logic
2803 rx_audio_out=1;//(int)rx_da_handle;
2804 }
2805 else
2806 #endif
2807 {
2808 #if HAVE_OSS == 1
2809 // There is no separate device for output which means that RDWR was not
2810 // selected for both input and output. Use the input device for our
2811 // output since input has to be from disk or network.
2812 make_devname(ui.rx_addev_no, ss);
2813 if(kill_all_flag)return;
2814 rx_audio_out=open( ss ,O_WRONLY|O_EXCL , 0);
2815 #endif
2816 }
2817 if(rx_audio_out == -1)
2818 {
2819 lirerr(1086);
2820 return;
2821 }
2822 goto set_da;
2823 }
2824 else
2825 {
2826 return;
2827 }
2828 }
2829 // *******************************************
2830 if(ui.rx_addev_no == ui.rx_dadev_no && ui.rx_admode == O_RDWR )
2831 {
2832 if(rx_audio_in == -1 )return;
2833 snd[RXDA]=snd[RXAD];
2834 rx_audio_out=rx_audio_in;
2835 }
2836 else
2837 {
2838 #if (ALSA_PRESENT == 1)
2839 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
2840 {
2841 char rx_out_plughw_pcm_name [MAX_ALSADEV];
2842 char rx_out_hw_pcm_name [MAX_ALSADEV];
2843 // We have to call this first, otherwise linrad would exit after this error:
2844 // (snd_config_hooks_call) Cannot open shared library
2845 // libasound_module_conf_pulse.so (32 bit xlinrad under 64 bit debian wheezy)
2846 err=alsa_get_dev_names (ui.rx_dadev_no);
2847 //get plughw_pcm_name corresponding with ui definition
2848 alsar_get_dev_pcm_names(ui.rx_dadev_no,rx_out_plughw_pcm_name,rx_out_hw_pcm_name );
2849 err=snd_pcm_open(&rx_da_handle, rx_out_plughw_pcm_name,
2850 SND_PCM_STREAM_PLAYBACK, 0);
2851 if(err < 0)
2852 {
2853 lirerr(1304);
2854 return;
2855 }
2856 // use rx_audio_out as switch for compatibility reasons with the existing OSS logic
2857 rx_audio_out=1; //(int)rx_da_handle;
2858 }
2859 else
2860 #endif
2861 {
2862 #if HAVE_OSS == 1
2863 make_devname(ui.rx_dadev_no, ss);
2864 if(kill_all_flag)return;
2865 rx_audio_out=open( ss ,ui.rx_damode|O_EXCL , 0);
2866 #endif
2867 }
2868 if(rx_audio_out == -1)
2869 {
2870 if(diskread_flag==2)
2871 {
2872 lirerr(1191);
2873 }
2874 else
2875 {
2876 lirerr(1017);
2877 }
2878 return;
2879 }
2880 set_da:;
2881 #if (ALSA_PRESENT == 1)
2882 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
2883 {
2884 //*********************************************************************
2885 //******************** SET PLAYBACK PARAMETERS THE ALSA WAY ******
2886 //*********************************************************************
2887 err=snd_pcm_hw_params_malloc (&hw_da_params);
2888 if(err < 0)
2889 {
2890 lirerr(1305);
2891 return;
2892 }
2893 err=snd_pcm_hw_params_any(rx_da_handle, hw_da_params);
2894 if(err < 0)
2895 {
2896 lirerr(1306);
2897 return;
2898 }
2899 // Interleaved mode
2900 err=snd_pcm_hw_params_set_access(rx_da_handle, hw_da_params,
2901 SND_PCM_ACCESS_RW_INTERLEAVED);
2902 if(err < 0)
2903 {
2904 lirerr(1307);
2905 return;
2906 }
2907 // Set sample format
2908 if(rx_daout_bytes == 1)
2909 {
2910 format=SND_PCM_FORMAT_U8;
2911 }
2912 else
2913 {
2914 format=SND_PCM_FORMAT_S16_LE;
2915 }
2916 err=snd_pcm_hw_params_set_format(rx_da_handle, hw_da_params,format);
2917 if(err < 0)
2918 {
2919 lirerr(1308);
2920 return;
2921 }
2922 // Set number of da_channels
2923 err=snd_pcm_hw_params_set_channels(rx_da_handle,
2924 hw_da_params,
2925 (unsigned int)rx_daout_channels);
2926 if(err <0 )
2927 {
2928 lirerr(1309);
2929 return;
2930 }
2931 // Set sample rate
2932 // first disable hardware resample
2933 resample=0;
2934 err=snd_pcm_hw_params_set_rate_resample(
2935 rx_da_handle,
2936 hw_da_params,
2937 (unsigned int)resample);
2938 if(err < 0)
2939 {
2940 lirerr(1310);
2941 return;
2942 }
2943 // now set sample rate
2944 val=(unsigned int)genparm[DA_OUTPUT_SPEED];
2945 err=snd_pcm_hw_params_set_rate_near(rx_da_handle,hw_da_params, &val, 0);
2946 if(err < 0)
2947 {
2948 lirerr(1311);
2949 return;
2950 }
2951 t1=(float)(val)/(float)genparm[DA_OUTPUT_SPEED];
2952 if(t1 > 1.05 || t1 < 0.95)
2953 {
2954 lirerr(1023);
2955 return;
2956 }
2957 genparm[DA_OUTPUT_SPEED]=(int)val;
2958 dir=0;
2959 // obtained value is <,=,> target-value, according value of dir (-1,0,1)
2960 err=snd_pcm_hw_params_set_period_size_near(rx_da_handle, hw_da_params,
2961 (snd_pcm_uframes_t*)((void*)&snd[RXDA].block_frames), &dir);
2962 if(err < 0)
2963 {
2964 lirerr(1312);
2965 return;
2966 }
2967 // check obtained period size
2968 err=snd_pcm_hw_params_get_period_size(hw_da_params, (snd_pcm_uframes_t*)
2969 ((void*)&snd[RXDA].block_frames), &dir);
2970 if(err < 0)
2971 {
2972 DEB"\nopen_rx_sndout:Unable to get period size for playback: %s\n",
2973 snd_strerror(err));
2974 lirerr(53841);
2975 return;
2976 }
2977 // set the hw parameters
2978 err=snd_pcm_hw_params(rx_da_handle, hw_da_params);
2979 if(err < 0)
2980 {
2981 lirerr(1313);
2982 return;
2983 }
2984 // free the memory for the hardware parameter struct
2985 snd_pcm_hw_params_free(hw_da_params);
2986
2987 snd[RXDA].block_frames=snd[RXDA].block_bytes/snd[RXDA].framesize;
2988 // get buffersize
2989 err=snd_pcm_get_params ( rx_da_handle,
2990 (snd_pcm_uframes_t*)((void*)&snd[RXDA].tot_frames),
2991 (snd_pcm_uframes_t*)((void*)&snd[RXDA].block_frames) );
2992 snd[RXDA].tot_bytes=snd[RXDA].tot_frames*snd[RXDA].framesize;
2993 snd[RXDA].no_of_blocks=snd[RXDA].tot_frames/snd[RXDA].framesize;
2994 if(err < 0)
2995 {
2996 lirerr(1313);
2997 return;
2998 }
2999 goto alsacont;
3000 }
3001 else
3002 #endif
3003 {
3004 #if HAVE_OSS == 1
3005 frag=-1;
3006 i=snd[RXDA].block_bytes;
3007 while(i>0)
3008 {
3009 i>>=1;
3010 frag++;
3011 }
3012 if(frag < 4)frag=4;
3013 frag|=0x7fff0000;
3014 if(ioctl(rx_audio_out,SNDCTL_DSP_SETFRAGMENT,&frag)==-1)
3015 {
3016 lirerr(1018);
3017 return;
3018 }
3019 if(rx_daout_bytes == 1)
3020 {
3021 i=AFMT_U8;
3022 }
3023 else
3024 {
3025 i=AFMT_S16_LE;
3026 }
3027 j=i;
3028 if(ioctl(rx_audio_out, SNDCTL_DSP_SETFMT, &i) == -1)
3029 {
3030 lirerr(1020);
3031 return;
3032 }
3033 if(i != j)
3034 {
3035 lirerr(1021);
3036 return;
3037 }
3038 i=rx_daout_channels;
3039 if(ioctl(rx_audio_out, SNDCTL_DSP_CHANNELS, &i) == -1)
3040 {
3041 lirerr(1019);
3042 return;
3043 }
3044 if(i != rx_daout_channels)
3045 {
3046 lirerr(1099);
3047 return;
3048 }
3049 i=genparm[DA_OUTPUT_SPEED];
3050 if(i > 0)
3051 {
3052 if(ioctl(rx_audio_out, SNDCTL_DSP_SPEED, &i)==-1)
3053 {
3054 lirerr(1022);
3055 return;
3056 }
3057 t1=(float)(i)/(float)genparm[DA_OUTPUT_SPEED];
3058 if(t1 > 1.05 || t1 < 0.95)
3059 {
3060 lirerr(1023);
3061 return;
3062 }
3063 genparm[DA_OUTPUT_SPEED]=i;
3064 }
3065 #endif
3066 }
3067 }
3068 bufalloc:;
3069 if( (ui.use_alsa&PORTAUDIO_RX_OUT) != 0)
3070 {
3071 return;
3072 }
3073 #if HAVE_OSS == 1
3074 // We have to write to the output because
3075 // 4Front OSS requires a write before it will return
3076 // correct buffer information with the ioctl call.
3077 tmpbuf=malloc((size_t)snd[RXDA].block_bytes);
3078 if(rx_daout_bytes == 1)
3079 {
3080 cc=(char)0x80;
3081 }
3082 else
3083 {
3084 cc=0;
3085 }
3086 memset(tmpbuf,cc,(size_t)snd[RXDA].block_bytes);
3087 zrw=write(rx_audio_out,tmpbuf,(size_t)snd[RXDA].block_bytes);
3088 zrw=write(rx_audio_out,tmpbuf,(size_t)snd[RXDA].block_bytes);
3089 free(tmpbuf);
3090 if(ioctl(rx_audio_out,SNDCTL_DSP_GETOSPACE, &rx_da_info) == -1)lirerr(856432);
3091 snd[RXDA].tot_bytes=rx_da_info.fragstotal*rx_da_info.fragsize;
3092 snd[RXDA].tot_frames=snd[RXDA].tot_bytes/snd[RXDA].framesize;
3093 if(rx_da_info.fragsize != snd[RXDA].block_bytes)
3094 {
3095 snd[RXDA].block_bytes=rx_da_info.fragsize;
3096 }
3097 snd[RXDA].block_frames=snd[RXDA].block_bytes/snd[RXDA].framesize;
3098 #endif
3099 #if (ALSA_PRESENT == 1)
3100 alsacont:;
3101 #endif
3102 snd[RXDA].interrupt_rate=(float)
3103 (snd[RXDA].framesize*genparm[DA_OUTPUT_SPEED])/
3104 (float)(snd[RXDA].block_bytes);
3105 DEB" Actual %f \n",snd[RXDA].interrupt_rate);
3106 snd[RXDA].no_of_blocks=snd[RXDA].tot_bytes/snd[RXDA].block_bytes;
3107 }
3108
3109 #define SDI_COL 78
3110
display_sdi(void)3111 void display_sdi(void)
3112 {
3113 FILE *sdifile;
3114 char *p;
3115 char work_line [80];
3116 int sdi_screen_line_counter;
3117 char sdi_intro_msg [26]= "SOUND DRIVER INFORMATION:" ;
3118 char sdi_error_msg [46]= "No OSS or ALSA sound-driver information found";
3119 char sndstat_filename [25];
3120 char sndlog_sep [80];
3121 if(screen_last_col < SDI_COL+30)return;
3122 memset (sndlog_sep,'-',sizeof(sndlog_sep));
3123 sndlog_sep[0]='\n';
3124 sndlog_sep[79]='\0';
3125 SNDLOG "%s",sndlog_sep);
3126 SNDLOG"\n%s ", sdi_intro_msg );
3127 settextcolor(YELLOW);
3128 lir_text(SDI_COL, 0, sdi_intro_msg );
3129 sdi_screen_line_counter=1;
3130 // Look for OSS-driver info
3131 strcpy (sndstat_filename,"/dev/sndstat");
3132 sdifile=fopen ( sndstat_filename,"r");
3133 // if OSS not active, try ALSA
3134 if(sdifile==NULL)
3135 {
3136 strcpy (sndstat_filename,"/proc/asound/oss/sndstat");
3137 sdifile=fopen (sndstat_filename,"r");
3138 }
3139 if(sdifile!=NULL)
3140 {
3141 SNDLOG"\n(output of 'cat %s' command): \n\n",sndstat_filename );
3142 settextcolor(LIGHT_GREEN);
3143 while(fgets(work_line, sizeof(work_line)-1, sdifile) != NULL &&
3144 sdi_screen_line_counter < screen_last_line)
3145 {
3146 // check if work_line is ready for output processing
3147 p=strchr(work_line, '\n');
3148 if(p != NULL)p[0]=0;
3149 if(*work_line != '\0')
3150 {
3151 // display work_line only if it is not blank
3152 // and there are enough lines available on the screen
3153 // and there are at least 40 characters available on a line
3154 if(sdi_screen_line_counter < screen_last_line &&
3155 (screen_last_col - 40)>= 80)
3156 {
3157 sdi_screen_line_counter++;
3158 lir_text (SDI_COL, sdi_screen_line_counter, work_line);
3159 }
3160 // write to soundboard_init.log
3161 SNDLOG"%s\n",work_line);
3162 }
3163 }
3164 fclose(sdifile);
3165 }
3166 else
3167 {
3168 settextcolor(LIGHT_RED);
3169 lir_text( SDI_COL, sdi_screen_line_counter++, sdi_error_msg);
3170 SNDLOG"\n%s",sdi_error_msg );
3171 }
3172 SNDLOG"%s",sndlog_sep);
3173 sndlog_sync();
3174 settextcolor(7);
3175 }
3176
3177 #if HAVE_OSS == 1
ossdev_show(char * ss,int no,int minrate,int maxrate,int chan,int byte,char * modes)3178 void ossdev_show(char *ss, int no, int minrate, int maxrate,
3179 int chan, int byte, char *modes)
3180 {
3181 int i, j, k;
3182 sprintf(ss," %02d %s ",no, dev_name);
3183 sprintf(&ss[22],"%d/%d ",minrate,maxrate);
3184 i=40;
3185 k=1;
3186 while(k < 8)
3187 {
3188 if(chan&k)
3189 {
3190 sprintf(&ss[i],"%d ",k);
3191 i+=2;
3192 }
3193 k*=2;
3194 }
3195 k=1;
3196 i=49;
3197 while(k < 8)
3198 {
3199 if(byte&k)
3200 {
3201 sprintf(&ss[i],"%d ",k);
3202 i+=2;
3203 }
3204 k*=2;
3205 }
3206 if(modes == NULL)
3207 {
3208 i=57;
3209 for(j=0; j<3; j++)
3210 {
3211 k=1<<j;
3212 if( (dev_flag[no]&k) != 0)
3213 {
3214 sprintf(&ss[i],"%s ",devmode_txt[j]);
3215 while(ss[i] != 0)i++;
3216 }
3217 }
3218 }
3219 else
3220 {
3221 sprintf(&ss[57],"%s ",modes);
3222 }
3223 }
3224
log_output_mode(int no)3225 void log_output_mode(int no)
3226 {
3227 SNDLOG"\n%s opened as %s ",dev_name, devmode_txt[no]);
3228 sndlog_sync();
3229 }
3230
3231
select_rdwr_mode(int * line,int no,int mode)3232 int select_rdwr_mode(int *line, int no, int mode)
3233 {
3234 int m, k;
3235 char s[80];
3236 if(mode == O_RDONLY)
3237 {
3238 k=DEVFLAG_R;
3239 }
3240 else
3241 {
3242 k=DEVFLAG_W;
3243 }
3244 m=mode;
3245 if( (dev_flag[no]&DEVFLAG_RW) != 0)
3246 {
3247 if( (dev_flag[no]&k) != 0)
3248 {
3249 line[0]++;
3250 gt_rdo:;
3251 sprintf(s,"Open %s as RDWR? (Y/N) =>",dev_name);
3252 lir_text(10,line[0],s);
3253 await_processed_keyboard();
3254 if(kill_all_flag)return 0;
3255 if(lir_inkey == 'Y')
3256 {
3257 line[0]++;
3258 settextcolor(14);
3259 lir_text(0,line[0],
3260 "RDWR mode is limited and less reliable. Are you sure? (Y/N) =>");
3261 await_processed_keyboard();
3262 settextcolor(7);
3263 if(kill_all_flag)return 0;
3264 if(lir_inkey == 'Y')
3265 {
3266 goto rdwr;
3267 }
3268 clear_lines(line[0],line[0]);
3269 line[0]--;
3270 goto gt_rdo;
3271 }
3272 if(lir_inkey != 'N')goto gt_rdo;
3273 SNDLOG"\nUser selected RDONLY");
3274 }
3275 else
3276 {
3277 rdwr:;
3278 m=O_RDWR;
3279 SNDLOG"\nUser selected RDWR");
3280 }
3281 line[0]++;
3282 }
3283 else
3284 {
3285 SNDLOG"\nRDWR not available");
3286 }
3287 return m;
3288 }
3289
show_oss_presel(int * line,int suggested_dev)3290 void show_oss_presel(int *line, int suggested_dev)
3291 {
3292 char s[80];
3293 clear_lines(0,0);
3294 line[0]++;
3295 make_devname(suggested_dev, dev_name);
3296 if(kill_all_flag)return;
3297 sprintf(s,"%s auto-selected. There is no other alternative.", dev_name);
3298 lir_text(0,line[0],s);
3299 line[0]++;
3300 }
3301
select_ossdev(int * line,int sound_type)3302 void select_ossdev(int *line, int sound_type)
3303 {
3304 int iohandle;
3305 int caps;
3306 int i, j, k, m, n, nn;
3307 char ss[3*MAX_COLUMN];
3308 int mode, rdwr_fmt, device_no;
3309 int rdwr_min_speed;
3310 int rdwr_max_speed;
3311 audio_buf_info ad_info;
3312 char *rdtest_buffer;
3313 int rdwr_channels, suggested_dev;
3314 int dev_rdwr_channels[MAX_DEVNAMES];
3315 int dev_max_rdwr_speed[MAX_DEVNAMES];
3316 int dev_min_rdwr_speed[MAX_DEVNAMES];
3317 int dev_rdwr_bytes[MAX_DEVNAMES];
3318 int column, maxcolumn, bottom_line;
3319 int devflag_val;
3320 char s[256];
3321 char color[3];
3322 int h_test;
3323 int h_test2;
3324 h_test=-1;
3325 h_test2=-1;
3326 rdtest_buffer=malloc(2048);
3327 if(rdtest_buffer == NULL)
3328 {
3329 lirerr(1044);
3330 return;
3331 }
3332 n=0;
3333 suggested_dev=-1;
3334 maxcolumn=screen_last_xpixel/text_width-1;
3335 if(maxcolumn > MAX_COLUMN)maxcolumn=MAX_COLUMN;
3336 bottom_line=0;
3337 line[0]++;
3338 sprintf(s,"Dev device sample-rate channels bytes modes");
3339 SNDLOG"%s\n",s);
3340 lir_text(0,line[0],s);
3341 line[0]++;
3342 sprintf(s," no file min / max");
3343 SNDLOG"%s\n",s);
3344 lir_text(0, line[0],s);
3345 line[0]++;
3346 sprintf(s," -- --------------- -------------- ------- ------- -------------------" );
3347 SNDLOG"%s\n",s);
3348 lir_text(0,line[0],s);
3349 line[0]++;
3350 for(device_no=0; device_no<MAX_DEVNAMES; device_no++)
3351 {
3352 lir_sched_yield();
3353 dev_flag[device_no]=0;
3354 make_devname(device_no, dev_name);
3355 SNDLOG"Checking %s\n",dev_name);
3356 if(kill_all_flag)goto sel_ossdev_skip;
3357 if(device_no == (ui.rx_addev_no&255) && ui.rx_admode == O_RDWR)
3358 {
3359 if(ui.rx_dadev_no != device_no && ui.tx_dadev_no != device_no)
3360 {
3361 k=2;
3362 if( (ui.rx_input_mode&DWORD_INPUT) )k=4;
3363 ossdev_show(ss, device_no, ui.rx_ad_speed, ui.rx_ad_speed,
3364 ui.rx_ad_channels, k,"RDWR used by RXin");
3365 settextcolor(10);
3366 line[0]++;
3367 lir_text(0,line[0],ss);
3368 lir_refresh_screen();
3369 dev_flag[device_no]=DEVFLAG_RW;
3370 n++;
3371 suggested_dev=device_no;
3372 }
3373 else
3374 {
3375 dev_flag[device_no]=0;
3376 }
3377 goto used_rdwr;
3378 }
3379 if(sound_type == TXAD &&
3380 device_no == ui.rx_dadev_no &&
3381 ui.rx_damode == O_RDWR)
3382 {
3383 ossdev_show(ss, device_no, ui.rx_min_da_speed, ui.rx_max_da_speed,
3384 ui.rx_min_da_channels, 2,"RDWR used by RXout");
3385 settextcolor(10);
3386 line[0] ++;
3387 lir_text(0,line[0],ss);
3388 lir_refresh_screen();
3389 dev_flag[device_no]=DEVFLAG_RW;
3390 goto used_rdwr;
3391 }
3392 sndlog_sync();
3393 for(mode=0; mode<3; mode++)
3394 {
3395 rdwr_max_speed=0;
3396 rdwr_min_speed=0;
3397 devflag_val=1<<mode;
3398 sprintf(s,
3399 "Trying to open %s %s. Device defective if system hangs here. Read %s ",
3400 dev_name, devmode_txt[mode],rx_logfile_name);
3401 sndlog_sync();
3402 settextcolor(12);
3403 lir_text(0,line[0]+1,s);
3404 lir_refresh_screen();
3405 settextcolor(7);
3406 iohandle=open( dev_name, devmodes[mode]|O_NONBLOCK|O_EXCL, 0);
3407 clear_lines(line[0]+1,line[0]+1);
3408 if(iohandle != -1)
3409 {
3410 #ifdef SNDCTL_DSP_COOKEDMODE
3411 i=0;
3412 ioctl(iohandle, SNDCTL_DSP_COOKEDMODE, &i);
3413 #endif
3414 for(nn=0; nn<80; nn++)SNDLOG"-");
3415 log_output_mode(mode);
3416 rdwr_fmt=0;
3417 rdwr_channels=0;
3418 // Check for 16 bits
3419 if( ioctl(iohandle, SNDCTL_DSP_GETFMTS, &m) == -1)
3420 {
3421 SNDLOG"\nioctl(GETFMTS) failed");
3422 baddev:;
3423 sndlog_sync();
3424 devflag_val=0;
3425 goto cls;
3426 }
3427 if( (m&AFMT_U8) ==0)
3428 {
3429 SNDLOG"\n8bit format NOT supported");
3430 }
3431 else
3432 {
3433 SNDLOG"\n8bit format supported");
3434 rdwr_fmt|=1;
3435 }
3436 if( (m&AFMT_S16_LE) == 0)
3437 {
3438 SNDLOG"\n16bit format NOT supported");
3439 }
3440 else
3441 {
3442 SNDLOG"\n16bit format supported");
3443 rdwr_fmt|=2;
3444 }
3445 #ifdef AFMT_S32_LE
3446 // Check for 32 bits
3447 if( (m&AFMT_S32_LE) != 0)
3448 {
3449 rdwr_fmt|=4;
3450 devflag_val=1<<mode;
3451 SNDLOG"\n32bit format supported");
3452 }
3453 else
3454 {
3455 SNDLOG"\n32bit format NOT supported");
3456 }
3457 #endif
3458 sndlog_sync();
3459 if(rdwr_fmt == 0)
3460 {
3461 devflag_val=0;
3462 goto cls;
3463 }
3464 // Find max no of channels.
3465 // We never want more than 4 input channels!!
3466 rdwr_channels=0;
3467 m=4;
3468 while(m > 0)
3469 {
3470 k=m;
3471 j=ioctl(iohandle, SNDCTL_DSP_CHANNELS, &k);
3472 if(j != -1 && k == m)rdwr_channels|=k;
3473 m/=2;
3474 }
3475 if(rdwr_channels == 0)
3476 {
3477 k=0;
3478 SNDLOG"\nMax no of channels = 0");
3479 goto baddev;
3480 }
3481 else
3482 {
3483 SNDLOG"\nChannels = %d",rdwr_channels);
3484 }
3485 sndlog_sync();
3486 //
3487 // To allow a separate #ifdef __FreeBSD__
3488 // - Diane Bruce VA3DB, Sept 6, 2006
3489 //
3490 #ifdef __linux__
3491 // Find maximum speed
3492 rdwr_max_speed=ABOVE_MAX_SPEED;
3493 if(ioctl(iohandle, SNDCTL_DSP_SPEED, &rdwr_max_speed)==-1)
3494 {
3495 SNDLOG"\nioctl(SPEED) failed (max)");
3496 goto baddev;
3497 }
3498 SNDLOG"\nMax speed %d Hz",rdwr_max_speed);
3499 // Find minimum speed
3500 i=0;
3501 while(i<MAX_LOWSPEED)
3502 {
3503 rdwr_min_speed=low_speeds[i];
3504 if(ioctl(iohandle, SNDCTL_DSP_SPEED, &rdwr_min_speed)!=-1)
3505 goto minok;
3506 i++;
3507 }
3508 lirerr(1040);
3509 goto sel_ossdev_skip;
3510 minok:;
3511 #endif
3512 //
3513 // This code finds min max speed of sound card for FreeBSD
3514 // It probably works for other BSDs as well
3515 // Diane Bruce, db@db.net VA3DB
3516 // Sept 7, 2006
3517 //
3518 #ifdef __FreeBSD__
3519 {
3520 snd_capabilities capab;
3521 int status;
3522 bzero((void *)&capab, sizeof(capab));
3523 status=ioctl(iohandle, AIOGCAP, &capab);
3524 if(status < 0)goto sel_ossdev_skip;
3525 rdwr_min_speed=capab.rate_min;
3526 rdwr_max_speed=capab.rate_max;
3527 SNDLOG"\nMax sampling speed %d", rdwr_max_speed);
3528 }
3529 #endif
3530 SNDLOG"\nMin sampling speed = %d Hz",rdwr_min_speed);
3531 sndlog_sync();
3532 if(sound_type == RXAD)
3533 {
3534 //devmode_txt[3]={"RDONLY","WRONLY","RDWR"};
3535 if(mode != DEVMODE_WRONLY)
3536 {
3537 if(ioctl(iohandle, SNDCTL_DSP_GETISPACE, &ad_info) == -1)
3538 {
3539 SNDLOG"\nioctl(GETISPACE) failed");
3540 goto baddev;
3541 }
3542 // If it is opened RDWR, check we have a chance to write while reading
3543 // Some devices allow write or read in rdwr mode - but not simultaneously.
3544 if(mode == DEVMODE_RDWR)
3545 {
3546 zrw=read(iohandle, rdtest_buffer, 128);
3547 if(ioctl(iohandle,SNDCTL_DSP_GETOSPACE, &ad_info) == -1)
3548 {
3549 SNDLOG"\nioctl(GETOSPACE) failed while reading");
3550 goto baddev;
3551 }
3552 }
3553 }
3554 }
3555 cls:;
3556 if(close(iohandle)==-1)
3557 {
3558 sndlog_sync();
3559 lirerr(1037);
3560 goto sel_ossdev_skip;
3561 }
3562 if(devflag_val != 0)
3563 {
3564 if(sound_type == RXAD || sound_type == TXAD)
3565 {
3566 if(devflag_val != 2)
3567 {
3568 suggested_dev=device_no;
3569 n++;
3570 }
3571 }
3572 if( sound_type == RXDA || sound_type == TXDA)
3573 {
3574 if(devflag_val != 1)
3575 {
3576 suggested_dev=device_no;
3577 n++;
3578 }
3579 }
3580 dev_flag[device_no]|=devflag_val;
3581 switch (mode)
3582 {
3583 case DEVMODE_RDONLY:
3584 dev_rd_channels[device_no]=rdwr_channels;
3585 dev_max_rd_speed[device_no]=rdwr_max_speed;
3586 dev_min_rd_speed[device_no]=rdwr_min_speed;
3587 dev_rd_bytes[device_no]=rdwr_fmt;
3588 break;
3589
3590 case DEVMODE_WRONLY:
3591 dev_wr_channels[device_no]=rdwr_channels;
3592 dev_max_wr_speed[device_no]=rdwr_max_speed;
3593 dev_min_wr_speed[device_no]=rdwr_min_speed;
3594 dev_wr_bytes[device_no]=rdwr_fmt;
3595 break;
3596
3597 case DEVMODE_RDWR:
3598 dev_rdwr_channels[device_no]=rdwr_channels;
3599 dev_max_rdwr_speed[device_no]=rdwr_max_speed;
3600 dev_min_rdwr_speed[device_no]=rdwr_min_speed;
3601 dev_rdwr_bytes[device_no]=rdwr_fmt;
3602 break;
3603 }
3604 }
3605 SNDLOG"\n");
3606 }
3607 }
3608 if(dev_flag[device_no] != 0)
3609 {
3610 SNDLOG"\nFLAG= %d",dev_flag[device_no]);
3611 // One device may be different hardwares for input and output.
3612 // Put them on different lines if characteristics differ.
3613 k=0;
3614 j=0;
3615 // Store equal pairs in k
3616 // bit 0=1 => READ==WRITE
3617 // bit 1=1 => READ==RDWR
3618 // bit 2=1 => WRITE==RDWR
3619 if( (dev_flag[device_no]&(DEVFLAG_R+DEVFLAG_W)) == DEVFLAG_R+DEVFLAG_W)
3620 {
3621 j|=1;
3622 if(dev_rd_channels[device_no]==dev_wr_channels[device_no] &&
3623 dev_max_rd_speed[device_no]==dev_max_wr_speed[device_no] &&
3624 dev_min_rd_speed[device_no]==dev_min_wr_speed[device_no] &&
3625 dev_rd_bytes[device_no]==dev_wr_bytes[device_no]) k|=1;
3626 }
3627 if( (dev_flag[device_no]&(DEVFLAG_R+DEVFLAG_RW)) == DEVFLAG_R+DEVFLAG_RW)
3628 {
3629 j|=2;
3630 if(dev_rd_channels[device_no]==dev_rdwr_channels[device_no] &&
3631 dev_max_rd_speed[device_no]==dev_max_rdwr_speed[device_no] &&
3632 dev_min_rd_speed[device_no]==dev_min_rdwr_speed[device_no] &&
3633 dev_rd_bytes[device_no]==dev_rdwr_bytes[device_no])k|=2;
3634 }
3635 if( (dev_flag[device_no]&(DEVFLAG_W+DEVFLAG_RW)) == DEVFLAG_W+DEVFLAG_RW)
3636 {
3637 j|=4;
3638 if(dev_wr_channels[device_no]==dev_rdwr_channels[device_no] &&
3639 dev_max_wr_speed[device_no]==dev_max_rdwr_speed[device_no] &&
3640 dev_min_wr_speed[device_no]==dev_min_rdwr_speed[device_no] &&
3641 dev_wr_bytes[device_no]==dev_rdwr_bytes[device_no])k|=4;
3642 }
3643 SNDLOG"\nj=%d k=%d",j,k);
3644 if(j == k)
3645 {
3646 // There are no differences between devices. Put everything on one line.
3647 m=1;
3648 if( (dev_flag[device_no]&DEVFLAG_R) == DEVFLAG_R)
3649 {
3650 ossdev_show(ss, device_no,
3651 dev_min_rd_speed[device_no],
3652 dev_max_rd_speed[device_no],
3653 dev_rd_channels[device_no],
3654 dev_rd_bytes[device_no],NULL);
3655 }
3656 else
3657 {
3658 if( (dev_flag[device_no]&DEVFLAG_W) == DEVFLAG_W)
3659 {
3660 ossdev_show(ss, device_no,
3661 dev_min_wr_speed[device_no],
3662 dev_max_wr_speed[device_no],
3663 dev_wr_channels[device_no],
3664 dev_wr_bytes[device_no],NULL);
3665 }
3666 }
3667 if(sound_type == RXAD || sound_type == TXAD)
3668 {
3669 if( (dev_flag[device_no]&(DEVFLAG_R+DEVFLAG_RW)) == 0)
3670 {
3671 color[0]=0x17;
3672 }
3673 else
3674 {
3675 color[0]=0x1c;
3676 }
3677 }
3678 else
3679 {
3680 if( (dev_flag[device_no]&(DEVFLAG_W+DEVFLAG_RW)) == 0)
3681 {
3682 color[0]=0x17;
3683 }
3684 else
3685 {
3686 color[0]=0x1c;
3687 }
3688 }
3689 }
3690 else
3691 {
3692 // There are differences.
3693 // We can not arrive here unless there are at least two modes
3694 // and consequently j can not be zero.
3695 if( (j&1) == 0)
3696 {
3697 // We do not have both read and write so it is one of them plus rdwr.
3698 // This does not seem right, but we present the info we get to the user.
3699 color[0]=0x1c;
3700 m=2;
3701 ossdev_show(ss, device_no,
3702 dev_min_rdwr_speed[device_no],
3703 dev_max_rdwr_speed[device_no],
3704 dev_rdwr_channels[device_no],
3705 dev_rdwr_bytes[device_no],devmode_txt[2]);
3706 if( (dev_flag[device_no]&DEVFLAG_R) == 0)
3707 {
3708 if(sound_type == RXAD || sound_type == TXAD)
3709 {
3710 color[1]=0x17;
3711 }
3712 else
3713 {
3714 color[1]=0x1c;
3715 }
3716 ossdev_show(&ss[maxcolumn], device_no,
3717 dev_min_wr_speed[device_no],
3718 dev_max_wr_speed[device_no],
3719 dev_wr_channels[device_no],
3720 dev_wr_bytes[device_no],devmode_txt[1]);
3721 }
3722 else
3723 {
3724 if(sound_type == RXAD || sound_type == TXAD)
3725 {
3726 color[1]=0x1c;
3727 }
3728 else
3729 {
3730 color[1]=0x17;
3731 }
3732 ossdev_show(&ss[maxcolumn], device_no,
3733 dev_min_rd_speed[device_no],
3734 dev_max_rd_speed[device_no],
3735 dev_rd_channels[device_no],
3736 dev_rd_bytes[device_no],devmode_txt[0]);
3737 }
3738 }
3739 else
3740 {
3741 // There is both read and write.
3742 if( (dev_flag[device_no]&DEVFLAG_RW) == 0)
3743 {
3744 // but there is no rdwr
3745 m=2;
3746 if(sound_type == RXAD || sound_type == TXAD)
3747 {
3748 color[1]=0x17;
3749 color[0]=0x1c;
3750 }
3751 else
3752 {
3753 color[1]=0x1c;
3754 color[0]=0x17;
3755 }
3756 ossdev_show(&ss[maxcolumn], device_no,
3757 dev_min_wr_speed[device_no],
3758 dev_max_wr_speed[device_no],
3759 dev_wr_channels[device_no],
3760 dev_wr_bytes[device_no],devmode_txt[1]);
3761 ossdev_show(ss, device_no,
3762 dev_min_rd_speed[device_no],
3763 dev_max_rd_speed[device_no],
3764 dev_rd_channels[device_no],
3765 dev_rd_bytes[device_no],devmode_txt[0]);
3766 }
3767 else
3768 {
3769 // There is rdwr, read and write.
3770 if(k == 0)
3771 {
3772 // They are all different
3773 m=3;
3774 if(sound_type == RXAD || sound_type == TXAD)
3775 {
3776 color[2]=0x17;
3777 color[1]=0x1c;
3778 }
3779 else
3780 {
3781 color[2]=0x1c;
3782 color[1]=0x17;
3783 }
3784 ossdev_show(&ss[2*maxcolumn], device_no,
3785 dev_min_wr_speed[device_no],
3786 dev_max_wr_speed[device_no],
3787 dev_wr_channels[device_no],
3788 dev_wr_bytes[device_no],devmode_txt[1]);
3789 ossdev_show(&ss[maxcolumn], device_no,
3790 dev_min_rd_speed[device_no],
3791 dev_max_rd_speed[device_no],
3792 dev_rd_channels[device_no],
3793 dev_rd_bytes[device_no],devmode_txt[0]);
3794 color[0]=0x1c;
3795 ossdev_show(ss, device_no,
3796 dev_min_rdwr_speed[device_no],
3797 dev_max_rdwr_speed[device_no],
3798 dev_rdwr_channels[device_no],
3799 dev_rdwr_bytes[device_no],devmode_txt[2]);
3800 }
3801 else
3802 {
3803 // rdwr equals read or write.
3804 m=2;
3805 if( (k&4) == 0)
3806 {
3807 if(sound_type == RXAD || sound_type == TXAD)
3808 {
3809 color[1]=0x17;
3810 color[0]=0x1c;
3811 }
3812 else
3813 {
3814 color[1]=0x1c;
3815 color[0]=0x1c;
3816 }
3817 ossdev_show(&ss[maxcolumn], device_no,
3818 dev_min_wr_speed[device_no],
3819 dev_max_wr_speed[device_no],
3820 dev_wr_channels[device_no],
3821 dev_wr_bytes[device_no],devmode_txt[1]);
3822 ossdev_show(ss, device_no,
3823 dev_min_rd_speed[device_no],
3824 dev_max_rd_speed[device_no],
3825 dev_rd_channels[device_no],
3826 dev_rd_bytes[device_no],
3827 devmode_txt[0]);
3828 strcat(ss,devmode_txt[2]);
3829 }
3830 else
3831 {
3832 if(sound_type == RXAD || sound_type == TXAD)
3833 {
3834 color[1]=0x17;
3835 color[0]=0x1c;
3836 }
3837 else
3838 {
3839 color[1]=0x1c;
3840 color[0]=0x1c;
3841 }
3842 ossdev_show(&ss[maxcolumn], device_no,
3843 dev_min_wr_speed[device_no],
3844 dev_max_wr_speed[device_no],
3845 dev_wr_channels[device_no], dev_wr_bytes[device_no],
3846 devmode_txt[1]);
3847 strcat(ss,devmode_txt[2]);
3848 ossdev_show(ss, device_no,
3849 dev_min_rd_speed[device_no],
3850 dev_max_rd_speed[device_no],
3851 dev_rd_channels[device_no],
3852 dev_rd_bytes[device_no],
3853 devmode_txt[0]);
3854 }
3855 }
3856 }
3857 }
3858 }
3859 while (m >0)
3860 {
3861 m--;
3862 line[0]++;
3863 if(line[0] >= screen_last_line-1)
3864 {
3865 for(column=0; column<maxcolumn; column++)s[column]=' ';
3866 s[maxcolumn]=0;
3867 lir_text(0,line[0],s);
3868 settextcolor(14);
3869 lir_text(10,line[0],"(press ENTER to continue)");
3870 settextcolor(7);
3871 await_keyboard();
3872 if(kill_all_flag) goto sel_ossdev_skip;
3873 lir_text(0,line[0],s);
3874 bottom_line=screen_last_line-1;
3875 line[0]=1;
3876 }
3877 column=0;
3878 while(ss[m*maxcolumn+column]!=0)column++;
3879 while(column < maxcolumn)
3880 {
3881 ss[m*maxcolumn+column]=' ';
3882 column++;
3883 }
3884 ss[(m+1)*maxcolumn-1]=0;
3885 settextcolor((unsigned char)color[m]);
3886 lir_text(0,line[0],&ss[m*maxcolumn]);
3887 lir_refresh_screen();
3888 SNDLOG"\n%s color=%d m=%d",&ss[m*maxcolumn],color[m],m);
3889 }
3890 SNDLOG"\n");
3891 }
3892 used_rdwr: ;
3893 }
3894 settextcolor(7);
3895 line[0]++;
3896 clear_lines(line[0],line[0]);
3897 if(bottom_line > line[0])line[0]=bottom_line;
3898 display_sdi();
3899 if(sound_type == TXDA)
3900 {
3901 if(n == 0)
3902 {
3903 ui.tx_dadev_no=UNDEFINED_DEVICE_CODE;
3904 lir_text(0,line[0],"No device found for Tx output");
3905 lir_text(2,line[0]+1,"ERROR (press any key)");
3906 await_keyboard();
3907 goto sel_ossdev_skip;
3908 }
3909 line[0]++;
3910 lir_text(10,line[0],"=>");
3911 get_tx_dadev:;
3912 ui.tx_dadev_no=lir_get_integer(13, line[0], 3, 0,MAX_DEVNAMES-1);
3913 if(kill_all_flag) goto sel_ossdev_skip;
3914 if( (dev_flag[ui.tx_dadev_no]&(DEVFLAG_W+DEVFLAG_RW)) == 0)
3915 {
3916 settextcolor(15);
3917 lir_text(29,line[0],"???");
3918 lir_text(25,line[0]+1,"ERROR (press any key)");
3919 await_keyboard();
3920 if(kill_all_flag) goto sel_ossdev_skip;
3921 clear_lines(line[0]+1,line[0]+1);
3922 goto get_tx_dadev;
3923 }
3924 line[0]+=2;
3925 }
3926 if(sound_type == RXDA)
3927 {
3928 if(n == 0)
3929 {
3930 if(soundcard_test_cmd_flag[RXAD] != THRFLAG_ACTIVE)
3931 {
3932 line[0]++;
3933 lir_text(0,line[0],"No usable device found");
3934 goto sel_ossdev_skip;
3935 }
3936 if(line[0] > screen_last_line-6)line[0]=screen_last_line-6;
3937 lir_text(0,line[0],
3938 "No device found for 1/2 byte output while input is open.");
3939 lir_text(0,line[0]+1,
3940 "You may use Linrad to watch spectra and record raw data.");
3941 lir_text(0,line[0]+2,
3942 "Linrad will now look for devices that can be used to");
3943 lir_text(0,line[0]+3,
3944 "output sound while processing recorded data.");
3945 lir_text(0,line[0]+4,press_any_key);
3946 SNDLOG"\nNo output device found while input is open.");
3947 await_keyboard();
3948 clear_lines(line[0],line[0]+4);
3949 goto sel_ossdev_skip;
3950 }
3951 if(n == 1)
3952 {
3953 ui.rx_dadev_no=suggested_dev;
3954 show_oss_presel(line,suggested_dev);
3955 }
3956 if(n > 1)
3957 {
3958 line[0]++;
3959 lir_text(10,line[0],"=>");
3960 get_rx_dadev:;
3961 display_sdi() ;
3962 ui.rx_dadev_no=lir_get_integer(13, line[0], 3, 0,MAX_DEVNAMES-1);
3963 if(kill_all_flag)goto sel_ossdev_skip;
3964 if( (dev_flag[ui.rx_dadev_no]&(DEVFLAG_W+DEVFLAG_RW)) == 0)
3965 {
3966 settextcolor(15);
3967 lir_text(51,line[0],"???");
3968 lir_text(35,line[0]+1,"ERROR (press any key)");
3969 await_keyboard();
3970 if(kill_all_flag) goto sel_ossdev_skip;
3971 clear_lines(line[0],line[0]+1);
3972 goto get_rx_dadev;
3973 }
3974 }
3975 goto sel_ossdev_skip;
3976 }
3977 if(sound_type == TXAD)
3978 {
3979 if(n == 0)
3980 {
3981 lir_text(0,line[0],"No device found for microphone input.");
3982 line[0]++;
3983 lir_text(2,line[0]+1,"ERROR (press any key)");
3984 await_keyboard();
3985 goto sel_ossdev_skip;
3986 }
3987 line[0]++;
3988 lir_text(10,line[0],"=>");
3989 get_micdev:;
3990 ui.tx_addev_no=lir_get_integer(13, line[0], 3, 0,MAX_DEVNAMES-1);
3991 if( (dev_flag[ui.tx_addev_no]&(DEVFLAG_R+DEVFLAG_RW)) == 0)
3992 {
3993 settextcolor(15);
3994 lir_text(37,line[0],"???");
3995 lir_text(25,line[0]+1,"ERROR (press any key)");
3996 await_keyboard();
3997 if(kill_all_flag)goto sel_ossdev_skip;
3998 clear_lines(line[0]+1,line[0]+1);
3999 goto get_micdev;
4000 }
4001 goto sel_ossdev_skip;
4002 }
4003 if(sound_type == RXAD)
4004 {
4005 if(n == 0)
4006 {
4007 if(line[0] > screen_last_line-5)
4008 {
4009 line[0]=screen_last_line-5;
4010 clear_lines(line[0], screen_last_line);
4011 }
4012 lir_text(0,line[0],"No OSS sound device found (for 2/4 byte input).");
4013 line[0]+=2;
4014 #if (ALSA_PRESENT == 1)
4015 lir_text(0,line[0],"ALSA is available, you may press 'Y' to use it.");
4016 #else
4017 lir_text(10,line[0],"ALSA is not available.");
4018 line[0]++;
4019 #endif
4020 line[0]+=2;
4021 lir_text(0,line[0],press_f1_for_info);
4022 line[0]++;
4023 lir_text(20,line[0],press_any_key);
4024 await_processed_keyboard();
4025 if(lir_inkey == F1_KEY || lir_inkey == '!')
4026 {
4027 #if (ALSA_PRESENT == 1)
4028 help_message(332);
4029 #else
4030 help_message(333);
4031 #endif
4032 }
4033 SNDLOG"\nNo input device found");
4034 ui.rx_addev_no=UNDEFINED_DEVICE_CODE;
4035 goto sel_ossdev_skip;
4036 }
4037 if(n == 1)
4038 {
4039 ui.rx_addev_no=suggested_dev;
4040 show_oss_presel(line,suggested_dev);
4041 }
4042 if(n > 1)
4043 {
4044 line[0]++;
4045 lir_text(10,line[0],"=>");
4046 get_rx_addev:;
4047 display_sdi();
4048 ui.rx_addev_no=lir_get_integer(13, line[0], 3, 0,MAX_DEVNAMES-1);
4049 if(kill_all_flag)goto sel_ossdev_skip;
4050 if( (dev_flag[ui.rx_addev_no]&(DEVFLAG_R+DEVFLAG_RW)) == 0)
4051 {
4052 settextcolor(15);
4053 lir_text(51,line[0],"???");
4054 lir_text(35 ,line[0]+1,"ERROR (press any key)");
4055 await_keyboard();
4056 if(kill_all_flag) goto sel_ossdev_skip;
4057 clear_lines(line[0],line[0]+1);
4058 goto get_rx_addev;
4059 }
4060 }
4061 make_devname(ui.rx_addev_no, dev_name);
4062 if(kill_all_flag)goto sel_ossdev_skip;
4063 SNDLOG"\n\n %s selected by user for input.",dev_name);
4064 SNDLOG" dev_flag=%d",dev_flag[ui.rx_addev_no]);
4065 sndlog_sync();
4066 // High end users might need two devices to read four A/D channels.
4067 // This is an option introduced April 2004 to allow two receive
4068 // channels with the Lynx Two card (model A).
4069 // Do not confus e other users by asking for a second input device
4070 // unless the selected device has 32 bits but only allows 2 channels.
4071 if(dev_rd_bytes[ui.rx_addev_no] >= 4 &&
4072 dev_rd_channels[ui.rx_addev_no]==2 &&
4073 (dev_flag[ui.rx_addev_no]&DEVFLAG_R) != 0)
4074 {
4075 SNDLOG"\n\n User selected 4 byte device with max two channels.");
4076 j=0;
4077 clear_lines(1,line[0]);
4078 line[0]=1;
4079 for(i=0; i<MAX_DEVNAMES; i++)
4080 {
4081 if(i != ui.rx_addev_no &&
4082 dev_max_rd_speed[i] == dev_max_rd_speed[ui.rx_addev_no] &&
4083 dev_rd_bytes[i] >= 4 &&
4084 (dev_flag[i]&DEVFLAG_R) != 0)
4085 {
4086 // This device can also read 32 bits at the same speed.
4087 // Check if it can be opened simultaneously in read mode.
4088 if(j==0)
4089 {
4090 line[0]++;
4091 lir_text(5,line[0],"This device allows two channels only.");
4092 line[0]++;
4093 lir_text(5,line[0],"Do you want to use a second device to run two");
4094 line[0]++;
4095 lir_text(5,line[0],"receive channels with four audio channels ?");
4096 line[0]++;
4097 lir_text(5,line[0],"(Y/N)=>");
4098 line[0]++;
4099 gt_dual:;
4100 await_processed_keyboard();
4101 line[0]+=2;
4102 if( kill_all_flag) goto sel_ossdev_skip;
4103 if(lir_inkey == 'N')
4104 {
4105 SNDLOG"\nUser skipped dual devices");
4106 goto skip_dual_devices;
4107 }
4108 if(lir_inkey != 'Y')goto gt_dual;
4109 SNDLOG"\nUser wants to try to open two read devices");
4110 make_devname(ui.rx_addev_no, dev_name);
4111 if(kill_all_flag)goto sel_ossdev_skip;
4112 h_test=open( dev_name, O_RDONLY|O_EXCL, 0);
4113 if(h_test == -1)
4114 {
4115 lirerr(1102);
4116 goto sel_ossdev_skip;
4117 }
4118 #ifdef SNDCTL_DSP_COOKEDMODE
4119 k=0;
4120 ioctl(h_test, SNDCTL_DSP_COOKEDMODE, &k);
4121 #endif
4122 // Check for DSP_CAP_TRIGGER capability
4123 if(ioctl(h_test, SNDCTL_DSP_GETCAPS,&caps) == -1)
4124 {
4125 lirerr(1182);
4126 goto sel_ossdev_skip;
4127 }
4128 if( (caps&DSP_CAP_TRIGGER) == 0)
4129 {
4130 SNDLOG"\nDevice does not have DSP_CAP_TRIGGER");
4131 close(h_test);
4132 goto skip_dual_devices;
4133 }
4134 j=2;
4135 if(ioctl(h_test, SNDCTL_DSP_CHANNELS, &j) == -1)
4136 {
4137 lirerr(1185);
4138 goto sel_ossdev_skip;
4139 }
4140 if(j != 2)
4141 {
4142 lirerr(1186);
4143 goto sel_ossdev_skip;
4144 }
4145 }
4146 make_devname(i, dev_name);
4147 if(kill_all_flag)goto sel_ossdev_skip;
4148 h_test2=open( dev_name, O_RDONLY|O_NONBLOCK|O_EXCL, 0);
4149 if(h_test2 != -1)
4150 {
4151 #ifdef SNDCTL_DSP_COOKEDMODE
4152 k=0;
4153 ioctl(h_test2, SNDCTL_DSP_COOKEDMODE, &k);
4154 #endif
4155 line[0]++;
4156 SNDLOG"\n%s opened as second read device",dev_name);
4157 sprintf(s,"%2d:%12s %7d - %7d Hz %d Chan. %d bit",
4158 i,dev_name,
4159 dev_min_rd_speed[i],
4160 dev_max_rd_speed[i],
4161 dev_rd_channels[i],
4162 dev_rd_bytes[i]);
4163 lir_text(0,line[0],s);
4164 close(h_test2);
4165 dev_flag[i]|=256;
4166 }
4167 }
4168 }
4169 if(j == 0)goto skip_dual_devices;
4170 settextcolor(14);
4171 lir_text(0,line[0]+1,"Select second input device by Dev no.");
4172 get_addev2:;
4173 settextcolor(7);
4174 i=lir_get_integer(51, line[0]+1, 3, 0,MAX_DEVNAMES-1);
4175 if(kill_all_flag)goto sel_ossdev_skip;
4176 if( (256 & dev_flag[i]) == 0)
4177 {
4178 settextcolor(15);
4179 lir_text(40,line[0],"???");
4180 lir_text(35,line[0]+1,"ERROR (press any key)");
4181 await_keyboard();
4182 if(kill_all_flag) goto sel_ossdev_skip;
4183 clear_lines(line[0]+1,line[0]+1);
4184 settextcolor(7);
4185 goto get_addev2;
4186 }
4187 // We store the second A/D device in the second byte of ad_device_no
4188 make_devname(i, dev_name);
4189 if(kill_all_flag)goto sel_ossdev_skip;
4190 ui.rx_addev_no+=256*(i+1);
4191 dev_flag[i]&=255;
4192 h_test2=open( dev_name, O_RDONLY|O_NONBLOCK|O_EXCL, 0);
4193 if(h_test2 == -1)
4194 {
4195 lirerr(1172);
4196 goto sel_ossdev_skip;
4197 }
4198 #ifdef SNDCTL_DSP_COOKEDMODE
4199 k=0;
4200 ioctl(h_test2, SNDCTL_DSP_COOKEDMODE, &k);
4201 #endif
4202 // Check for DSP_CAP_TRIGGER capability
4203 if(ioctl(h_test2, SNDCTL_DSP_GETCAPS,&caps) == -1)
4204 {
4205 lirerr(1182);
4206 goto sel_ossdev_skip;
4207 }
4208 if( (caps&DSP_CAP_TRIGGER) == 0)
4209 {
4210 SNDLOG"\nSecond input device does not have DSP_CAP_TRIGGER");
4211 close(h_test);
4212 close(h_test2);
4213 goto skip_dual_devices;
4214 }
4215 SNDLOG"\n %s is second input device.",dev_name);
4216 ui.rx_input_mode=TWO_CHANNELS+IQ_DATA;
4217 ui.rx_rf_channels=2;
4218 ui.rx_ad_channels=4;
4219 clear_screen();
4220 goto continue_dual;
4221 skip_dual_devices:;
4222 clear_screen();
4223 }
4224 // Now that we decided what device to use for input, open it and let
4225 // the user decide how to use it.
4226 if(ui.rx_addev_no != UNDEFINED_DEVICE_CODE)
4227 {
4228 make_devname(ui.rx_addev_no, dev_name);
4229 if(kill_all_flag)goto sel_ossdev_skip;
4230 sndlog_sync();
4231 line[0]++;
4232 ui.rx_admode=select_rdwr_mode(line, ui.rx_addev_no, O_RDONLY);
4233 if(kill_all_flag) goto sel_ossdev_skip;
4234 sndlog_sync();
4235 }
4236 clear_screen();
4237 line[0]=0;
4238 mode=0;
4239 if(ui.rx_admode == O_RDWR)mode=2;
4240 sprintf(s,"For analog input: %s opened in %s mode",
4241 dev_name,devmode_txt[mode]);
4242 lir_text(0,line[0],s);
4243 line[0]+=2;
4244 rx_audio_in=open( dev_name, ui.rx_admode|O_EXCL, 0);
4245 if(rx_audio_in == -1)
4246 {
4247 lirerr(1038);
4248 goto sel_ossdev_skip;
4249 }
4250 continue_dual:;
4251 clear_lines(10,11+j);
4252 #ifdef SOUND_OSS
4253 sprintf(s,"Use ossmix");
4254 #else
4255 sprintf(s,"Use system mixer program");
4256 #endif
4257 column=0;
4258 while(s[column] != 0)column++;
4259 sprintf(&s[column]," to select input and");
4260 lir_text(0,line[0],s);
4261 line[0]++;
4262 lir_text(0,line[0],"to disable direct connection from input to output etc.");
4263 line[0]+=2;
4264 lir_text(0,line[0],"In case selection of sampling frequencies is not what you");
4265 line[0]++;
4266 lir_text(0,line[0],
4267 "expect, check README files for your board - there may be ways");
4268 line[0]++;
4269 lir_text(0,line[0],"to reconfigure the hardware. (Under OSS, run ossmix)");
4270 }
4271 sel_ossdev_skip:;
4272 free(rdtest_buffer);
4273 line[0]+=2;
4274 }
4275 #endif
4276
4277
set_rx_dadev_parms(int * line)4278 void set_rx_dadev_parms(int *line)
4279 {
4280 if(ui.rx_dadev_no == UNDEFINED_DEVICE_CODE)return;
4281 ui.rx_min_da_channels=1;
4282 ui.rx_max_da_channels=2;
4283 if( (dev_wr_channels[ui.rx_dadev_no]&3) == 0)
4284 {
4285 lir_text(0,line[0],
4286 "Error: Device must have 1 or 2 channels (or both).");
4287 line[0]++;
4288 lir_text(0,line[0],wish_anyway);
4289 anyway:;
4290 await_processed_keyboard();
4291 if(lir_inkey=='N')
4292 {
4293 ui.rx_dadev_no=UNDEFINED_DEVICE_CODE;
4294 return;
4295 }
4296 if(lir_inkey != 'Y')goto anyway;
4297 }
4298 else
4299 {
4300 if( (dev_wr_channels[ui.rx_dadev_no]&1) == 0)ui.rx_min_da_channels=2;
4301 if( (dev_wr_channels[ui.rx_dadev_no]&2) == 0)ui.rx_max_da_channels=1;
4302 }
4303 ui.rx_min_da_speed=dev_min_wr_speed[ui.rx_dadev_no];
4304 ui.rx_max_da_speed=dev_max_wr_speed[ui.rx_dadev_no];
4305 ui.rx_min_da_bytes=1;
4306 if( (dev_wr_bytes[ui.rx_dadev_no]&1) == 0)ui.rx_min_da_bytes=2;
4307 ui.rx_max_da_bytes=ui.rx_min_da_bytes;
4308 if( (dev_wr_bytes[ui.rx_dadev_no]&2) != 0)ui.rx_max_da_bytes=2;
4309 }
4310
stop_iotest(int mode)4311 void stop_iotest(int mode)
4312 {
4313 soundcard_test_cmd_flag[mode]=THRFLAG_KILL;
4314 pthread_join(thread_identifier_soundcard_test[mode],0);
4315 }
4316
start_iotest(int * line,int mode)4317 int start_iotest(int *line, int mode)
4318 {
4319 char *mode_text[3]={"RX INPUT", "RX OUTPUT", "TX OUTPUT"};
4320 char s[80];
4321 int i;
4322 // To make sure that the devices we select for tx or for rx output can
4323 // be used while the rx input is running we start a separate thread that
4324 // uses the rx input so we will fail on devices that do not
4325 // allow simultaneous read and write.
4326 soundcard_test_block_count[mode]=0;
4327 soundcard_test_cmd_flag[mode]=THRFLAG_ACTIVE;
4328 pthread_create(&thread_identifier_soundcard_test[mode],
4329 NULL,(void*)thread_iotest[mode], NULL);
4330 i=0;
4331 while(i < 100 && soundcard_test_block_count[mode] < 8)
4332 {
4333 lir_sleep(10000);
4334 if(kill_all_flag)return FALSE;
4335 i++;
4336 }
4337 if(i >= 100)
4338 {
4339 line[0]+=2;
4340 settextcolor(12);
4341 sprintf(s,"FAILED TO RUN THE %s",mode_text[mode]);
4342 lir_text(0,line[0],s);
4343 line[0]++;
4344 if(mode == RXAD)
4345 {
4346 lir_text(0,line[0],"Set a working input or force no soundcard by");
4347 line[0]++;
4348 lir_text(0,line[0],"selecting network input, then soundcard select.");
4349 line[0]++;
4350 lir_text(0,line[0],press_any_key);
4351 await_keyboard();
4352 settextcolor(7);
4353 return FALSE;
4354 }
4355 }
4356 settextcolor(7);
4357 return TRUE;
4358 }
4359
set_rx_io(void)4360 void set_rx_io(void)
4361 {
4362 char *tmptxt;
4363 char *tmptxt1;
4364 int dev_max_channels;
4365 int dev_min_channels;
4366 int i, j, k;
4367 int n1, n2, m1, m2;
4368 #if HAVE_OSS == 1
4369 int speed_warning;
4370 int min, max;
4371 int trySpeed, deltaSpeed;
4372 int rdwr_max_speed;
4373 int column;
4374 #endif
4375 int line, refline;
4376 char s[256];
4377 char s1[256];
4378 #if (ALSA_PRESENT == 1)
4379 unsigned int new_sample_rate;
4380 #endif
4381 int err;
4382 char pa_device_name[128];
4383 char pa_device_hostapi [128];
4384 double pa_device_max_speed;
4385 double pa_device_min_speed;
4386 int pa_device_max_bytes;
4387 int pa_device_min_bytes;
4388 int pa_device_max_channels;
4389 int pa_device_min_channels;
4390 dev_max_channels=1;
4391 dev_min_channels=1;
4392 memset(blanks, ' ',58);
4393 blanks[59]=0;
4394 refline=0;
4395 sndlog=fopen(rx_logfile_name, "w");
4396 if(sndlog == NULL)
4397 {
4398 lirerr(1016);
4399 return;
4400 }
4401 write_log=TRUE;
4402 if(ui.rx_addev_no != DISABLED_DEVICE_CODE)
4403 {
4404 if(ui.rx_ad_channels == 0 && ui.rx_dadev_no != DISABLED_DEVICE_CODE)
4405 {
4406 if(ui.rx_max_da_channels == 0 )
4407 {
4408 ui.use_alsa=0;
4409 }
4410 ui.rx_addev_no=UNDEFINED_DEVICE_CODE;
4411 }
4412 if(ui.rx_max_da_channels == 0)
4413 {
4414 ui.rx_dadev_no=UNDEFINED_DEVICE_CODE;
4415 }
4416 }
4417 ui.use_alsa&=NATIVE_ALSA_USED;
4418 #if (ALSA_PRESENT == 1)
4419 if(ui.rx_addev_no < 0)ui.use_alsa|=NATIVE_ALSA_USED;
4420 #endif
4421 begin_rx_set_io:;
4422 clear_screen();
4423 settextcolor(14);
4424 line=0;
4425 lir_text(2,line,"CURRENT A/D and D/A SETUP FOR RX");
4426 if(ui.use_extio != 0)
4427 {
4428 get_extio_name(&s[0]);
4429 lir_text(35,line,"using");
4430 lir_text(41,line,s);
4431 if(ui.extio_type == 4)
4432 {
4433 lir_text((int)(42+strlen(s)),line,"with soundcard input.");
4434 }
4435 else
4436 {
4437 if(ui.extio_type >= 3 && ui.extio_type <= 7)
4438 {
4439 goto display_rx_out;
4440 }
4441 else
4442 {
4443 lirerr(1237);
4444 return;
4445 }
4446 }
4447 }
4448 line+=2;
4449 settextcolor(7);
4450 // ******************************************
4451 // Start by writing what sound system we use
4452 // ******************************************
4453 #if (ALSA_PRESENT == 1)
4454 lir_text(2,line,"The current sound system is:");
4455 settextcolor(10);
4456 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
4457 {
4458 lir_text(31,line,"native ALSA");
4459 SNDLOG"\nsound system = native ALSA ");
4460 }
4461 else
4462 {
4463 #ifdef SOUND_OSS
4464 lir_text(31,line,"4Front OSS");
4465 #else
4466 lir_text(31,line,"alsa-oss");
4467 #endif
4468 SNDLOG"\nsound system = alsa-oss emulation ");
4469 }
4470 #ifndef SOUND_OSS
4471 sprintf(s,"(ALSA library version:%s)",SND_LIB_VERSION_STR);
4472 settextcolor(7);
4473 lir_text(43,line,s);
4474 #endif
4475 #else
4476 ui.use_alsa&=~NATIVE_ALSA_USED;
4477 lir_text(2,line,"This system uses OSS or legacy sound.");
4478 SNDLOG"\nsound system= OSS or legacy sound ");
4479 #endif
4480 line+=2;
4481 if( show_rx_input_settings(&line) )goto display_rx_out;
4482 // check for input soundcards
4483 if(ui.rx_addev_no == UNDEFINED_DEVICE_CODE)
4484 {
4485 settextcolor(12);
4486 if (ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
4487 {
4488 sprintf(s,"NOT YET SELECTED (Select Menu Option ""A"")");
4489 }
4490 else
4491 {
4492 sprintf(s,"SOUNDCARD NOT YET SELECTED: Select Menu Option A ");
4493 }
4494 lir_text(24,line,s);
4495 SNDLOG"\n%s",s);
4496 goto display_rx_out;
4497 }
4498 if ( (ui.use_alsa&PORTAUDIO_RX_IN) != 0)
4499 {
4500 err=pa_get_device_info (ui.rx_addev_no,
4501 RXAD,
4502 &pa_device_name,
4503 &pa_device_hostapi,
4504 &pa_device_max_speed,
4505 &pa_device_min_speed,
4506 &pa_device_max_bytes,
4507 &pa_device_min_bytes,
4508 &pa_device_max_channels,
4509 &pa_device_min_channels );
4510 if (err >= 0)
4511 {
4512 sprintf(s,"SOUNDCARD device = %s ", pa_device_name);
4513 lir_text(24,line,s);
4514 SNDLOG"\n%s",s);
4515 line+=1;
4516 sprintf(s,"device number = %d", ui.rx_addev_no);
4517 lir_text(24,line,s);
4518 SNDLOG"\n%s",s);
4519 line+=1;
4520 sprintf(s,"hostapi = Portaudio (%s)", pa_device_hostapi);
4521 lir_text(24,line,s);
4522 SNDLOG"\n%s",s);
4523 }
4524 else
4525 {
4526 sprintf (s,"PORTAUDIO device number %d : INVALID DEVICE ",ui.rx_addev_no );
4527 settextcolor(12);
4528 lir_text(24,line,s);
4529 SNDLOG"\n%s",s);
4530 ui.rx_addev_no=UNDEFINED_DEVICE_CODE;
4531 goto set_rx_io_ask;
4532 }
4533 }
4534 #if (ALSA_PRESENT == 1)
4535 if(( (ui.use_alsa&NATIVE_ALSA_USED)!=0) && ((ui.use_alsa&PORTAUDIO_RX_IN) == 0))
4536 {
4537 err=alsa_get_dev_names (ui.rx_addev_no);
4538 if(err < 0)
4539 {
4540 sprintf(s,"SOUNDCARD device number %i : INVALID DEVICE ", ui.rx_addev_no );
4541 settextcolor(12);
4542 lir_text(24,line,s);
4543 SNDLOG"\n%s\n",s);
4544 ui.rx_addev_no=UNDEFINED_DEVICE_CODE;
4545 goto display_rx_out;
4546 }
4547 else
4548 {
4549 sprintf(s,"SOUNDCARD =%s",alsa_dev_soundcard_name);
4550 lir_text(24,line,s);
4551 SNDLOG"\n%s",s);
4552 sprintf(s,"device =%s (%s)",alsa_dev_name,alsa_dev_plughw_pcm_name);
4553 line+=1;
4554 lir_text(24,line,s);
4555 SNDLOG"\n%s",s);
4556 sprintf(s,"device number = %i", alsa_dev_seq_nmbr);
4557 line+=1;
4558 lir_text(24,line,s);
4559 line+=1;
4560 sprintf(s,"hostapi = Native ALSA");
4561 lir_text(24,line,s);
4562 SNDLOG"\n%s",s);
4563 }
4564 }
4565 else
4566 #endif
4567 {
4568 if((ui.use_alsa&PORTAUDIO_RX_IN) == 0)
4569 {
4570 #if HAVE_OSS == 1
4571 // no validation available for alsa-oss or OSS
4572 sprintf(dev_name,"%s",SND_DEV);
4573 if(dev_name[0] != 'u')make_devname(ui.rx_addev_no, dev_name);
4574 if(kill_all_flag)goto set_rx_io_errexit;
4575 sprintf(s,"SOUNDCARD device = %s",dev_name);
4576 lir_text(24,line,s);
4577 line+=1;
4578 sprintf(s,"hostapi = alsa-oss");
4579 lir_text(24,line,s);
4580 SNDLOG"\n%s",s);
4581 #else
4582 lir_text(24,line,"ERROR");
4583 line+=1;
4584 #endif
4585 }
4586 }
4587 line++;
4588 settextcolor(7);
4589 sprintf(s,"associated radio = %s",soundcard_radio_names[ui.soundcard_radio]);
4590 lir_text(24,line,s);
4591 line++;
4592 if(ui.soundcard_radio == SOUNDCARD_RADIO_WSE)
4593 {
4594 sprintf(s,"Port=%d Pin =%d",wse.parport,wse.parport_pin);
4595 lir_text(50,line,s);
4596 if (wse.parport==USB2LPT16_PORT_NUMBER)
4597 {
4598 settextcolor(10);
4599 if(libusb1_library_flag == TRUE || libusb0_library_flag == TRUE)
4600 {
4601 sprintf(s,"USB2LPT 1.6 SELECTED");
4602 lir_text(70,line,s);
4603 }
4604 else
4605 {
4606 clear_lines(line,line);
4607 lir_text(15,line,"For USB2LTP you must install libusb or libusb-1.0");
4608 }
4609 settextcolor(7);
4610 }
4611 }
4612 line+=1;
4613 sprintf(s,"sample rate = %i ",ui.rx_ad_speed );
4614 SNDLOG"\n%s",s);
4615 lir_text(24,line,s);
4616 line++;
4617 if ( (ui.use_alsa&PORTAUDIO_RX_IN) != 0)
4618 {
4619 sprintf(s,"latency factor = %i ",ui.rx_ad_latency );
4620 SNDLOG"\n%s",s);
4621 lir_text(24,line,s);
4622 line++;
4623 }
4624 sprintf(s,"No of input bytes = 2 (16 bits)");
4625 if( (ui.rx_input_mode&DWORD_INPUT) != 0)
4626 {
4627 sprintf(&s[21],"4 (32 bits)");
4628 }
4629 SNDLOG"\n%s",s);
4630 lir_text(24,line,s);
4631 line+=1;
4632 tmptxt=" ";
4633 tmptxt1=" ";
4634 if( ((ui.rx_input_mode&TWO_CHANNELS) == 0)&&((ui.rx_input_mode&IQ_DATA) == 0))
4635 {
4636 tmptxt="radio interface = One Rx channel, one audio channels ";
4637 tmptxt1=" (normal audio)";
4638 }
4639 if( ((ui.rx_input_mode&TWO_CHANNELS) == 0)&&((ui.rx_input_mode&IQ_DATA) != 0))
4640 {
4641 tmptxt="radio interface = One Rx channel, two audio channels ";
4642 sprintf(s," (direct conversion, time shift=%d)",
4643 ui.sample_shift );
4644 tmptxt1=s;
4645 }
4646 if( ((ui.rx_input_mode&TWO_CHANNELS) != 0)&&((ui.rx_input_mode&IQ_DATA) != 0))
4647 {
4648 tmptxt="radio interface = Two Rx channels, four audio channels ";
4649 tmptxt1=" (direct conversion, adaptive polarization)";
4650 }
4651 if( ((ui.rx_input_mode&TWO_CHANNELS) != 0)&&((ui.rx_input_mode&IQ_DATA) == 0))
4652 {
4653 tmptxt="radio interface = Two Rx channels, two audio channels ";
4654 tmptxt1=" (normal audio, adaptive polarization)";
4655 }
4656 lir_text(24,line,tmptxt);
4657 SNDLOG"\n%s",tmptxt);
4658 line+=1;
4659 lir_text(24,line,tmptxt1);
4660 SNDLOG"\n%s\n",tmptxt1);
4661 display_rx_out:;
4662 // ************************************************************************************
4663 // Show the current RX output settings on the screen and do some validation if possible
4664 // ************************************************************************************
4665 settextcolor(7);
4666 line+=2;
4667 lir_text(2,line,"Linrad RX output to:");
4668 SNDLOG"\nSETUP FOR RX OUTPUT IS NOW:\n");
4669 settextcolor(10);
4670 //check if network output mode
4671 s[0]='\0';
4672 if((ui.network_flag & NET_RXOUT_RAW16) != 0) strncat ( s,"RAW16 ",6);
4673 if((ui.network_flag & NET_RXOUT_RAW18) != 0) strncat ( s,"RAW18 ",6);
4674 if((ui.network_flag & NET_RXOUT_RAW24) != 0) strncat ( s,"RAW24 ",6);
4675 if((ui.network_flag & NET_RXOUT_FFT1) != 0) strncat ( s,"FFT1 ",6);
4676 if((ui.network_flag & NET_RXOUT_TIMF2) != 0) strncat ( s,"TIMF2 ",6);
4677 if((ui.network_flag & NET_RXOUT_FFT2) != 0) strncat ( s,"FFT2 ",6);
4678 if((ui.network_flag & NET_RXOUT_BASEB) != 0) strncat ( s,"BASEB16 ",9);
4679 if((ui.network_flag & NET_RXOUT_BASEBRAW) != 0) strncat ( s,"BASEB24 ",9);
4680 if (strlen(s) != 0)
4681 {
4682 sprintf(s1,"NETWORK");
4683 lir_text(24,line,s1);
4684 SNDLOG"\n%s",s1);
4685 settextcolor(7);
4686 line+=1;
4687 sprintf(s1,"send format = %s",s);
4688 lir_text(24,line,s1);
4689 SNDLOG"\n%s\n",s1);
4690 line+=2;
4691 settextcolor(10);
4692 //disable output soundcard if not yet selected
4693 if(ui.rx_dadev_no == UNDEFINED_DEVICE_CODE) ui.rx_dadev_no=DISABLED_DEVICE_CODE;
4694 }
4695 //check for output soundcards
4696 if(ui.rx_dadev_no < 0)
4697 {
4698 if(ui.rx_dadev_no == UNDEFINED_DEVICE_CODE)
4699 {
4700 settextcolor(12);
4701 if (ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
4702 {
4703 sprintf(s,"NOT YET SELECTED (SHOULD BE EITHER SOUNDCARD OR DISABLED, AND/OR NETWORK)");
4704 }
4705 else
4706 {
4707 sprintf(s,"SOUNDCARD NOT YET SELECTED OR DISABLED: Select Menu Option B or Z ");
4708 }
4709 lir_text(24,line,s);
4710 SNDLOG"\n%s",s);
4711 goto set_rx_io_ask;
4712 }
4713 else
4714 {
4715 ui.rx_dadev_no=DISABLED_DEVICE_CODE;
4716 sprintf(s,"SOUNDCARD DISABLED");
4717 lir_text(24,line,s);
4718 SNDLOG"\n%s",s);
4719 goto set_rx_io_ask;
4720 }
4721 }
4722 else
4723 {
4724 if( (ui.use_alsa&PORTAUDIO_RX_OUT) != 0)
4725 {
4726 err=pa_get_device_info (ui.rx_dadev_no,
4727 RXDA,
4728 &pa_device_name,
4729 &pa_device_hostapi,
4730 &pa_device_max_speed,
4731 &pa_device_min_speed,
4732 &pa_device_max_bytes,
4733 &pa_device_min_bytes,
4734 &pa_device_max_channels,
4735 &pa_device_min_channels
4736 );
4737 if (err == 0 )
4738 {
4739 sprintf(s,"SOUNDCARD device = %s ", pa_device_name );
4740 lir_text(24,line,s);
4741 SNDLOG"\n%s",s);
4742 line++;
4743 sprintf(s,"device number = %d", ui.rx_dadev_no);
4744 lir_text(24,line,s);
4745 SNDLOG"\n%s",s);
4746 line++;
4747 sprintf(s,"hostapi = Portaudio (%s) ", pa_device_hostapi);
4748 lir_text(24,line,s);
4749 SNDLOG"\n%s",s);
4750 ui.rx_min_da_speed=(int)pa_device_min_speed;
4751 ui.rx_max_da_speed=(int)pa_device_max_speed;
4752 ui.rx_min_da_bytes=pa_device_min_bytes;
4753 ui.rx_max_da_bytes=pa_device_max_bytes;
4754 ui.rx_min_da_channels=pa_device_min_channels;
4755 ui.rx_max_da_channels=pa_device_max_channels;
4756 }
4757 else
4758 {
4759 sprintf(s,"INVALID DEVICE (Portaudio device number= %d )", ui.rx_dadev_no );
4760 settextcolor(12);
4761 lir_text(24,line,s);
4762 SNDLOG"\n%s\n",s);
4763 ui.rx_dadev_no=UNDEFINED_DEVICE_CODE;
4764 goto set_rx_io_ask;
4765 }
4766 }
4767 else
4768 {
4769 #if (ALSA_PRESENT == 1)
4770 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
4771 {
4772 err=alsa_get_dev_names (ui.rx_dadev_no);
4773 if(err < 0)
4774 {
4775 sprintf(s,"SOUNDCARD device number %i : INVALID DEVICE ",
4776 ui.rx_dadev_no );
4777 settextcolor(12);
4778 lir_text(24,line,s);
4779 SNDLOG"\n%s\n",s);
4780 ui.rx_dadev_no=UNDEFINED_DEVICE_CODE;
4781 goto set_rx_io_ask;
4782 }
4783 else
4784 {
4785 sprintf(s,"SOUNDCARD =%s",alsa_dev_soundcard_name);
4786 lir_text(24,line,s);
4787 line++;
4788 SNDLOG"\n%s",s);
4789 sprintf(s,"device =%s (%s)",alsa_dev_name,alsa_dev_plughw_pcm_name);
4790 lir_text(24,line,s);
4791 line++;
4792 SNDLOG"\n%s",s);
4793 sprintf(s,"device number = %i",alsa_dev_seq_nmbr);
4794 lir_text(24,line,s);
4795 line++;
4796 SNDLOG"\n%s",s);
4797 sprintf(s,"hostapi = Native ALSA");
4798 lir_text(24,line,s);
4799 SNDLOG"\n%s",s);
4800 settextcolor(7);
4801 }
4802 }
4803 else
4804 #endif
4805 {
4806 #if HAVE_OSS == 1
4807 make_devname(ui.rx_dadev_no, dev_name);
4808 if(kill_all_flag)goto set_rx_io_errexit;
4809 sprintf(s,"SOUNDCARD device = %s",dev_name);
4810 lir_text(24,line,s);
4811 SNDLOG"\n%s",s);
4812 settextcolor(7);
4813 #else
4814 lir_text(24,line,"ERROR");
4815 #endif
4816 }
4817 }
4818 }
4819 line++;
4820 settextcolor(7);
4821 sprintf(s,"min da sample rate = %i",ui.rx_min_da_speed);
4822 SNDLOG"\n%s",s);
4823 lir_text(24,line,s);
4824 line++;
4825 sprintf(s,"max da sample rate = %i ", ui.rx_max_da_speed);
4826 SNDLOG"\n%s",s);
4827 lir_text(24,line,s);
4828 line++;
4829 if ( (ui.use_alsa&PORTAUDIO_RX_OUT) != 0)
4830 {
4831 sprintf(s,"Latency factor = %i ",ui.rx_da_latency );
4832 SNDLOG"\n%s",s);
4833 lir_text(24,line,s);
4834 line++;
4835 }
4836 sprintf(s,"min da bytes = %i",ui.rx_min_da_bytes);
4837 SNDLOG"\n%s",s);
4838 lir_text(24,line,s);
4839 line++;
4840 sprintf(s,"max da bytes = %i ", ui.rx_max_da_bytes);
4841 SNDLOG"\n%s",s);
4842 lir_text(24,line,s);
4843 line++;
4844 sprintf(s,"min da channels = %i",ui.rx_min_da_channels);
4845 SNDLOG"\n%s",s);
4846 lir_text(24,line,s);
4847 line++;
4848 sprintf(s,"max da channels = %i", ui.rx_max_da_channels);
4849 SNDLOG"\n%s",s);
4850 lir_text(24,line,s);
4851 set_rx_io_ask:;
4852 settextcolor(7);
4853 line+=2;
4854 if(ui.converter_mode != 0)
4855 {
4856 compute_converter_parameters();
4857 settextcolor(10);
4858 line+=2;
4859 if( (ui.converter_mode&CONVERTER_UP) !=0 )
4860 {
4861 lir_text(2,line,"UP");
4862 j=4;
4863 }
4864 else
4865 {
4866 lir_text(2,line,"DOWN");
4867 j=6;
4868 }
4869 lir_text(j,line,"CONVERTER:");
4870 settextcolor(7);
4871 sprintf(s,"LO frequency %.6f",converter_offset_mhz);
4872 i=0;
4873 while(s[i] != 0)i++;
4874 while(s[i-1] == '0')i--;
4875 if(s[i-1] == '.')i--;
4876 if( (ui.converter_mode&CONVERTER_UP) !=0 )
4877 {
4878 sprintf(&s[i]," MHz.");
4879 }
4880 else
4881 {
4882 sprintf(&s[i]," MHz. LO is ");
4883 if( (ui.converter_mode&CONVERTER_LO_BELOW) != 0)
4884 {
4885 strcat(s,"below");
4886 }
4887 else
4888 {
4889 strcat(s,"above");
4890 }
4891 strcat(s," signal frequency.");
4892 }
4893 lir_text(j+11,line,s);
4894 }
4895 line+=2;
4896 sprintf(s,"DMA rate min=%i max=%i" ,ui.min_dma_rate, ui.max_dma_rate);
4897 SNDLOG"\n%s\n",s);
4898 lir_text(2,line,s);
4899 // *******************************************************************
4900 // Ask whether the user wants to change something and act accordingly.
4901 // *******************************************************************
4902 line+=2;
4903 sndlog_sync();
4904 lir_text(2,line,"A = Change the input settings and reset the output soundcard settings if a soundcard is selected as input.");
4905 line++;
4906 lir_text(2,line,"B = Change the output soundcard settings.");
4907 line++;
4908 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
4909 {
4910 lir_text(2,line,"C = Change min and max dma rate .");
4911 line++;
4912 }
4913 if(ui.soundcard_radio != SOUNDCARD_RADIO_UNDEFINED &&
4914 ui.soundcard_radio != SOUNDCARD_RADIO_UNDEFINED_REVERSED)
4915 {
4916 lir_text(2,line,"D = Set parameters for soundcard radio hardware.");
4917 line++;
4918 }
4919 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
4920 {
4921 lir_text(2,line,"E = Enable/Disable frequency converter and set LO.");
4922 line++;
4923 }
4924 lir_text(2,line,"Z = Disable the output soundcard.");
4925 line++;
4926 #if (ALSA_PRESENT == 1)
4927 lir_text(2,line,"Y = Toggle soundsystem between native ALSA and alsa-oss and reset all soundcard settings.");
4928 line++;
4929 #endif
4930 if(line >= screen_last_line)
4931 {
4932 clear_lines(screen_last_line,screen_last_line);
4933 settextcolor(12);
4934 lir_text(2,screen_last_line,"SCREEN TOO LOW FOR SELECTED FONT SIZE");
4935 settextcolor(7);
4936 }
4937 else
4938 {
4939 lir_text(2,line,"X = To main menu.");
4940 }
4941 await_processed_keyboard();
4942 if(kill_all_flag)goto set_rx_io_errexit;
4943 clear_screen();
4944 switch(lir_inkey)
4945 {
4946 case 'A':
4947 // ************************* CHANGE INPUT SETTINGS ************************************ //
4948 ui.sample_shift=0;
4949 line=2;
4950 SNDLOG"\nUSER STARTED THE SELECTION OF A NEW INPUT DEVICE \n");
4951 if(ui.use_extio != 0)
4952 {
4953 if(extio_handle != NULL)
4954 {
4955 command_extio_library(EXTIO_COMMAND_UNLOAD_DLL);
4956 }
4957 ui.use_extio=0;
4958 }
4959 ui.rx_addev_no =UNDEFINED_DEVICE_CODE;
4960 lir_text(10,line,"SELECT HARDWARE FOR INPUT");
4961 line+=2;
4962 lir_text(4,line,"A = Soundcard");
4963 line++;
4964 lir_text(4,line,"B = SDR-14 or SDR-IQ");
4965 line++;
4966 lir_text(4,line,"C = Perseus");
4967 line++;
4968 lir_text(4,line,"D = SDR-IP");
4969 line++;
4970 lir_text(4,line,"E = Excalibur");
4971 line++;
4972 lir_text(4,line,"F = libExtIO hardwares");
4973 line++;
4974 lir_text(4,line,"H = RTL2832 USB dongle");
4975 line++;
4976 lir_text(4,line,"I = Mirics USB dongle");
4977 line++;
4978 lir_text(4,line,"J = bladeRF");
4979 line++;
4980 lir_text(4,line,"K = PCIe 9842");
4981 line++;
4982 lir_text(4,line,"L = OpenHPSDR");
4983 line++;
4984 lir_text(4,line,"M = Afedri-NET");
4985 line++;
4986 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
4987 {
4988 lir_text(4,line,"Y = Network");
4989 line++;
4990 }
4991 lir_text(4,line,"Z = Disable (Disk input allowed)");
4992 await_processed_keyboard();
4993 if(kill_all_flag)goto set_rx_io_errexit;
4994 clear_screen();
4995 ui.soundcard_radio=0;
4996 ui.use_extio=0;
4997 switch (lir_inkey)
4998 {
4999 case 'A':
5000 use_sndcard:;
5001 clear_screen();
5002 // reset the output soundcard
5003 ui.use_alsa&=~PORTAUDIO_RX_IN;
5004 ui.rx_dadev_no=UNDEFINED_DEVICE_CODE;
5005 #if (ALSA_PRESENT == 1 || HAVE_OSS == 1)
5006 lir_text(10,5,
5007 "Use Portaudio (allows all/slow devices) for rx input? (Y/N) =>");
5008 lir_text(15,7,press_f1_for_info);
5009 await_processed_keyboard();
5010 if(kill_all_flag)goto set_rxin_exit;
5011 if(lir_inkey == F1_KEY || lir_inkey == '!')
5012 {
5013 help_message(343);
5014 goto use_sndcard;
5015 }
5016 if(lir_inkey == 'Y')
5017 {
5018 ui.use_alsa|=PORTAUDIO_RX_IN;
5019 }
5020 else
5021 {
5022 if(lir_inkey != 'N')
5023 {
5024 goto use_sndcard;
5025 }
5026 }
5027 #else
5028 ui.use_alsa|=PORTAUDIO_RX_IN;
5029 #endif
5030 if(!portaudio_startstop())goto use_sndcard;
5031 //get a 'portaudio' selection list
5032 clear_screen();
5033 line=1;
5034 if( (ui.use_alsa&PORTAUDIO_RX_IN) != 0)
5035 {
5036 set_portaudio(RXAD, &line);
5037 goto set_rxin_exit;
5038 }
5039 // look for input soundcards
5040 sprintf(s,"SELECT SOUNDCARD DEVICE FOR RX INPUT FROM LIST:");
5041 SNDLOG"%s\n",s);
5042 line=1;
5043 settextcolor(14);
5044 lir_text(2,line,s);
5045 settextcolor(7);
5046 line++;
5047 #if (ALSA_PRESENT == 1)
5048 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
5049 {
5050 ui.rx_addev_no=select_alsadev(SND_PCM_STREAM_CAPTURE, &line);
5051 if(kill_all_flag)goto set_rx_io_errexit;
5052 alsa_get_native_samplerate(ui.rx_addev_no,SND_PCM_STREAM_CAPTURE,&line,&new_sample_rate);
5053 if(kill_all_flag)return;
5054 ui.rx_ad_speed=(int)new_sample_rate;
5055 //get number of bytes and check
5056 if(alsa_dev_max_bytes > 2)
5057 {
5058 if(alsa_dev_max_bytes != 4)
5059 {
5060 lirerr(872341);
5061 return;
5062 }
5063 if(alsa_dev_min_bytes == 4)
5064 {
5065 ui.rx_input_mode=DWORD_INPUT;
5066 }
5067 else
5068 {
5069 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
5070 {
5071 sprintf(s,"Enter number of input bytes (2 or 4) >");
5072 select_number_input_bytes:;
5073 SNDLOG"%s\n",s);
5074 lir_text(0,line,s);
5075 i=lir_get_integer(39, line, 1,2,4);
5076 if(kill_all_flag)goto set_rx_io_errexit;
5077 sprintf(s,"User selected %i",i);
5078 SNDLOG"%s\n",s);
5079 lir_text(44,line,blanks);
5080 switch (i)
5081 {
5082 case 2:
5083 ui.rx_input_mode=0;
5084 break;
5085
5086 case 4:
5087 ui.rx_input_mode=DWORD_INPUT;
5088 break;
5089
5090 default:
5091 settextcolor(12);
5092 sprintf(s,"invalid selection, try again");
5093 SNDLOG"%s\n",s);
5094 lir_text(44,line,s);
5095 settextcolor(7);
5096 goto select_number_input_bytes;
5097 }
5098 }
5099 else
5100 {
5101 ui.rx_input_mode=DWORD_INPUT;
5102 }
5103 }
5104 }
5105 else
5106 {
5107 ui.rx_input_mode=0;
5108 SNDLOG"\n\n");
5109 }
5110 dev_min_channels=1;
5111 dev_max_channels=alsa_dev_max_channels;
5112 if(dev_max_channels > 4)dev_max_channels=4;
5113 // With native alsa, always set ui.rx_admode to 0
5114 ui.rx_admode=0;
5115 line+=2;
5116 }
5117 else
5118 #endif
5119 //OSS or alsa-oss
5120 {
5121 #if HAVE_OSS == 1
5122 column=0;
5123 speed_warning=0;
5124 if(ui.process_priority != 0)
5125 {
5126 if(ui.operator_skil == OPERATOR_SKIL_EXPERT)
5127 {
5128 settextcolor(12);
5129 lir_text(0,line+2,"WARNING!! SETTING PRIORITY ABOVE 0 WILL PROBABLY CAUSE");
5130 lir_text(0,line+3,"YOUR SYSTEM TO FREEZE IF YOU ARE USING 4FRONT OSS");
5131 sprintf(s,"Press y to keep priority=%d",ui.process_priority);
5132 lir_text(0,line+5,s);
5133 lir_text(0,line+6,"Any other key to set priority to zero.");
5134 await_processed_keyboard();
5135 if(lir_inkey != 'Y')ui.process_priority=0;
5136 settextcolor(7);
5137 clear_lines(line+2,line+6);
5138 }
5139 else
5140 {
5141 ui.process_priority=0;
5142 }
5143 }
5144 select_ossdev(&line, RXAD);
5145 if(kill_all_flag)goto set_rx_io_errexit;
5146 if(ui.rx_addev_no == UNDEFINED_DEVICE_CODE)goto begin_rx_set_io;
5147 max=dev_max_rd_speed[ui.rx_addev_no&255];
5148 min=dev_min_rd_speed[ui.rx_addev_no&255];
5149 if(max == ABOVE_MAX_SPEED || max < 1000)
5150 {
5151 max=ABOVE_MAX_SPEED;
5152 speed_warning=1;
5153 }
5154 sprintf(s,"Select sampling speed(%d to %d)", min,max);
5155 lir_text(0,line,s);
5156 if(speed_warning != 0)
5157 {
5158 settextcolor(12);
5159 lir_text(0,line+2,
5160 "WARNING!! device does not respond correctly to speed setting command");
5161 lir_text(0,line+3,
5162 "Incorrect (unsupported) values may cause system to hang");
5163 settextcolor(7);
5164 }
5165 column=0;
5166 while(s[column] != 0)column++;
5167 ui.rx_ad_speed=lir_get_integer(column+2, line, 8, min,max);
5168 lir_refresh_screen();
5169 if(kill_all_flag)goto set_rx_io_errexit;
5170 rdwr_max_speed=ui.rx_ad_speed;
5171 SNDLOG"\n%d Hz selected by user",ui.rx_ad_speed);
5172 line++;
5173 clear_lines(line,line+3);
5174 if(ioctl(rx_audio_in, SNDCTL_DSP_SPEED, &ui.rx_ad_speed)==-1)
5175 {
5176 lirerr(1041);
5177 goto set_rx_io_errexit;
5178 }
5179 if(ui.rx_ad_speed > (int)(rdwr_max_speed*1.05) ||
5180 ui.rx_ad_speed < (int)(rdwr_max_speed*0.95) )
5181 {
5182 // The user selected something that was unacceptable to the device driver.
5183 // Rather than just accepting whatever value goto set_rx_io_errexited,
5184 // could be -22 (an unspecified error code) we step the desired speed
5185 // upwards, looking for a valid speed.
5186 // In case we fail, an attempt is made downwards as well.
5187 // ****************************************************************
5188 // This code is written by Ulf, SM0LCB
5189 SNDLOG"\nReqested speed didn't work");
5190 // This code will search up/down from requested speed
5191 // until the driver will respond with valid code
5192 // Search use delta stepping of 3% from current speed
5193 // This to speed up the search for a valid speed
5194 // First search up in fq
5195 SNDLOG"\nSearch up : ");
5196 for( trySpeed=rdwr_max_speed,
5197 deltaSpeed=(int)((float)(rdwr_max_speed)*0.03F);
5198 trySpeed<192000;
5199 trySpeed+=deltaSpeed )
5200 {
5201 ui.rx_ad_speed=trySpeed;
5202 if(ioctl(rx_audio_in, SNDCTL_DSP_SPEED, &ui.rx_ad_speed)==-1)
5203 {
5204 lirerr(1024);
5205 goto set_rx_io_errexit;
5206 }
5207 // test if valid speed
5208 if(ui.rx_ad_speed < (int)(trySpeed*1.05) &&
5209 ui.rx_ad_speed > (int)(trySpeed*0.95) )
5210 {
5211 SNDLOG"try speed %d Hz ", trySpeed);
5212 goto spok;
5213 }
5214 deltaSpeed=(int)((float)(trySpeed)*0.03F);
5215 }
5216 SNDLOG"no speed found");
5217 // Then search down in fq
5218 SNDLOG"\nSearch down : ");
5219 for( trySpeed=rdwr_max_speed,
5220 deltaSpeed=(int)((float)(rdwr_max_speed)*0.03F);
5221 trySpeed>5000;
5222 trySpeed-=deltaSpeed )
5223 {
5224 ui.rx_ad_speed=trySpeed;
5225 if(ioctl(rx_audio_in, SNDCTL_DSP_SPEED, &ui.rx_ad_speed)==-1)
5226 {
5227 lirerr(1135);
5228 goto set_rx_io_errexit;
5229 }
5230 // test if valid speed
5231 if(ui.rx_ad_speed < (int)(trySpeed*1.05) &&
5232 ui.rx_ad_speed > (int)(trySpeed*0.95) )
5233 {
5234 SNDLOG"try speed %d Hz ", trySpeed);
5235 goto spok;
5236 }
5237 deltaSpeed=(int)((float)(trySpeed)*0.03F);
5238 }
5239 SNDLOG"no speed found");
5240 // If we didn't find any vaid speed
5241 SNDLOG"\nNo valid speed found !");
5242 // Exit program
5243 lirerr(1134);
5244 goto set_rx_io_errexit;
5245 }
5246 spok:;
5247 close(rx_audio_in);
5248 rx_audio_in=-1;
5249 SNDLOG"\n%d Hz reported by device",ui.rx_ad_speed);
5250 sndlog_sync();
5251 sprintf(s,"Input speed: %.3fkHz",0.001*(float)(ui.rx_ad_speed));
5252 lir_text(0,line,s);
5253 line++;
5254 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
5255 {
5256 if( (dev_rd_bytes[ui.rx_addev_no&255]&6) == 6)
5257 {
5258 line++;
5259 lir_text(0,line,"Select A/D number of bytes (2 or 4):");
5260 line++;
5261 selfmt:;
5262 await_processed_keyboard();
5263 if(kill_all_flag) goto set_rx_io_errexit;
5264 if(lir_inkey == '4')
5265 {
5266 ui.rx_input_mode=DWORD_INPUT;
5267 }
5268 else
5269 {
5270 if(lir_inkey != '2')goto selfmt;
5271 ui.rx_input_mode=0;
5272 }
5273 goto fmtok;
5274 }
5275 }
5276 if( (dev_rd_bytes[ui.rx_addev_no&255]&6) == 4)
5277 {
5278 ui.rx_input_mode=DWORD_INPUT;
5279 }
5280 else
5281 {
5282 ui.rx_input_mode=0;
5283 }
5284 fmtok:;
5285 dev_max_channels=0;
5286 k=4;
5287 while(dev_max_channels == 0 && k> 0)
5288 {
5289 dev_max_channels|=dev_rd_channels[ui.rx_addev_no]&k;
5290 k/=2;
5291 }
5292 dev_min_channels=1;
5293 #endif
5294 }
5295 if(ui.rx_addev_no < 256)
5296 {
5297 refline=line;
5298 sel_radio:;
5299 line=refline;
5300 j=dev_max_channels;
5301 k=dev_min_channels;
5302 line++;
5303 lir_text(0,line,"Select radio interface:");
5304 line=line+k+1;
5305 if(j == 2)j=3;
5306 for(i=k; i<=j; i++)
5307 {
5308 sprintf(s,"%d: %s",i,audiomode_text[i-1]);
5309 lir_text(5,line,s);
5310 line++;
5311 }
5312 line++;
5313 lir_text(1,line,"F1 for help/info");
5314 chsel:;
5315 await_processed_keyboard();
5316 if(kill_all_flag) goto set_rx_io_errexit;
5317 if(lir_inkey == F1_KEY || lir_inkey == '!')
5318 {
5319 help_message(89);
5320 clear_screen();
5321 goto sel_radio;
5322 }
5323 if(lir_inkey-'0'<k || lir_inkey-'0'>j)goto chsel;
5324 switch (lir_inkey)
5325 {
5326 case '1':
5327 ui.rx_rf_channels=1;
5328 ui.rx_ad_channels=1;
5329 break;
5330
5331 case '2':
5332 ui.rx_input_mode|=IQ_DATA;
5333 ui.rx_rf_channels=1;
5334 ui.rx_ad_channels=2;
5335 break;
5336
5337 case '3':
5338 ui.rx_input_mode|=TWO_CHANNELS;
5339 ui.rx_rf_channels=2;
5340 ui.rx_ad_channels=2;
5341 break;
5342
5343 case '4':
5344 ui.rx_input_mode|=TWO_CHANNELS+IQ_DATA;
5345 ui.rx_rf_channels=2;
5346 ui.rx_ad_channels=4;
5347 break;
5348
5349 default:
5350 goto chsel;
5351 }
5352 SNDLOG"\nui.rx_input_mode=%d ui.rx_rf_channels=%d ui.rx_ad_channels =%d",
5353 ui.rx_input_mode, ui.rx_rf_channels, ui.rx_ad_channels);
5354 if(ui.rx_addev_no == ui.rx_dadev_no)ui.rx_dadev_no=UNDEFINED_DEVICE_CODE;
5355 if(ui.rx_addev_no == ui.tx_dadev_no)ui.tx_dadev_no=UNDEFINED_DEVICE_CODE;
5356 if(ui.rx_addev_no == ui.tx_addev_no)ui.tx_addev_no=UNDEFINED_DEVICE_CODE;
5357 }
5358 if(ui.rx_rf_channels == 1 && ui.rx_ad_channels == 2)
5359 {
5360 line+=2;
5361 lir_text(0,line,"Number of points to time shift between I and Q? (-4 to +4)");
5362 ui.sample_shift=lir_get_integer(60,line, 2, -4, 4);
5363 }
5364 set_rxin_exit:
5365 clear_screen();
5366 line=4;
5367 lir_text(9,line,"Select receiver hardware to use with soundcard.");
5368 line+=3;
5369 for(i=0; i<MAX_SOUNDCARD_RADIO; i++)
5370 {
5371 sprintf(s,"%d %s",i,soundcard_radio_names[i]);
5372 lir_text(5,line,s);
5373 line++;
5374 }
5375 line++;
5376 lir_text(0,line,"Select by line number=>");
5377 ui.soundcard_radio=lir_get_integer(25,line,1,0,MAX_SOUNDCARD_RADIO);
5378 break;
5379
5380
5381 case 'B':
5382 timf1_char=malloc(0x8000);
5383 if(timf1_char == NULL)
5384 {
5385 lirerr(1231231);
5386 return;
5387 }
5388 init_sdr14();
5389 free(timf1_char);
5390 break;
5391
5392 case 'C':
5393 init_perseus();
5394 if(sdr == -1)
5395 {
5396 clear_screen();
5397 lir_text(5,5,"Perseus init failed.");
5398 lir_text(5,6,"Is the unit connected and properly powered?");
5399 lir_text(7,8,press_any_key);
5400 await_processed_keyboard();
5401 }
5402 else
5403 {
5404 sdr=-1;
5405 }
5406 break;
5407
5408 case 'D':
5409 init_sdrip();
5410 break;
5411
5412 case 'E':
5413 lir_text(5,5,"No Excalibur yet under Linux.");
5414 lir_text(7,8,press_any_key);
5415 await_processed_keyboard();
5416 break;
5417
5418 case 'F':
5419 init_extio();
5420 if(kill_all_flag)goto set_rx_io_errexit;
5421 if(ui.extio_type == 4)goto use_sndcard;
5422 break;
5423
5424 case 'H':
5425 init_rtl2832();
5426 break;
5427
5428 case 'I':
5429 init_mirics();
5430 break;
5431
5432 case 'J':
5433 init_bladerf();
5434 break;
5435
5436 case 'K':
5437 init_pcie9842();
5438 break;
5439
5440 case 'L':
5441 init_openhpsdr();
5442 break;
5443
5444 case 'M':
5445 init_netafedri();
5446 break;
5447
5448 case 'Y':
5449 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
5450 {
5451 ui.rx_addev_no=NETWORK_DEVICE_CODE;
5452 ui.use_alsa&=~PORTAUDIO_RX_IN;
5453 ui.network_flag=(int)((unsigned int)ui.network_flag|NET_RX_INPUT);
5454 verify_network(TRUE);
5455 }
5456 break;
5457
5458 case 'Z':
5459 ui.rx_addev_no=DISABLED_DEVICE_CODE;
5460 break;
5461 }
5462 if(kill_all_flag)goto set_rx_io_errexit;
5463 if(ui.rx_addev_no == UNDEFINED_DEVICE_CODE)goto begin_rx_set_io;
5464 break;
5465
5466 case 'B':
5467 // ************************* CHANGE OUTPUT SETTINGS ************************************ //
5468 if (ui.rx_addev_no == UNDEFINED_DEVICE_CODE)
5469 {
5470 settextcolor(11);
5471 line+=2;
5472 lir_text(2,line,"Option B selected, but RX input must be set first:");
5473 line+=1;
5474 lir_text(2,line,"Hit any key to go back to this menu and select option A");
5475 settextcolor(7);
5476 await_processed_keyboard();
5477 if(kill_all_flag) goto set_rx_io_errexit;
5478 break;
5479 }
5480 SNDLOG"\nUSER STARTED THE SELECTION OF A NEW OUTPUT DEVICE \n");
5481 pa_rxda:;
5482 clear_screen();
5483 line=3;
5484 ui.rx_dadev_no=UNDEFINED_DEVICE_CODE;
5485 ui.use_alsa&=~PORTAUDIO_RX_OUT;
5486 #if (ALSA_PRESENT == 1 || HAVE_OSS == 1)
5487 lir_text(2,line,
5488 "Use Portaudio (allows all/slow devices) for rx output? (Y/N) =>");
5489 lir_text(7,line+2,press_f1_for_info);
5490 await_processed_keyboard();
5491 if(kill_all_flag) goto set_rx_io_errexit;
5492 if(lir_inkey == F1_KEY || lir_inkey == '!')
5493 {
5494 help_message(343);
5495 goto pa_rxda;
5496 }
5497 if(lir_inkey == 'Y')
5498 {
5499 ui.use_alsa|=PORTAUDIO_RX_OUT;
5500 }
5501 else
5502 {
5503 if(lir_inkey != 'N')
5504 {
5505 goto pa_rxda;
5506 }
5507 }
5508 #else
5509 ui.use_alsa|=PORTAUDIO_RX_OUT;
5510 #endif
5511 if(!portaudio_startstop())goto pa_rxda;
5512 // Start test-thread with input soundcard device
5513 if( (double)(ui.rx_addev_no >=0 && ui.rx_addev_no < SPECIFIC_DEVICE_CODES) &&
5514 ((unsigned int)ui.network_flag&NET_RX_INPUT) == 0)
5515 {
5516 if(start_iotest(&line,RXAD) == FALSE)goto set_rxout_exit;
5517 }
5518 //get a 'portaudio' selection list for output soundcards
5519 if( (ui.use_alsa&PORTAUDIO_RX_OUT) != 0)
5520 {
5521 set_portaudio(RXDA, &line);
5522 if(kill_all_flag) goto set_rx_io_errexit;
5523 goto set_rxout_exit;
5524 }
5525 //get an 'ALSA' or 'OSS' selection list for output soundcards
5526 sprintf(s,"SELECT SOUNDCARD DEVICE FOR RX OUTPUT FROM LIST:");
5527 SNDLOG"%s\n",s);
5528 line=1;
5529 settextcolor(14);
5530 lir_text(2,line,s);
5531 settextcolor(7);
5532 line++;
5533 #if (ALSA_PRESENT == 1)
5534 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
5535 {
5536 ui.rx_dadev_no=select_alsadev(SND_PCM_STREAM_PLAYBACK, &line);
5537 if(kill_all_flag)goto set_rxout_exit;
5538 ui.rx_min_da_speed=alsa_dev_min_rate[ui.rx_dadev_no];
5539 ui.rx_max_da_speed=alsa_dev_max_rate[ui.rx_dadev_no];
5540 if(alsa_dev_min_bytes > 2 )
5541 {
5542 lir_text(0,line, "RX output only allowed with 8 or 16 bit data.");
5543 line++;
5544 lir_text(0,line, wish_anyway);
5545 line++;
5546 anyw:;
5547 await_processed_keyboard();
5548 if(kill_all_flag) goto set_rx_io_errexit;
5549 if(lir_inkey == 'N')
5550 {
5551 ui.rx_dadev_no=UNDEFINED_DEVICE_CODE;
5552 lir_text(10,line,press_any_key);
5553 goto set_rxout_exit;
5554 }
5555 if(lir_inkey != 'Y')goto anyw;
5556 alsa_dev_min_bytes=1;
5557 }
5558 ui.rx_min_da_bytes=alsa_dev_min_bytes;
5559 ui.rx_max_da_bytes=alsa_dev_max_bytes;
5560 if(ui.rx_max_da_bytes > 2)
5561 {
5562 ui.rx_max_da_bytes=2;
5563 }
5564 if(alsa_dev_min_channels >= 2 )ui.rx_min_da_channels=2;
5565 else ui.rx_min_da_channels=1;
5566 if(alsa_dev_max_channels < 2 )ui.rx_max_da_channels=1;
5567 else ui.rx_max_da_channels=2;
5568 }
5569 else
5570 #endif
5571 {
5572 #if HAVE_OSS == 1
5573 refline=line;
5574 select_ossdev(&line, RXDA);
5575 if(kill_all_flag)goto set_rx_io_errexit;
5576 if(ui.rx_dadev_no == (ui.rx_addev_no&255) && ui.rx_admode == O_RDWR)
5577 {
5578 if( (ui.rx_ad_channels == 4) || (ui.rx_input_mode&DWORD_INPUT) != 0)
5579 {
5580 lir_text(0,line,
5581 "RDWR for output not possible with 32 bit data or 4 channels.");
5582 line++;
5583 ui.rx_dadev_no=UNDEFINED_DEVICE_CODE;
5584 lir_text(10,line,press_any_key);
5585 await_processed_keyboard();
5586 if(kill_all_flag) goto set_rx_io_errexit;
5587 goto set_rxout_exit;
5588 }
5589 ui.rx_min_da_speed=ui.rx_ad_speed;
5590 ui.rx_max_da_speed=ui.rx_ad_speed;
5591 ui.rx_min_da_bytes=2;
5592 ui.rx_max_da_bytes=2;
5593 ui.rx_max_da_channels=ui.rx_ad_channels;
5594 ui.rx_min_da_channels=ui.rx_ad_channels;
5595 }
5596 else
5597 {
5598 set_rx_dadev_parms(&line);
5599 }
5600 // Now that we decided what device to use for output, let
5601 // the user decide how to use it. (It may become microphone input).
5602 if(ui.rx_dadev_no != UNDEFINED_DEVICE_CODE)
5603 {
5604 make_devname(ui.rx_dadev_no, dev_name);
5605 if(kill_all_flag)goto set_rx_io_errexit;
5606 sndlog_sync();
5607 ui.rx_damode=select_rdwr_mode(&line, ui.rx_dadev_no, O_WRONLY);
5608 }
5609 #endif
5610 }
5611 set_rxout_exit:;
5612 if((ui.rx_addev_no >=0 && ui.rx_addev_no < SPECIFIC_DEVICE_CODES)&&
5613 ((unsigned int)ui.network_flag&NET_RX_INPUT) == 0)
5614 {
5615 stop_iotest(RXAD);
5616 if(kill_all_flag)goto set_rx_io_errexit;
5617 #if HAVE_OSS == 1
5618 if((ui.use_alsa&NATIVE_ALSA_USED)==0)
5619 {
5620 if(ui.rx_dadev_no == UNDEFINED_DEVICE_CODE)
5621 {
5622 clear_lines(refline,line+4);
5623 line=refline;
5624 select_ossdev(&line, RXDA);
5625 if(kill_all_flag)goto set_rx_io_errexit;
5626 set_rx_dadev_parms(&line);
5627 if(kill_all_flag)goto set_rx_io_errexit;
5628 if(ui.rx_dadev_no != UNDEFINED_DEVICE_CODE)
5629 {
5630 ui.rx_input_mode|=NO_DUPLEX;
5631 }
5632 else
5633 {
5634 break;
5635 }
5636 }
5637 }
5638 #endif
5639 }
5640 if(ui.rx_dadev_no == UNDEFINED_DEVICE_CODE)break;
5641 line++;
5642 if(ui.rx_dadev_no == ui.tx_dadev_no)ui.tx_dadev_no=UNDEFINED_DEVICE_CODE;
5643 if(ui.rx_dadev_no == ui.tx_addev_no)ui.tx_addev_no=UNDEFINED_DEVICE_CODE;
5644 break;
5645
5646 case 'C':
5647 // ************************ CHANGE DMA RATE SETTINGS ******************************
5648 if(ui.operator_skil != OPERATOR_SKIL_NEWCOMER)
5649 {
5650 line=5;
5651 SNDLOG"\nUSER STARTED A CHANGE OF MIN/MAX DMA RATE\n");
5652 sprintf(s,"Current min, max DMA rates in Hz : %i, %i ",
5653 ui.min_dma_rate, ui.max_dma_rate);
5654 lir_text(10,line,s);
5655 SNDLOG"%s\n",s);
5656 line+=2;
5657 if(ui.operator_skil == OPERATOR_SKIL_EXPERT)
5658 {
5659 n1=MIN_DMA_RATE_EXP;
5660 m1=DMA_MIN_DIGITS_EXP;
5661 n2=MAX_DMA_RATE_EXP;
5662 m2=DMA_MAX_DIGITS_EXP;
5663 }
5664 else
5665 {
5666 n1=MIN_DMA_RATE;
5667 m1=DMA_MIN_DIGITS;
5668 n2=MAX_DMA_RATE;
5669 m2=DMA_MAX_DIGITS;
5670 }
5671 sprintf(s,"Enter new min DMA rate in Hz (%d-%d) > ",n1,n2);
5672 SNDLOG"%s\n",s);
5673 lir_text(10,line,s);
5674 i=lir_get_integer(45+m1+m2, line, m2,n1,n2);
5675 if(kill_all_flag)goto set_rx_io_errexit;
5676 sprintf(s,"User selected %i",i);
5677 SNDLOG"%s\n",s);
5678 ui.min_dma_rate=i;
5679 line+=4;
5680 sprintf(s,"%i",i);
5681 m1=strlen(s);
5682 sprintf(s,"Enter new max DMA rate in Hz (%d-%d) > ",ui.min_dma_rate,n2);
5683 SNDLOG"%s\n",s);
5684 lir_text(10,line,s);
5685 i=lir_get_integer(43+m1+m2, line, m2, ui.min_dma_rate, n2);
5686 if(kill_all_flag)goto set_rx_io_errexit;
5687 sprintf(s,"User selected %i",i);
5688 SNDLOG"%s\n",s);
5689 ui.max_dma_rate=i;
5690 }
5691 break;
5692
5693 case 'D':
5694 switch (ui.soundcard_radio)
5695 {
5696 case SOUNDCARD_RADIO_WSE:
5697 wse_setup();
5698 break;
5699
5700 case SOUNDCARD_RADIO_SI570:
5701 si570_setup();
5702 break;
5703
5704 case SOUNDCARD_RADIO_SOFT66:
5705 soft66_setup();
5706 break;
5707
5708 case SOUNDCARD_RADIO_ELEKTOR:
5709 elektor_setup();
5710 break;
5711
5712 case SOUNDCARD_RADIO_FCDPROPLUS:
5713 #if LIBUDEV_PRESENT == 1
5714 fcdproplus_setup();
5715 #else
5716 clear_screen();
5717 lir_text(5,5,"FCDProPlus not supported");
5718 lir_text(5,7,"Install the libudev package");
5719 lir_text(5,8,"Then run configure and make.");
5720 lir_text(8,10,press_any_key);
5721 await_processed_keyboard();
5722 if(kill_all_flag) goto set_rx_io_errexit;
5723 #endif
5724 break;
5725
5726 case SOUNDCARD_RADIO_AFEDRI_USB:
5727 #if LIBUDEV_PRESENT == 1
5728 afedriusb_setup();
5729 #else
5730 clear_screen();
5731 lir_text(5,5,"Afedri USB not supported");
5732 lir_text(5,7,"Install the libudev package");
5733 lir_text(5,8,"Then run configure and make.");
5734 lir_text(8,10,press_any_key);
5735 await_processed_keyboard();
5736 if(kill_all_flag) goto set_rx_io_errexit;
5737 #endif
5738 }
5739 break;
5740
5741 case 'E':
5742 // ************************* CONVERTER SETUP FOR RX ****************************
5743 lir_text(5,3,"Do you wish to use a converter in front of your receiver (Y/N)?");
5744 get_convuse:;
5745 await_processed_keyboard();
5746 if(kill_all_flag) goto set_rx_io_errexit;
5747 ui.converter_mode=0;
5748 if(lir_inkey=='N')
5749 {
5750 ui.converter_hz=0;
5751 ui.converter_mhz=0;
5752 converter_offset_mhz=0;
5753 break;
5754 }
5755 else
5756 {
5757 if(lir_inkey != 'Y')goto get_convuse;
5758 }
5759 ui.converter_mode=CONVERTER_USE;
5760 lir_text(5,5,"Enter converter LO frequency in MHz:");
5761 converter_offset_mhz=(float)lir_get_float(42,5,14,0.001F,200000.);
5762 ui.converter_mhz=(unsigned int)converter_offset_mhz;
5763 ui.converter_hz=(int)(round(1000000*(converter_offset_mhz-ui.converter_mhz)));
5764 get_updown:;
5765 lir_text(5,7,"Up or down conversion? (U/D)?");
5766 await_processed_keyboard();
5767 if(kill_all_flag) goto set_rx_io_errexit;
5768 if(lir_inkey=='U')
5769 {
5770 ui.converter_mode|=CONVERTER_UP;
5771 }
5772 else
5773 {
5774 if(lir_inkey != 'D')goto get_updown;
5775 }
5776 if( (ui.converter_mode&CONVERTER_UP) == 0)
5777 {
5778 get_losign:;
5779 lir_text(5,9,"Is LO below signal frequency (Y/N)?");
5780 await_processed_keyboard();
5781 if(kill_all_flag) goto set_rx_io_errexit;
5782 if(lir_inkey=='Y')
5783 {
5784 ui.converter_mode|=CONVERTER_LO_BELOW;
5785 }
5786 else
5787 {
5788 if(lir_inkey != 'N')goto get_losign;
5789 }
5790 }
5791 compute_converter_parameters();
5792 break;
5793
5794 case 'Z':
5795 // ************************* DISABLE OUTPUT *************************************
5796 SNDLOG"\nUSER DISABLED THE OUPUT SOUNDCARD \n");
5797 ui.rx_dadev_no=DISABLED_DEVICE_CODE;
5798 ui.rx_max_da_bytes=2;
5799 ui.rx_max_da_channels=2;
5800 ui.rx_min_da_bytes=1;
5801 ui.rx_min_da_channels=1;
5802 ui.rx_min_da_speed=5000;
5803 ui.rx_max_da_speed=1000000;
5804 break;
5805
5806 #if (ALSA_PRESENT == 1)
5807 case 'Y':
5808 // ************************** TOGGLE SOUNDSYSTEM ********************************** //
5809 // toggle between alsa-oss and native ALSA
5810 // and reset all the previous selections
5811 SNDLOG"\nUSER TOGGLED BETWEEN NATIVE-ALSA AND ALSA-OSS EMULATION\n");
5812 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
5813 {
5814 ui.use_alsa&=~NATIVE_ALSA_USED;
5815 }
5816 else
5817 {
5818 ui.use_alsa |= NATIVE_ALSA_USED;
5819 }
5820 ui.rx_dadev_no=UNDEFINED_DEVICE_CODE;
5821 ui.rx_addev_no=UNDEFINED_DEVICE_CODE;
5822 ui.tx_dadev_no=UNDEFINED_DEVICE_CODE;
5823 ui.tx_addev_no=UNDEFINED_DEVICE_CODE;
5824 ui.max_dma_rate=DEFAULT_MAX_DMA_RATE;
5825 ui.min_dma_rate=DEFAULT_MIN_DMA_RATE;
5826 goto begin_rx_set_io;
5827 #endif
5828
5829 case 'X':
5830 // ************************* EXIT TO MAIN MENU *********************************** //
5831 //validate input settings
5832 if((ui.rx_addev_no == -1) && (((unsigned int)ui.network_flag&NET_RX_INPUT) == 0))
5833 {
5834 settextcolor(12);
5835 line+=2;
5836 lir_text(2,line,"Invalid input settings: NOT YET SELECTED");
5837 line+=1;
5838 lir_text(2,line,
5839 "Hit any key to go back to the main menu and select a network input");
5840 line+=1;
5841 lir_text(2,line,
5842 "or hit U on the main menu to go back to this menu and hit A.");
5843 settextcolor(7);
5844 }
5845 else
5846 {
5847 //validate output settings
5848 if(ui.rx_dadev_no == UNDEFINED_DEVICE_CODE)
5849 {
5850 settextcolor(12);
5851 line+=2;
5852 lir_text(2,line,"Invalid output settings: NOT YET SELECTED");
5853 line+=1;
5854 lir_text(2,line,
5855 "Hit any key to go back to this menu and select option B or Z");
5856 settextcolor(7);
5857 await_processed_keyboard();
5858 if(kill_all_flag) goto set_rx_io_errexit;
5859 break;
5860 }
5861 clear_screen();
5862 lir_text(2,5,remind_parsave);
5863 lir_text(2,7,press_any_key);
5864 }
5865 await_keyboard();
5866 goto set_rx_io_exit;
5867
5868 default:
5869 break;
5870 }
5871 // ******************************************************************************** //
5872 SNDLOG"\ngoto begin_rx_set_io\n\n");
5873 if(kill_all_flag)goto set_rx_io_errexit;
5874 sndlog_sync();
5875 goto begin_rx_set_io;
5876 set_rx_io_exit:;
5877 SNDLOG"\nNormal end");
5878 set_rx_io_errexit:;
5879 SNDLOG"\n");
5880 fclose(sndlog);
5881 write_log=FALSE;
5882 }
5883
get_mic_speed(int * line,int min,int max)5884 int get_mic_speed(int *line, int min, int max)
5885 {
5886 int i,mm;
5887 char s[80];
5888 line[0]++;
5889 lir_text(2,line[0],
5890 "Note that sampling speed should be at least 8 times higher");
5891 line[0]++;
5892 lir_text(2,line[0],"than the highest voice frequency.");
5893 line[0]+=2;
5894 sprintf(s,"Select microphone A/D speed %d to %d",min, max);
5895 lir_text(5,line[0],s);
5896 i=0;
5897 while(s[i] != 0)i++;
5898 mm=lir_get_integer(i+7, line[0], 6, min, max);
5899 line[0]++;
5900 return mm;
5901 }
5902
select_txout_format(int * line)5903 void select_txout_format(int *line)
5904 {
5905 line[0]++;
5906 lir_text(3,line[0],"Select tx format");
5907 line[0]+=2;
5908 lir_text(7,line[0],"1=Single channel (normal audio)");
5909 line[0]++;
5910 lir_text(7,line[0],"2=Two channels (I and Q, frequency shifted)");
5911 line[0]++;
5912 get_txout_dachan:;
5913 await_processed_keyboard();
5914 if(kill_all_flag)return;
5915 if(lir_inkey=='1')
5916 {
5917 ui.tx_da_channels=1;
5918 }
5919 else
5920 {
5921 if(lir_inkey=='2')
5922 {
5923 ui.tx_da_channels=2;
5924 }
5925 else
5926 {
5927 goto get_txout_dachan;
5928 }
5929 }
5930 }
5931
5932
set_tx_io(void)5933 void set_tx_io(void)
5934 {
5935 char *tmptxt;
5936 int i, j, k;
5937 #if (ALSA_PRESENT == 1)
5938 int err;
5939 #endif
5940 int line;
5941 char s[256];
5942 char *tx_logfile_name="soundboard_tx_init.log";
5943 clear_screen();
5944 if(((unsigned int)ui.network_flag&NET_RX_INPUT) != 0)
5945 {
5946 lir_text(0,0,"Input from the network is currently selected.");
5947 goto not_now;
5948 }
5949 if(ui.rx_ad_channels == 0 ||
5950 ui.rx_addev_no == -1 ||
5951 ui.rx_max_da_channels == 0 ||
5952 ui.rx_dadev_no == UNDEFINED_DEVICE_CODE)
5953 {
5954 lir_text(0,0,"The RX input and output must be set up before the TX.");
5955 not_now:;
5956 lir_text(0,1,"TX is now disabled.");
5957 ui.tx_addev_no=UNDEFINED_DEVICE_CODE;
5958 ui.tx_dadev_no=UNDEFINED_DEVICE_CODE;
5959 lir_text(10,3,press_any_key);
5960 await_processed_keyboard();
5961 return;
5962 }
5963 memset(blanks, ' ',58);
5964 blanks[59]=0;
5965 if(ui.tx_ad_channels == 0)ui.tx_addev_no=UNDEFINED_DEVICE_CODE;
5966 if(ui.tx_da_channels == 0)ui.tx_dadev_no=UNDEFINED_DEVICE_CODE;
5967 sndlog=fopen(tx_logfile_name, "w");
5968 if(sndlog == NULL)
5969 {
5970 lirerr(1016);
5971 return;
5972 }
5973 write_log=TRUE;
5974 begin_tx_set_io:;
5975 clear_screen();
5976 if(kill_all_flag)goto set_tx_io_errexit;
5977 #if (ALSA_PRESENT == 1)
5978 lir_text(0,0,"The current setting is:");
5979 lir_text(0,1,"Use RX setup menu to toggle between native ALSA and alsa-oss.");
5980 i=ui.use_alsa;
5981 settextcolor(10);
5982 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
5983 {
5984 lir_text(24,0,"native ALSA");
5985 }
5986 else
5987 {
5988 lir_text(24,0,"alsa-oss ");
5989 }
5990 sprintf(s,"ALSA library version:%s",SND_LIB_VERSION_STR);
5991 settextcolor(7);
5992 lir_text(37,0,s);
5993 #else
5994 ui.use_alsa&=~NATIVE_ALSA_USED;
5995 lir_text(0,0,"This system uses OSS, alsa-oss or legacy sound.");
5996 #endif
5997 clear_lines(1,4);
5998 line=2;
5999 // **************************************************************
6000 // Show the current TX output settings on the screen.
6001 // **************************************************************
6002 lir_text(0,line,"Linrad TX output from:");
6003 settextcolor(10);
6004 sprintf(s,"UNKNOWN (no=%d)",ui.tx_dadev_no);
6005 tmptxt=s;
6006 i=0;
6007 j=1;
6008 if(ui.tx_dadev_no == UNDEFINED_DEVICE_CODE)
6009 {
6010 tmptxt="NOT YET SELECTED";
6011 j=0;
6012 }
6013 else
6014 {
6015 #if (ALSA_PRESENT == 1)
6016 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
6017 {
6018 err=alsa_get_dev_names (ui.tx_dadev_no);
6019 if(err < 0)
6020 {
6021 sprintf(s,"invalid card/device ( alsa-device-seq-nmbr = %i )",
6022 ui.tx_dadev_no );
6023 tmptxt=s;
6024 j=0;
6025 }
6026 else
6027 {
6028 sprintf(s,"Soundcard =%s",alsa_dev_soundcard_name);
6029 lir_text(22,line,s);
6030 settextcolor(7);
6031 i++;
6032 SNDLOG"Initial TXout setting: %s\n",s);
6033 sprintf(s,"Dev name = %s",alsa_dev_name);
6034 lir_text(2,line+i,s);
6035 i++;
6036 SNDLOG"%s\n",s);
6037 sprintf(s,"Pcm name = %s",alsa_dev_plughw_pcm_name);
6038 lir_text(2,line+i,s);
6039 i++;
6040 SNDLOG"%s\n",s);
6041 sprintf(s,"Seq nmbr = %i",alsa_dev_seq_nmbr);
6042 lir_text(2,line+i,s);
6043 SNDLOG"%s\n",s);
6044 }
6045 }
6046 else
6047 #endif
6048 {
6049 #if HAVE_OSS == 1
6050 make_devname(ui.tx_dadev_no, dev_name);
6051 if(kill_all_flag)goto set_tx_io_errexit;
6052 sprintf(s,"Device name =%s",dev_name);
6053 tmptxt=s;
6054 #endif
6055 }
6056 }
6057 if(i == 0)
6058 {
6059 lir_text(22,line,tmptxt);
6060 settextcolor(7);
6061 SNDLOG"Initial TXout setting: %s\n",tmptxt);
6062 }
6063 line+=i+1;
6064 if(j)
6065 {
6066 sprintf(s,"sample rate = %i ",ui.tx_da_speed );
6067 SNDLOG"%s\n",s);
6068 lir_text(2,line,s);
6069 line++;
6070 sprintf(s,"No of output bytes = %d (%d bits)",
6071 ui.tx_da_bytes, 8*ui.tx_da_bytes);
6072 SNDLOG"%s\n",s);
6073 lir_text(2,line,s);
6074 line++;
6075 sprintf(s,"No of output chans = %d", ui.tx_da_channels);
6076 SNDLOG"%s\n",s);
6077 lir_text(2,line,s);
6078 line++;
6079 }
6080 line+=2;
6081 // **************************************************************
6082 // Show the current TX input settings on the screen.
6083 // **************************************************************
6084 lir_text(0,line,"Linrad TX input to:");
6085 settextcolor(10);
6086 sprintf(s,"UNKNOWN (no=%d)",ui.tx_addev_no);
6087 tmptxt=s;
6088 i=0;
6089 k=1;
6090 if(ui.tx_addev_no == UNDEFINED_DEVICE_CODE)
6091 {
6092 tmptxt="NOT YET SELECTED";
6093 k=0;
6094 }
6095 else
6096 {
6097 #if (ALSA_PRESENT == 1)
6098 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
6099 {
6100 err=alsa_get_dev_names (ui.tx_addev_no);
6101 if(err < 0)
6102 {
6103 sprintf(s,"invalid card/device ( alsa-device-seq-nmbr = %i )",
6104 ui.tx_addev_no );
6105 tmptxt=s;
6106 k=0;
6107 }
6108 else
6109 {
6110 sprintf(s,"Soundcard =%s",alsa_dev_soundcard_name);
6111 lir_text(22,line,s);
6112 settextcolor(7);
6113 i++;
6114 SNDLOG"Initial TXin setting: %s\n",s);
6115 sprintf(s,"Dev name = %s",alsa_dev_name);
6116 lir_text(2,line+i,s);
6117 i++;
6118 SNDLOG"%s\n",s);
6119 sprintf(s,"Pcm name = %s",alsa_dev_plughw_pcm_name);
6120 lir_text(2,line+i,s);
6121 i++;
6122 SNDLOG"%s\n",s);
6123 sprintf(s,"Seq nmbr = %i",alsa_dev_seq_nmbr);
6124 lir_text(2,line+i,s);
6125 SNDLOG"%s\n",s);
6126 }
6127 }
6128 else
6129 #endif
6130 {
6131 #if HAVE_OSS == 1
6132 make_devname(ui.tx_addev_no, dev_name);
6133 sprintf(s,"Device name =%s",dev_name);
6134 tmptxt=s;
6135 #endif
6136 }
6137 }
6138 if(i == 0)
6139 {
6140 lir_text(22,line,tmptxt);
6141 settextcolor(7);
6142 SNDLOG"Initial TXin setting: %s\n",tmptxt);
6143 }
6144 line+=i+1;
6145 if(k)
6146 {
6147 sprintf(s,"sample rate = %i ",ui.tx_ad_speed);
6148 SNDLOG"%s\n",s);
6149 lir_text(2,line,s);
6150 line++;
6151 sprintf(s,"No of input bytes = %d (%d bits)",
6152 ui.tx_ad_bytes, 8*ui.tx_ad_bytes);
6153 SNDLOG"%s\n",s);
6154 lir_text(2,line,s);
6155 line++;
6156 sprintf(s,"No of input chans = %d", ui.tx_ad_channels);
6157 SNDLOG"%s\n",s);
6158 lir_text(2,line,s);
6159 }
6160 line+=2;
6161 sndlog_sync();
6162 // **************************************************************
6163 // Ask whether the user wants to change something and act accordingly.
6164 // **************************************************************
6165 lir_text(0,line,"A = Change the output settings.");
6166 line++;
6167 lir_text(0,line,"B = Change the input settings.");
6168 line++;
6169 lir_text(0,line,"X = To main menu.");
6170 setup_menu:;
6171 await_processed_keyboard();
6172 if(kill_all_flag)goto set_tx_io_errexit;
6173 line=0;
6174 switch(lir_inkey)
6175 {
6176 case 'A':
6177 clear_screen();
6178 if(ui.rx_addev_no >=0 && ui.rx_addev_no < SPECIFIC_DEVICE_CODES)
6179 {
6180 if(start_iotest(&line,RXAD) == FALSE)goto set_txout_exit;
6181 }
6182 if(ui.rx_dadev_no >=0 && ui.rx_dadev_no < SPECIFIC_DEVICE_CODES)
6183 {
6184 if(start_iotest(&line,RXDA) == FALSE)goto set_txout_exit;
6185 }
6186 sprintf(s,"SELECT SOUNDCARD/DEVICE FOR TX OUTPUT FROM LIST:");
6187 SNDLOG"%s\n",s);
6188 lir_text(0,line,s);
6189 line++;
6190 #if (ALSA_PRESENT == 1)
6191 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
6192 {
6193 ui.tx_dadev_no=select_alsadev(SND_PCM_STREAM_PLAYBACK, &line);
6194 if(kill_all_flag)goto set_txout_exit;
6195 if(alsa_dev_min_rate[ui.tx_dadev_no] !=
6196 alsa_dev_max_rate[ui.tx_dadev_no])
6197 {
6198 sprintf(s,"Select Tx D/A speed %d to %d",
6199 alsa_dev_min_rate[ui.tx_dadev_no],
6200 alsa_dev_max_rate[ui.tx_dadev_no]);
6201 lir_text(5,line,s);
6202 i=0;
6203 while(s[i] != 0)i++;
6204 ui.tx_da_speed=lir_get_integer(i+7, line, 6,
6205 alsa_dev_min_rate[ui.tx_dadev_no],
6206 alsa_dev_max_rate[ui.tx_dadev_no]);
6207 if(kill_all_flag)goto set_txout_exit;
6208 line++;
6209 }
6210 else
6211 {
6212 ui.tx_da_speed=alsa_dev_min_rate[ui.tx_dadev_no];
6213 }
6214 select_txout_format(&line);
6215 if(kill_all_flag)goto set_txout_exit;
6216 if(alsa_dev_max_bytes > 2)
6217 {
6218 if(alsa_dev_max_bytes != 4)
6219 {
6220 lirerr(327761);
6221 return;
6222 }
6223 if(alsa_dev_min_bytes == 4)
6224 {
6225 ui.tx_da_bytes=4;
6226 }
6227 else
6228 {
6229 line++;
6230 lir_text(5,line,"Select tx no of bytes (2 or 4)");
6231 alsa_get_tx_dabytes:;
6232 ui.tx_da_bytes=lir_get_integer(36,line,2,2,4);
6233 if(ui.tx_da_bytes==3)goto alsa_get_tx_dabytes;
6234 }
6235 }
6236 else
6237 {
6238 ui.tx_da_bytes=2;
6239 }
6240 }
6241 else
6242 #endif
6243 {
6244 #if HAVE_OSS == 1
6245 select_ossdev(&line, TXDA);
6246 if(kill_all_flag)goto set_tx_io_errexit;
6247 if(ui.tx_dadev_no == (ui.rx_addev_no&255) && ui.rx_admode == O_RDWR)
6248 {
6249 if(ui.tx_dadev_no == ui.rx_dadev_no)
6250 {
6251 lir_text(line,0,"Device used for RX input and output.");
6252 goto nodup;
6253 }
6254 if(ui.rx_ad_channels == 4)
6255 {
6256 lir_text(0,line,"RDWR for TX output not possible with 4 channels.");
6257 nodup:;
6258 line++;
6259 ui.tx_dadev_no=UNDEFINED_DEVICE_CODE;
6260 lir_text(10,line,press_any_key);
6261 await_processed_keyboard();
6262 goto set_txout_exit;
6263 }
6264 //set speed
6265 ui.tx_da_speed=ui.rx_ad_speed;
6266 ui.tx_da_bytes=2;
6267 if( (ui.rx_input_mode&DWORD_INPUT) != 0)ui.tx_da_bytes=4;
6268 ui.tx_da_channels=2;
6269 }
6270 else
6271 {
6272 if(dev_min_wr_speed[ui.tx_dadev_no] != dev_max_wr_speed[ui.tx_dadev_no])
6273 {
6274 sprintf(s,"Select Tx D/A speed %d to %d",
6275 dev_min_wr_speed[ui.tx_dadev_no], dev_max_wr_speed[ui.tx_dadev_no]);
6276 lir_text(5,line,s);
6277 i=0;
6278 while(s[i] != 0)i++;
6279 ui.tx_da_speed=lir_get_integer(i+7, line, 6,
6280 dev_min_wr_speed[ui.tx_dadev_no], dev_max_wr_speed[ui.tx_dadev_no]);
6281 line++;
6282 }
6283 else
6284 {
6285 ui.tx_da_speed=dev_min_wr_speed[ui.tx_dadev_no];
6286 }
6287 // Rely on the driver to allow one or two channels.
6288 // 4Front returns 4 for a Delta44 in cooked mode so
6289 // the "clever" code does not work.
6290 dev_wr_channels[ui.tx_dadev_no]=3;
6291 select_txout_format(&line);
6292 if( (dev_wr_bytes[ui.tx_dadev_no]&6) == 6)
6293 {
6294 line++;
6295 lir_text(5,line,"Select tx no of bytes (2 or 4)");
6296 get_tx_dabytes:;
6297 ui.tx_da_bytes=lir_get_integer(36,line,2,2,4);
6298 if(ui.tx_da_bytes==3)goto get_tx_dabytes;
6299 }
6300 else
6301 {
6302 ui.tx_da_bytes=dev_wr_bytes[ui.tx_dadev_no]&6;
6303 }
6304 }
6305 #endif
6306 }
6307 set_txout_exit:;
6308 if(ui.rx_dadev_no >=0 && ui.rx_dadev_no < SPECIFIC_DEVICE_CODES)
6309 {
6310 stop_iotest(RXDA);
6311 }
6312 if(ui.rx_addev_no >=0 && ui.rx_addev_no < SPECIFIC_DEVICE_CODES)
6313 {
6314 stop_iotest(RXAD);
6315 }
6316 break;
6317
6318 case 'B':
6319 clear_screen();
6320 if(ui.tx_dadev_no == UNDEFINED_DEVICE_CODE)
6321 {
6322 lir_text(0,line,"Set tx output device first.");
6323 line+=2;
6324 lir_text(10,line,press_any_key);
6325 await_processed_keyboard();
6326 break;
6327 }
6328 ui.tx_addev_no=UNDEFINED_DEVICE_CODE;
6329 if(ui.rx_addev_no >=0 && ui.rx_addev_no < SPECIFIC_DEVICE_CODES)
6330 {
6331 if(start_iotest(&line,RXAD) == FALSE)goto set_txin_exit;
6332 }
6333 if(start_iotest(&line,RXDA) == FALSE)goto set_txin_exit;
6334 if(start_iotest(&line,TXDA) == FALSE)goto set_txin_exit;
6335 sprintf(s,"SELECT SOUNDCARD/DEVICE FOR TX INPUT FROM LIST:");
6336 SNDLOG"%s\n",s);
6337 lir_text(0,line,s);
6338 line++;
6339 #if (ALSA_PRESENT == 1)
6340 if( (ui.use_alsa&NATIVE_ALSA_USED)!=0)
6341 {
6342 ui.tx_addev_no=select_alsadev(SND_PCM_STREAM_CAPTURE, &line);
6343 if(kill_all_flag)goto set_tx_io_errexit;
6344 sprintf(s,"Enter sample-rate >");
6345 lir_text(0,line,s);
6346 SNDLOG"%s\n",s);
6347 ui.tx_ad_speed=lir_get_integer(21, line, 6,
6348 alsa_dev_min_rate[ui.tx_addev_no],
6349 alsa_dev_max_rate[ui.tx_addev_no]);
6350 if(kill_all_flag)goto set_tx_io_errexit;
6351 sprintf(s,"User selected %i",i);
6352 SNDLOG"%s\n",s);
6353 lir_text(29,line,blanks);
6354 line++;
6355 SNDLOG"\n\n");
6356 //get number of bytes and check
6357 if(alsa_dev_max_bytes > 2)
6358 {
6359 sprintf(s,"Enter number of input bytes (2 or 4) >");
6360 select_number_input_bytes:;
6361 SNDLOG"%s\n",s);
6362 lir_text(0,line,s);
6363 ui.tx_ad_bytes=lir_get_integer(39, line, 1,2,4);
6364 if(kill_all_flag)goto set_tx_io_errexit;
6365 if(ui.tx_ad_bytes==3)
6366 {
6367 settextcolor(12);
6368 sprintf(s,"invalid selection, try again");
6369 SNDLOG"%s\n",s);
6370 lir_text(44,line,s);
6371 settextcolor(7);
6372 goto select_number_input_bytes;
6373 }
6374 line++;
6375 }
6376 else
6377 {
6378 ui.tx_ad_bytes=2;
6379 SNDLOG"\n\n");
6380 }
6381 ui.tx_ad_channels=1;
6382 line+=2;
6383 }
6384 else
6385 #endif
6386 {
6387 #if HAVE_OSS == 1
6388 select_ossdev(&line, TXAD);
6389 if(kill_all_flag)goto set_tx_io_errexit;
6390 if(ui.tx_addev_no == ui.rx_dadev_no && ui.rx_damode == O_RDWR)
6391 {
6392 if(ui.rx_max_da_bytes != 2)
6393 {
6394 ui.tx_addev_no=UNDEFINED_DEVICE_CODE;
6395 lir_text(0,line,"Useless device. Only 8 bit.");
6396 }
6397 else
6398 {
6399 lir_text(0,line,"Rx output parameters modified for RDWR usage");
6400 ui.rx_min_da_bytes=2;
6401 ui.tx_ad_bytes=2;
6402 if(ui.rx_max_da_channels == 2)
6403 {
6404 ui.rx_min_da_channels=2;
6405 ui.tx_ad_channels=2;
6406 }
6407 else
6408 {
6409 ui.rx_max_da_channels=1;
6410 ui.tx_ad_channels=1;
6411 }
6412 ui.tx_ad_speed=get_mic_speed(&line, ui.rx_min_da_speed,
6413 ui.rx_max_da_speed);
6414 ui.rx_min_da_speed=ui.tx_ad_speed;
6415 ui.rx_max_da_speed=ui.tx_ad_speed;
6416 }
6417 line++;
6418 lir_text(5,line,press_any_key);
6419 await_processed_keyboard();
6420 goto set_txin_exit;
6421 }
6422 // Use one channel if the device can do both one and two channels.
6423 if( (3 & dev_rd_channels[ui.tx_addev_no]) == 3)
6424 {
6425 ui.tx_ad_channels=1;
6426 }
6427 else
6428 {
6429 ui.tx_ad_channels=3&dev_rd_channels[ui.tx_addev_no];
6430 }
6431 if( (dev_rd_channels[ui.tx_addev_no]&3) == 3)
6432 {
6433 line++;
6434 lir_text(0,line,"Select microphone no of bytes (2 or 4)");
6435 get_micbytes:;
6436 ui.tx_ad_bytes=lir_get_integer(39,line,2,2,4);
6437 if(ui.tx_ad_bytes==3)goto get_micbytes;
6438 line++;
6439 }
6440 else
6441 {
6442 ui.tx_ad_bytes=dev_rd_channels[ui.tx_addev_no]&3;
6443 }
6444 if(dev_min_rd_speed[ui.tx_addev_no] != dev_max_rd_speed[ui.tx_addev_no])
6445 {
6446 ui.tx_ad_speed=get_mic_speed(&line, dev_min_rd_speed[ui.tx_addev_no],
6447 dev_max_rd_speed[ui.tx_addev_no]);
6448 }
6449 else
6450 {
6451 ui.tx_ad_speed=dev_min_rd_speed[ui.tx_addev_no];
6452 }
6453 #endif
6454 }
6455 set_txin_exit:;
6456 stop_iotest(TXDA);
6457 stop_iotest(RXDA);
6458 if(ui.rx_addev_no >=0 && ui.rx_addev_no < SPECIFIC_DEVICE_CODES)
6459 {
6460 stop_iotest(RXAD);
6461 }
6462 if(ui.tx_addev_no != UNDEFINED_DEVICE_CODE)
6463 {
6464 line=0;
6465 clear_screen();
6466 get_enable:;
6467 if(kill_all_flag)break;
6468 lir_text(4,line,"Enable Tx while running receive modes ? (Y/N) =>");
6469 await_processed_keyboard();
6470 if(lir_inkey == 'Y')
6471 {
6472 ui.tx_enable=1;
6473 line+=2;
6474 lir_text(0,line,"Parameters for speech processor, keying, etc. have to");
6475 line++;
6476 lir_text(0,line,"be set up and saved before Tx becomes enabled in Rx modes.");
6477 line++;
6478 }
6479 else
6480 {
6481 if(lir_inkey != 'N')goto get_enable;
6482 ui.tx_enable=0;
6483 }
6484 line+=2;
6485 lir_text(0,line,"The tx pilot tone may control fast Rx/Tx switching.");
6486 line++;
6487 lir_text(0,line,"Set pilot tone level in dB below signal (50-130)");
6488 ui.tx_pilot_tone_db=lir_get_integer(49, line, 3, 50, 130);
6489 line+=2;
6490 lir_text(0,line,"Set prestart in microseconds (0-100000)");
6491 ui.tx_pilot_tone_prestart=lir_get_integer(39, line, 6, 0, 100000);
6492 line+=2;
6493 settextcolor(15);
6494 lir_text(5,line,remind_parsave);
6495 settextcolor(7);
6496 line+=2;
6497 lir_text(5,line,press_any_key);
6498 await_processed_keyboard();
6499 }
6500 break;
6501
6502 case 'X':
6503 goto set_tx_io_exit;
6504
6505 default:
6506 goto setup_menu;
6507 }
6508 SNDLOG"goto begin_tx_set_io\n\n");
6509 sndlog_sync();
6510 goto begin_tx_set_io;
6511 set_tx_io_exit:;
6512 SNDLOG"\nNormal end");
6513 set_tx_io_errexit:;
6514 SNDLOG"\n");
6515 fclose(sndlog);
6516 write_log=FALSE;
6517 }
6518
6519
6520