patch-src_server-main_C 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539
  1. $OpenBSD: patch-src_server-main_C,v 1.3 2017/05/02 16:47:32 espie Exp $
  2. Index: src/server-main.C
  3. --- src/server-main.C.orig
  4. +++ src/server-main.C
  5. @@ -20,21 +20,14 @@
  6. */
  7. -#include <sys/mman.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <unistd.h>
  11. #include <string.h>
  12. #include <errno.h>
  13. -#include <sys/socket.h>
  14. -#include <sys/types.h>
  15. -#include <sys/stat.h>
  16. -#include <sys/un.h>
  17. -#include <netinet/in.h>
  18. -#include <sys/time.h>
  19. #include <fcntl.h>
  20. -#include <sys/soundcard.h>
  21. #include <sys/ioctl.h>
  22. +#include <poll.h>
  23. #include "psk31-receiver.h"
  24. #include "psk31-transmitter.h"
  25. #include "psk31-fft.h"
  26. @@ -56,13 +49,15 @@
  27. #define RX 0
  28. // receive / transmit state information
  29. -int full_duplex;
  30. +int full_duplex = 0;
  31. int chans;
  32. int size;
  33. int bits;
  34. -static char *audio_path="/dev/dsp";
  35. +static char *audio_path=NULL;
  36. static char *ptt_path=NULL;
  37. -static int audiofd=-1, pttfd=-1;
  38. +static int pttfd=-1;
  39. +static struct sio_hdl *hdl;
  40. +static struct sio_par par;
  41. static int ptt_invert=0;
  42. static int ctl_ptt(int onoff);
  43. int scconfig[2]; /* [0]=8bit/16bit [1]=mono/stereo */
  44. @@ -125,7 +120,16 @@ typedef struct
  45. #define N_BUFFERS 6
  46. static buffer_t buffers[N_BUFFERS];
  47. +long long realpos, playpos;
  48. +static void onmove(void *addr, int delta)
  49. +{
  50. + struct sio_par *par = (struct sio_par *)addr;
  51. +
  52. + realpos += delta * par->bps * par->pchan;
  53. +}
  54. +
  55. +
  56. static void init_buffer()
  57. {
  58. int i;
  59. @@ -203,216 +207,177 @@ buffer_t *b = buffers+bufnr;
  60. */
  61. int init_audio ()
  62. {
  63. - int val;
  64. - int speed = 8000;
  65. + uint speed = 8000;
  66. int frags;
  67. + int want_bits, want_chans, retval = 0;
  68. pthread_mutex_lock(&mutex_fd); //get the mutex for soundcard fd
  69. - if (audiofd > 2)
  70. + if (hdl != NULL)
  71. {
  72. - close (audiofd);
  73. - usleep (50000); //strange
  74. - audiofd = -1;
  75. + sio_close(hdl);
  76. + hdl = NULL;
  77. }
  78. /* Open the soundcard */
  79. - if (audiofd < 0)
  80. + if (hdl == NULL)
  81. {
  82. if (trDir == RX)
  83. {
  84. - audiofd = open(audio_path, O_RDONLY|O_NONBLOCK);
  85. + /* audio_path */
  86. + hdl = sio_open(NULL, SIO_REC, 0);
  87. }
  88. else
  89. {
  90. - audiofd = open(audio_path, O_WRONLY|O_NONBLOCK);
  91. + hdl = sio_open(NULL, SIO_PLAY, 0);
  92. }
  93. }
  94. - if (audiofd < 0)
  95. + if (hdl == NULL)
  96. {
  97. - fprintf (stderr, "init_audio: can't open %s\n", audio_path);
  98. + fprintf (stderr, "init_audio: can't open ");
  99. + if (audio_path == NULL)
  100. + fprintf (stderr, "default sndio device\n");
  101. + else
  102. + fprintf (stderr, "%s\n", audio_path);
  103. return -1;
  104. }
  105. + sio_initpar(&par);
  106. +
  107. /* check parameter to see if 8 or 16 bits was requested */
  108. /* return 1 or 2 if set 8 or 16 bits format failed */
  109. - switch (scconfig[0])
  110. + want_bits = scconfig[0];
  111. + switch (want_bits)
  112. {
  113. case 0: /* 8 bits requested */
  114. - val=AFMT_U8;
  115. - if (ioctl(audiofd, SNDCTL_DSP_SETFMT, &val) <0)
  116. - {
  117. - /* ioctl failed */
  118. - fprintf (stderr, "init_audio: ioctl SETFMT 8 failed\n");
  119. - return -1;
  120. - }
  121. -
  122. - /* see if 8 bit worked */
  123. - if (val == AFMT_U8)
  124. - {
  125. - /* we can use 8 bit */
  126. - size = 1;
  127. - bits = 8;
  128. - // fprintf (stderr, "init_audio: trying 8 bit ");
  129. - }
  130. - else /* 8 bit failed */
  131. - {
  132. - fprintf (stderr, "init_audio: failed to set to 8 bits\n");
  133. - return 1;
  134. - }
  135. + par.bits = 8;
  136. + par.sig = 0;
  137. break;
  138. -
  139. case 1: /* 16 bits requested */
  140. - val=AFMT_S16_NE;
  141. - if (ioctl(audiofd, SNDCTL_DSP_SETFMT, &val) <0)
  142. - {
  143. - /* ioctl failed */
  144. - fprintf (stderr, "init_audio: ioctl SETFMT 16 failed\n");
  145. - return -1;
  146. - }
  147. -
  148. - /* see if 16 bit worked */
  149. - if (val == AFMT_S16_NE)
  150. - {
  151. - /* we can use 16 bit */
  152. - size = 2;
  153. - bits = 16;
  154. - // fprintf (stderr, "init_audio: trying 16 bit ");
  155. - }
  156. - else /* set 16 bit failed */
  157. - {
  158. - fprintf (stderr, "init_audio: failed to set to 16 bits\n");
  159. - return 2;
  160. - }
  161. + par.bits = 16;
  162. + par.sig = 1;
  163. break;
  164. -
  165. - default: /* Invalid request */
  166. - fprintf (stderr, "\ninit_audio: invalid 8 or 16 bit request\n");
  167. + default:
  168. + fprintf (stderr, "\ninit_audio: invalid bit-depth request\n");
  169. return -1;
  170. }
  171. /* check parameter to see if MONO or STEREO was requested */
  172. /* return 3 or 4 if set mono or stereo format failed */
  173. + want_chans = scconfig[1];
  174. switch (scconfig[1])
  175. {
  176. case 0: /* mono requested */
  177. - val=MONO;
  178. - if( ioctl(audiofd, SNDCTL_DSP_STEREO, &val)<0 )
  179. - {
  180. - /* ioctl failed */
  181. - fprintf (stderr,"\ninit_audio: ioctl failed - MONO\n");
  182. - return -1;
  183. - }
  184. - /* see if mono worked */
  185. - if (val == MONO)
  186. - {
  187. - /* we can use mono */
  188. - fprintf (stderr, "mono format\n");
  189. - chans = MONO;
  190. - }
  191. + if (trDir == RX)
  192. + par.rchan = 1;
  193. else
  194. - {
  195. - /* set mono failed */
  196. - fprintf (stderr, "\ninit_audio: request for mono failed\n");
  197. - return 3;
  198. - }
  199. + par.pchan = 1;
  200. break;
  201. -
  202. case 1: /* stereo request */
  203. - val = STEREO;
  204. - if( ioctl(audiofd, SNDCTL_DSP_STEREO, &val)<0 )
  205. - {
  206. - fprintf (stderr, "\ninit_audio: ioctl failed - STEREO\n");
  207. - return -1;
  208. - }
  209. - /* see if stereo worked */
  210. - if (val == STEREO)
  211. - {
  212. - /* we can use stereo */
  213. - fprintf (stderr, "stereo format\n");
  214. - size = size * 2;
  215. - chans = STEREO;
  216. - }
  217. + if (trDir == RX)
  218. + par.rchan = 2;
  219. else
  220. - {
  221. - /* set stereo failed */
  222. - fprintf (stderr, "\ninit_audio: request for stereo failed\n");
  223. - return 4;
  224. - }
  225. + par.pchan = 2;
  226. break;
  227. -
  228. default:
  229. - fprintf (stderr, "\ninit_audio: invalid mono or stereo request\n");
  230. - return -1;
  231. + fprintf (stderr, "\ninit_audio: invalid mono or stereo request\n");
  232. + return -1;
  233. }
  234. - /* setup the rest */
  235. - val = speed;
  236. - if (ioctl(audiofd, SNDCTL_DSP_SPEED, &val) < 0)
  237. + if (want_bits == 0)
  238. + frags = 8;
  239. + else
  240. + frags = 10;
  241. +
  242. + if (want_chans == 1)
  243. + frags++;
  244. +
  245. + par.appbufsz = 1 << frags;
  246. +
  247. + par.rate = speed;
  248. +
  249. + if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par))
  250. {
  251. - fprintf (stderr, "init_audio: ioctl SPEED failed\n");
  252. + fprintf (stderr, "init_audio: error setting parameters\n");
  253. return -1;
  254. }
  255. - if (val == speed)
  256. + if (want_bits == 0 && (par.bits != 8 || par.sig != 0))
  257. {
  258. - fprintf (stderr,"init_audio: using %d sample rate\n", val);
  259. + fprintf (stderr, "init_audio: could not set 8-bit mode\n");
  260. + retval = 1;
  261. }
  262. - else
  263. + else if (want_bits == 1 && (par.bits != 16 || par.sig != 1))
  264. {
  265. - fprintf(stderr,"inexact sampling rate: "
  266. - "request for %d resulted in %d\n",speed,val);
  267. + fprintf (stderr, "init_audio: could not set 16-bit mode\n");
  268. + retval = 2;
  269. }
  270. - if (bits == 8)
  271. - frags = 0x00020008;
  272. + if (par.bits == 8 && par.sig == 0)
  273. + {
  274. + size = 1;
  275. + bits = 8;
  276. + }
  277. + else if (par.bits == 16 && par.sig == 1)
  278. + {
  279. + size = 2;
  280. + bits = 16;
  281. + }
  282. else
  283. - frags = 0x0002000A;
  284. + {
  285. + fprintf (stderr, "init_audio: could not get usable format\n");
  286. + return -1;
  287. + }
  288. - if (chans == STEREO)
  289. - frags++;
  290. + if (want_chans == 0 &&
  291. + ((trDir == RX && par.rchan != 1) || (trDir == TX && par.pchan != 1)))
  292. + {
  293. + fprintf (stderr, "\ninit_audio: request for mono failed\n");
  294. + retval = 3;
  295. + }
  296. + else if (want_chans == 1 &&
  297. + ((trDir == RX && par.rchan != 2) || (trDir == TX && par.pchan != 2)))
  298. + {
  299. + fprintf (stderr, "\ninit_audio: request for stereo failed\n");
  300. + retval = 4;
  301. + }
  302. - val = frags;
  303. - ioctl(audiofd, SNDCTL_DSP_SETFRAGMENT, &val);
  304. + if ((trDir == RX && par.rchan == 1) || (trDir == TX && par.pchan == 1))
  305. + {
  306. + fprintf (stderr, "mono format\n");
  307. + chans = MONO;
  308. + }
  309. + else if ((trDir == RX && par.rchan == 2) || (trDir == TX && par.pchan == 2))
  310. + {
  311. + fprintf (stderr, "stereo format\n");
  312. + size = size * 2;
  313. + chans = STEREO;
  314. + }
  315. -/*****************************************************/
  316. -#if 0
  317. - audio_buf_info inInfo, outInfo;
  318. - if (ioctl(audiofd, SNDCTL_DSP_GETISPACE, &inInfo))
  319. - perror ("init_audio: SNDCTL_DSP_GETOSPACE");
  320. - if (ioctl(audiofd, SNDCTL_DSP_GETOSPACE, &outInfo))
  321. - perror ("init_audio: SNDCTL_DSP_GETOSPACE");
  322. -
  323. -printf ("In fragments=0x%08x fragstotal=0x%08x fragsize=0x%08x\n",
  324. - inInfo.fragments, inInfo.fragstotal, inInfo.fragsize);
  325. -printf ("Out fragments=0x%08x fragstotal=0x%08x fragsize=0x%08x\n",
  326. - outInfo.fragments, outInfo.fragstotal, outInfo.fragsize);
  327. -#endif
  328. -/*****************************************************/
  329. -
  330. - // Check if the device is operating in full duplex mode
  331. - if( ioctl(audiofd, SNDCTL_DSP_GETCAPS, &val)<0 )
  332. - perror("Warning: GETCAPS on audio device failed");
  333. + if (abs(int(par.rate) - int(speed)) < speed * 1.03)
  334. + {
  335. + fprintf (stderr, "init_audio: using %d sample rate\n", speed);
  336. + }
  337. else
  338. - if(val&DSP_CAP_DUPLEX)
  339. - full_duplex=1;
  340. - fprintf(stderr,"init_audio: using %s duplex mode\n",
  341. - full_duplex ? "full" : "half");
  342. + {
  343. + fprintf(stderr, "could not set sampling rate: "
  344. + "request for %d resulted in %d\n", speed, par.rate);
  345. + return -1;
  346. + }
  347. -/*****************************************************/
  348. -#if 0
  349. - val = 0;
  350. - if (ioctl(audiofd, SNDCTL_DSP_SETTRIGGER, &val) == -1)
  351. - perror("ioctl: SNDCTL_DSP_SETTRIGGER");
  352. - val = PCM_ENABLE_INPUT;
  353. - if (ioctl(audiofd, SNDCTL_DSP_SETTRIGGER, &val) == -1)
  354. - perror("ioctl: SNDCTL_DSP_SETTRIGGER");
  355. -#endif
  356. -/*****************************************************/
  357. + realpos = playpos = 0;
  358. + if (trDir == TX)
  359. + sio_onmove(hdl, onmove, &par);
  360. + if (!sio_start(hdl))
  361. + {
  362. + fprintf (stderr, "init_audio: could not start audio\n");
  363. + return -1;
  364. + }
  365. +
  366. // fprintf (stderr, "init_audio: size=%d\n", size);
  367. pthread_mutex_unlock(&mutex_fd);
  368. - return 0;
  369. + return retval;
  370. }
  371. @@ -461,10 +426,7 @@ static void *master_thr_func(void *dummy)
  372. void master_handler(void)
  373. {
  374. int res;
  375. - fd_set rset, wset, eset;
  376. - struct timeval tm;
  377. int dcd;
  378. - static short odd;
  379. buffers[COMM_RXCH].psk31rx->get_info(NULL,NULL,NULL,NULL,
  380. NULL,&dcd,NULL,NULL);
  381. @@ -487,13 +449,6 @@ void master_handler(void)
  382. lastMode = trDir;
  383. }
  384. - FD_ZERO(&rset); FD_ZERO(&wset); FD_ZERO(&eset);
  385. - FD_SET(audiofd, &rset);
  386. - FD_SET(audiofd, &eset);
  387. - if (trDir == TX)
  388. - FD_SET(audiofd, &wset);
  389. - tm.tv_sec=0; tm.tv_usec=50000; /* 50ms */
  390. - res=select(audiofd+1, &rset, &wset, &eset, &tm);
  391. /* In my older version I had the problem, that there exist
  392. * sound drivers which do not support select correctly. So this
  393. * code tries to read/write from/to the audiodevice without
  394. @@ -502,61 +457,54 @@ void master_handler(void)
  395. if (trDir == RX)
  396. {
  397. - short sample[2], save;
  398. + short buf[128];
  399. + int s = 0, todo;
  400. + char *p, *end;
  401. - for (;;)
  402. - {
  403. - pthread_mutex_lock (&mutex_fd); // grab the mutex for the fd
  404. - odd++;
  405. - res = read(audiofd, &sample, size);
  406. - if (res == 0)
  407. - {
  408. - break;
  409. - }
  410. - else if (res != size)
  411. - {
  412. - // fprintf(stderr,"%d %d\n",res,errno);
  413. - if (errno == EINTR)
  414. - {
  415. - break;
  416. - }
  417. - if (errno == EAGAIN || errno == EBUSY)
  418. - {
  419. - break;
  420. - }
  421. - perror ("Audio read failed");
  422. + pthread_mutex_lock (&mutex_fd); // grab the mutex for the fd
  423. + p = (char *)buf;
  424. + todo = sizeof(buf);
  425. + while (todo > 0) {
  426. + res = sio_read(hdl, p, todo);
  427. + if (res == 0)
  428. + {
  429. + fprintf (stderr, "Audio read failed");
  430. exit (1);
  431. - }
  432. - pthread_mutex_unlock (&mutex_fd); // release mutex for fd
  433. + }
  434. + todo -= res;
  435. + p += res;
  436. + }
  437. + pthread_mutex_unlock (&mutex_fd); // release mutex for fd
  438. + for (p = (char *)buf, end = p + sizeof(buf); p < end;)
  439. + {
  440. /******* for S16_NE stereo *******/
  441. if (chans == STEREO && bits == 16)
  442. {
  443. /* two signed 16 bits to one signed short */
  444. - sample[0] = sample[0] | sample[1];
  445. + s = (((short *)p)[0] + ((short *)p)[1]) / 2;
  446. + p += 2 * sizeof(short);
  447. }
  448. /******* for S16_NE mono *******/
  449. if (chans == MONO && bits == 16)
  450. {
  451. - /* nothing to do for this one */
  452. + s = ((short *)p)[0];
  453. + p += sizeof(short);
  454. }
  455. /******* for U8 stereo *******/
  456. if (chans==STEREO && bits == 8)
  457. {
  458. - /* two unsigned 8 bit to a signed short */
  459. - save = (((sample[0]>>8)&0xFF) - 128) * 128; //low
  460. - sample[0] = ((sample[0]&0xFF) - 128) * 128; //high
  461. - sample[0] = sample[0] | save; //mixed
  462. + s = 128 * (p[0] ^ 0x80) + (p[1] ^ 0x80);
  463. + p += 2;
  464. }
  465. /******* for U8 mono *******/
  466. if (chans == MONO && bits == 8)
  467. - {
  468. - /* unsigned 8 bit to signed short */
  469. - sample[0] = ((sample[0]&0xFF) - 128) * 128;
  470. -
  471. + {
  472. + s = 256 * (p[0] ^ 0x80);
  473. + p++;
  474. }
  475. /*****************************/
  476. @@ -569,7 +517,7 @@ void master_handler(void)
  477. pthread_mutex_unlock(&mutex_rx);
  478. continue;
  479. }
  480. - res = rx->process_rx_sample (sample[0]);
  481. + res = rx->process_rx_sample (s);
  482. pthread_mutex_unlock(&mutex_rx);
  483. if(res!=NO_CHAR)
  484. {
  485. @@ -597,13 +545,14 @@ void master_handler(void)
  486. char buffer[128];
  487. for(;;)
  488. {
  489. - res=read(audiofd, buffer, 128);
  490. + res=sio_read(hdl, buffer, 128);
  491. if(res!=128) break;
  492. }
  493. }
  494. pthread_mutex_lock (&mutex_fd);
  495. pthread_mutex_lock(&mutex_tx);
  496. + psk31tx->set_audiofd(hdl);
  497. res=psk31tx->processor();
  498. pthread_mutex_unlock(&mutex_tx);
  499. pthread_mutex_unlock (&mutex_fd);
  500. @@ -742,7 +691,7 @@ int server_main(char *audio, char *ptt, char *datadir)
  501. psk31fft->set_parameters(1024, 1024, psk31_fft::MODE_RXDATA);
  502. buffers[COMM_RXCH].psk31rx = new psk31_receiver(psk31fft);
  503. psk31tx = new psk31_transmitter();
  504. - psk31tx->set_audiofd(audiofd);
  505. + psk31tx->set_audiofd(hdl);
  506. #ifdef USE_PTHREAD