1 
2 //
3 //    This file is part of Dire Wolf, an amateur radio packet TNC.
4 //
5 //    Copyright (C) 2011, 2012, 2013, 2014, 2015  John Langner, WB2OSZ
6 //
7 //    This program is free software: you can redistribute it and/or modify
8 //    it under the terms of the GNU General Public License as published by
9 //    the Free Software Foundation, either version 2 of the License, or
10 //    (at your option) any later version.
11 //
12 //    This program is distributed in the hope that it will be useful,
13 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //    GNU General Public License for more details.
16 //
17 //    You should have received a copy of the GNU General Public License
18 //    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 //
20 
21 
22 /*------------------------------------------------------------------
23  *
24  * Module:      audio_win.c
25  *
26  * Purpose:   	Interface to audio device commonly called a "sound card" for
27  *		historical reasons.
28  *
29  *		This version uses the native Windows sound interface.
30  *
31  * Credits:	Fabrice FAURE contributed Linux code for the SDR UDP interface.
32  *
33  *		Discussion here:  http://gqrx.dk/doc/streaming-audio-over-udp
34  *
35  * Major revisions:
36  *
37  *		1.2 - Add ability to use more than one audio device.
38  *
39  *---------------------------------------------------------------*/
40 
41 
42 #include "direwolf.h"		// Sets _WIN32_WINNT for XP API level needed by ws2tcpip.h
43 				// Also includes windows.h.
44 
45 
46 #include <stdio.h>
47 #include <unistd.h>
48 #include <sys/types.h>
49 #include <stdlib.h>
50 #include <assert.h>
51 #include <ctype.h>
52 #include <io.h>
53 #include <fcntl.h>
54 
55 #include <mmsystem.h>
56 
57 #ifndef WAVE_FORMAT_96M16
58 #define WAVE_FORMAT_96M16 0x40000
59 #define WAVE_FORMAT_96S16 0x80000
60 #endif
61 
62 #include <winsock2.h>
63 #include <ws2tcpip.h>  		// _WIN32_WINNT must be set to 0x0501 before including this
64 
65 
66 #include "audio.h"
67 #include "audio_stats.h"
68 #include "textcolor.h"
69 #include "ptt.h"
70 #include "demod.h"		/* for alevel_t & demod_get_audio_level() */
71 
72 
73 
74 /* Audio configuration. */
75 
76 static struct audio_s          *save_audio_config_p;
77 
78 
79 /*
80  * Allocate enough buffers for 1 second each direction.
81  * Each buffer size is a trade off between being responsive
82  * to activity on the channel vs. overhead of having too
83  * many little transfers.
84  */
85 
86 /*
87  * Originally, we had an abitrary buf time of 40 mS.
88  *
89  * For mono, the buffer size was rounded up from 3528 to 4k so
90  * it was really about 50 mS per buffer or about 20 per second.
91  * For stereo, the buffer size was rounded up from 7056 to 7k so
92  * it was really about 43.7 mS per buffer or about 23 per second.
93  *
94  * In version 1.2, let's try changing it to 10 to reduce the latency.
95  * For mono, the buffer size was rounded up from 882 to 1k so it
96  * was really about 12.5 mS per buffer or about 80 per second.
97  */
98 
99 #define TOTAL_BUF_TIME 1000
100 #define ONE_BUF_TIME 10
101 
102 #define NUM_IN_BUF ((TOTAL_BUF_TIME)/(ONE_BUF_TIME))
103 #define NUM_OUT_BUF ((TOTAL_BUF_TIME)/(ONE_BUF_TIME))
104 
105 
106 #define roundup1k(n) (((n) + 0x3ff) & ~0x3ff)
107 
calcbufsize(int rate,int chans,int bits)108 static int calcbufsize(int rate, int chans, int bits)
109 {
110 	int size1 = (rate * chans * bits  / 8 * ONE_BUF_TIME) / 1000;
111 	int size2 = roundup1k(size1);
112 #if DEBUG
113 	text_color_set(DW_COLOR_DEBUG);
114 	dw_printf ("audio_open: calcbufsize (rate=%d, chans=%d, bits=%d) calc size=%d, round up to %d\n",
115 		rate, chans, bits, size1, size2);
116 #endif
117 
118 	/* Version 1.3 - add a sanity check. */
119 	if (size2 < 256 || size2 > 32768) {
120 	  text_color_set(DW_COLOR_ERROR);
121 	  dw_printf ("Audio buffer has unexpected extreme size of %d bytes.\n", size2);
122 	  dw_printf ("Detected at %s, line %d.\n", __FILE__, __LINE__);
123 	  dw_printf ("This might be caused by unusual audio device configuration values.\n");
124 	  size2 = 2048;
125 	  dw_printf ("Using %d to attempt recovery.\n", size2);
126 	}
127 
128 	return (size2);
129 }
130 
131 
132 /* Information for each audio stream (soundcard, stdin, or UDP) */
133 
134 static struct adev_s {
135 
136 	enum audio_in_type_e g_audio_in_type;
137 
138 /*
139  * UDP socket for receiving audio stream.
140  * Buffer, length, and pointer for UDP or stdin.
141  */
142 
143 
144 	SOCKET udp_sock;
145 	char stream_data[SDR_UDP_BUF_MAXLEN];
146 	int stream_len;
147 	int stream_next;
148 
149 
150 /* For sound output. */
151 /* out_wavehdr.dwUser is used to keep track of output buffer state. */
152 
153 #define DWU_FILLING 1		/* Ready to use or in process of being filled. */
154 #define DWU_PLAYING 2		/* Was given to sound system for playing. */
155 #define DWU_DONE 3		/* Sound system is done with it. */
156 
157 	HWAVEOUT audio_out_handle;
158 
159 	volatile WAVEHDR out_wavehdr[NUM_OUT_BUF];
160 	int out_current;		/* index to above. */
161 	int outbuf_size;
162 
163 
164 /* For sound input. */
165 /* In this case dwUser is index of next available byte to remove. */
166 
167 	HWAVEIN  audio_in_handle;
168 	WAVEHDR in_wavehdr[NUM_IN_BUF];
169 	volatile WAVEHDR *in_headp;	/* head of queue to process. */
170 	CRITICAL_SECTION in_cs;
171 
172 } adev[MAX_ADEVS];
173 
174 
175 /*------------------------------------------------------------------
176  *
177  * Name:        audio_open
178  *
179  * Purpose:     Open the digital audio device.
180  *
181  *		New in version 1.0, we recognize "udp:" optionally
182  *		followed by a port number.
183  *
184  * Inputs:      pa		- Address of structure of type audio_s.
185  *
186  *				Using a structure, rather than separate arguments
187  *				seemed to make sense because we often pass around
188  *				the same set of parameters various places.
189  *
190  *				The fields that we care about are:
191  *					num_channels
192  *					samples_per_sec
193  *					bits_per_sample
194  *				If zero, reasonable defaults will be provided.
195  *
196  * Outputs:	pa		- The ACTUAL values are returned here.
197  *
198  *				The Linux version adjusts strange values to the
199  *				nearest valid value.  Don't know, yet, if Windows
200  *				does the same or just fails.  Or performs some
201  *				expensive resampling from a rate supported by
202  *				hardware.
203  *
204  *				These might not be exactly the same as what was requested.
205  *
206  *				Example: ask for stereo, 16 bits, 22050 per second.
207  *				An ordinary desktop/laptop PC should be able to handle this.
208  *				However, some other sort of smaller device might be
209  *				more restrictive in its capabilities.
210  *				It might say, the best I can do is mono, 8 bit, 8000/sec.
211  *
212  *				The sofware modem must use this ACTUAL information
213  *				that the device is supplying, that could be different
214  *				than what the user specified.
215  *
216  * Returns:     0 for success, -1 for failure.
217  *
218  * References:	Multimedia Reference
219  *
220  *		http://msdn.microsoft.com/en-us/library/windows/desktop/dd743606%28v=vs.85%29.aspx
221  *
222  *----------------------------------------------------------------*/
223 
224 
225 static void CALLBACK in_callback (HWAVEIN handle, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2);
226 static void CALLBACK out_callback (HWAVEOUT handle, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2);
227 
audio_open(struct audio_s * pa)228 int audio_open (struct audio_s *pa)
229 {
230 	int a;
231 
232 	int err;
233 	int chan;
234 	int n;
235 	int in_dev_no[MAX_ADEVS];
236 	int out_dev_no[MAX_ADEVS];
237 
238 
239 	int num_devices;
240 	WAVEINCAPS wic;
241 	WAVEOUTCAPS woc;
242 
243 	save_audio_config_p = pa;
244 
245 
246     	for (a=0; a<MAX_ADEVS; a++) {
247       	  if (pa->adev[a].defined) {
248 
249             struct adev_s *A = &(adev[a]);
250 
251 	    assert (A->audio_in_handle == 0);
252 	    assert (A->audio_out_handle == 0);
253 
254 	    //text_color_set(DW_COLOR_DEBUG);
255 	    //dw_printf ("pa->adev[a].adevice_in = '%s'\n",  pa->adev[a].adevice_in);
256 	    //dw_printf ("pa->adev[a].adevice_out = '%s'\n", pa->adev[a].adevice_out);
257 
258 
259 /*
260  * Fill in defaults for any missing values.
261  */
262 	    if (pa -> adev[a].num_channels == 0)
263 	      pa -> adev[a].num_channels = DEFAULT_NUM_CHANNELS;
264 
265 	    if (pa -> adev[a].samples_per_sec == 0)
266 	      pa -> adev[a].samples_per_sec = DEFAULT_SAMPLES_PER_SEC;
267 
268 	    if (pa -> adev[a].bits_per_sample == 0)
269 	      pa -> adev[a].bits_per_sample = DEFAULT_BITS_PER_SAMPLE;
270 
271 	    A->g_audio_in_type = AUDIO_IN_TYPE_SOUNDCARD;
272 
273 	    for (chan=0; chan<MAX_CHANS; chan++) {
274 	      if (pa -> achan[chan].mark_freq == 0)
275 	        pa -> achan[chan].mark_freq = DEFAULT_MARK_FREQ;
276 
277 	      if (pa -> achan[chan].space_freq == 0)
278 	        pa -> achan[chan].space_freq = DEFAULT_SPACE_FREQ;
279 
280 	      if (pa -> achan[chan].baud == 0)
281 	        pa -> achan[chan].baud = DEFAULT_BAUD;
282 
283 	      if (pa->achan[chan].num_subchan == 0)
284 	        pa->achan[chan].num_subchan = 1;
285 	    }
286 
287 
288 	    A->udp_sock = INVALID_SOCKET;
289 
290 	    in_dev_no[a] = WAVE_MAPPER;	/* = ((UINT)-1) in mmsystem.h */
291 	    out_dev_no[a] = WAVE_MAPPER;
292 
293 /*
294  * Determine the type of audio input and select device.
295  * This can be soundcard, UDP stream, or stdin.
296  */
297 
298 	    if (strcasecmp(pa->adev[a].adevice_in, "stdin") == 0 || strcmp(pa->adev[a].adevice_in, "-") == 0) {
299 	      A->g_audio_in_type = AUDIO_IN_TYPE_STDIN;
300 	      /* Change - to stdin for readability. */
301 	      strlcpy (pa->adev[a].adevice_in, "stdin", sizeof(pa->adev[a].adevice_in));
302 	    }
303 	    else if (strncasecmp(pa->adev[a].adevice_in, "udp:", 4) == 0) {
304 	      A->g_audio_in_type = AUDIO_IN_TYPE_SDR_UDP;
305 	      /* Supply default port if none specified. */
306 	      if (strcasecmp(pa->adev[a].adevice_in,"udp") == 0 ||
307 	        strcasecmp(pa->adev[a].adevice_in,"udp:") == 0) {
308 	        snprintf (pa->adev[a].adevice_in, sizeof(pa->adev[a].adevice_in), "udp:%d", DEFAULT_UDP_AUDIO_PORT);
309 	      }
310 	    }
311 	    else {
312 	      A->g_audio_in_type = AUDIO_IN_TYPE_SOUNDCARD;
313 
314 	      /* Does config file have a number?  */
315 	      /* If so, it is an index into list of devices. */
316 	      /* Originally only a single digit was recognized.  */
317 	      /* v 1.5 also recognizes two digits.  (Issue 116) */
318 
319 	      if (strlen(pa->adev[a].adevice_in) == 1 && isdigit(pa->adev[a].adevice_in[0])) {
320 	        in_dev_no[a] = atoi(pa->adev[a].adevice_in);
321 	      }
322 	      else if (strlen(pa->adev[a].adevice_in) == 2 && isdigit(pa->adev[a].adevice_in[0]) && isdigit(pa->adev[a].adevice_in[1])) {
323 	        in_dev_no[a] = atoi(pa->adev[a].adevice_in);
324 	      }
325 
326 	      /* Otherwise, does it have search string? */
327 
328 	      if ((UINT)(in_dev_no[a]) == WAVE_MAPPER && strlen(pa->adev[a].adevice_in) >= 1) {
329 	        num_devices = waveInGetNumDevs();
330 	        for (n=0 ; n<num_devices && (UINT)(in_dev_no[a]) == WAVE_MAPPER ; n++) {
331 	          if ( ! waveInGetDevCaps(n, &wic, sizeof(WAVEINCAPS))) {
332 	            if (strstr(wic.szPname, pa->adev[a].adevice_in) != NULL) {
333 	              in_dev_no[a] = n;
334 	            }
335 	          }
336 	        }
337 	        if ((UINT)(in_dev_no[a]) == WAVE_MAPPER) {
338 	          text_color_set(DW_COLOR_ERROR);
339 	          dw_printf ("\"%s\" doesn't match any of the input devices.\n", pa->adev[a].adevice_in);
340 	        }
341 	      }
342  	    }
343 
344 /*
345  * Select output device.
346  * Only soundcard at this point.
347  * Purhaps we'd like to add UDP for an SDR transmitter.
348  */
349 	    if (strlen(pa->adev[a].adevice_out) == 1 && isdigit(pa->adev[a].adevice_out[0])) {
350 	      out_dev_no[a] = atoi(pa->adev[a].adevice_out);
351 	    }
352 	    else if (strlen(pa->adev[a].adevice_out) == 2 && isdigit(pa->adev[a].adevice_out[0]) && isdigit(pa->adev[a].adevice_out[1])) {
353 	      out_dev_no[a] = atoi(pa->adev[a].adevice_out);
354 	    }
355 
356 	    if ((UINT)(out_dev_no[a]) == WAVE_MAPPER && strlen(pa->adev[a].adevice_out) >= 1) {
357 	      num_devices = waveOutGetNumDevs();
358 	      for (n=0 ; n<num_devices && (UINT)(out_dev_no[a]) == WAVE_MAPPER ; n++) {
359 	        if ( ! waveOutGetDevCaps(n, &woc, sizeof(WAVEOUTCAPS))) {
360 	          if (strstr(woc.szPname, pa->adev[a].adevice_out) != NULL) {
361 	            out_dev_no[a] = n;
362 	          }
363 	        }
364 	      }
365 	      if ((UINT)(out_dev_no[a]) == WAVE_MAPPER) {
366 	        text_color_set(DW_COLOR_ERROR);
367 	        dw_printf ("\"%s\" doesn't match any of the output devices.\n", pa->adev[a].adevice_out);
368 	      }
369 	    }
370 	  }   /* if defined */
371 	}    /* for each device */
372 
373 
374 /*
375  * Display the input devices (soundcards) available and what is selected.
376  */
377 
378 	text_color_set(DW_COLOR_INFO);
379 	dw_printf ("Available audio input devices for receive (*=selected):\n");
380 
381 	num_devices = waveInGetNumDevs();
382 
383         for (a=0; a<MAX_ADEVS; a++) {
384           if (pa->adev[a].defined) {
385 
386 	    if (in_dev_no[a] < -1 || in_dev_no[a] >= num_devices) {
387 	      text_color_set(DW_COLOR_ERROR);
388 	      dw_printf ("Invalid input (receive) audio device number %d.\n", in_dev_no[a]);
389 	      in_dev_no[a] = WAVE_MAPPER;
390 	    }
391 	  }
392         }
393 
394 	text_color_set(DW_COLOR_INFO);
395 	for (n=0; n<num_devices; n++) {
396 
397 	  if ( ! waveInGetDevCaps(n, &wic, sizeof(WAVEINCAPS))) {
398 	    for (a=0; a<MAX_ADEVS; a++) {
399 	      if (pa->adev[a].defined) {
400 	        dw_printf (" %c", n==in_dev_no[a] ? '*' : ' ');
401 
402 	      }
403 	    }
404 	    dw_printf ("  %d: %s", n, wic.szPname);
405 
406 	    for (a=0; a<MAX_ADEVS; a++) {
407 	      if (pa->adev[a].defined && n==in_dev_no[a]) {
408 	        if (pa->adev[a].num_channels == 2) {
409 	          dw_printf ("   (channels %d & %d)", ADEVFIRSTCHAN(a), ADEVFIRSTCHAN(a)+1);
410 	        }
411 	        else {
412 	          dw_printf ("   (channel %d)", ADEVFIRSTCHAN(a));
413 	        }
414 	      }
415 	    }
416 	    dw_printf ("\n");
417  	  }
418     	}
419 
420 // Add UDP or stdin to end of device list if used.
421 
422     	for (a=0; a<MAX_ADEVS; a++) {
423       	  if (pa->adev[a].defined) {
424 
425             struct adev_s *A = &(adev[a]);
426 
427 	    /* Display stdin or udp:port if appropriate. */
428 
429 	    if (A->g_audio_in_type != AUDIO_IN_TYPE_SOUNDCARD) {
430 
431 	      int aaa;
432 	      for (aaa=0; aaa<MAX_ADEVS; aaa++) {
433 	        if (pa->adev[aaa].defined) {
434 	          dw_printf (" %c", a == aaa ? '*' : ' ');
435 
436 	        }
437 	      }
438 	      dw_printf ("  %s                             ", pa->adev[a].adevice_in);	/* should be UDP:nnnn or stdin */
439 
440 	      if (pa->adev[a].num_channels == 2) {
441 	        dw_printf ("   (channels %d & %d)", ADEVFIRSTCHAN(a), ADEVFIRSTCHAN(a)+1);
442 	      }
443 	      else {
444 	        dw_printf ("   (channel %d)", ADEVFIRSTCHAN(a));
445 	      }
446 	      dw_printf ("\n");
447 	    }
448       	  }
449      	}
450 
451 
452 /*
453  * Display the output devices (soundcards) available and what is selected.
454  */
455 
456 	dw_printf ("Available audio output devices for transmit (*=selected):\n");
457 
458 	/* TODO? */
459 	/* No "*" is currently displayed when using the default device. */
460 	/* Should we put "*" next to the default device when using it? */
461 	/* Which is the default?  The first one? */
462 
463 	num_devices = waveOutGetNumDevs();
464 
465         for (a=0; a<MAX_ADEVS; a++) {
466           if (pa->adev[a].defined) {
467 	    if (out_dev_no[a] < -1 || out_dev_no[a] >= num_devices) {
468 	      text_color_set(DW_COLOR_ERROR);
469 	      dw_printf ("Invalid output (transmit) audio device number %d.\n", out_dev_no[a]);
470 	      out_dev_no[a] = WAVE_MAPPER;
471 	    }
472 	  }
473 	}
474 
475 	text_color_set(DW_COLOR_INFO);
476 	for (n=0; n<num_devices; n++) {
477 
478 	  if ( ! waveOutGetDevCaps(n, &woc, sizeof(WAVEOUTCAPS))) {
479 	    for (a=0; a<MAX_ADEVS; a++) {
480 	      if (pa->adev[a].defined) {
481 	        dw_printf (" %c", n==out_dev_no[a] ? '*' : ' ');
482 
483 	      }
484 	    }
485 	    dw_printf ("  %d: %s", n, woc.szPname);
486 
487 	    for (a=0; a<MAX_ADEVS; a++) {
488 	      if (pa->adev[a].defined && n==out_dev_no[a]) {
489 	        if (pa->adev[a].num_channels == 2) {
490 	          dw_printf ("   (channels %d & %d)", ADEVFIRSTCHAN(a), ADEVFIRSTCHAN(a)+1);
491 	        }
492 	        else {
493 	          dw_printf ("   (channel %d)", ADEVFIRSTCHAN(a));
494 	        }
495 	      }
496 	    }
497 	    dw_printf ("\n");
498 	  }
499 	}
500 
501 
502 /*
503  * Open for each audio device input/output pair.
504  */
505 
506      	for (a=0; a<MAX_ADEVS; a++) {
507       	  if (pa->adev[a].defined) {
508 
509             struct adev_s *A = &(adev[a]);
510 
511 	     WAVEFORMATEX wf;
512 
513 	     wf.wFormatTag = WAVE_FORMAT_PCM;
514 	     wf.nChannels = pa -> adev[a].num_channels;
515 	     wf.nSamplesPerSec = pa -> adev[a].samples_per_sec;
516 	     wf.wBitsPerSample = pa -> adev[a].bits_per_sample;
517 	     wf.nBlockAlign = (wf.wBitsPerSample / 8) * wf.nChannels;
518 	     wf.nAvgBytesPerSec = wf.nBlockAlign * wf.nSamplesPerSec;
519 	     wf.cbSize = 0;
520 
521 	     A->outbuf_size = calcbufsize(wf.nSamplesPerSec,wf.nChannels,wf.wBitsPerSample);
522 
523 
524 /*
525  * Open the audio output device.
526  * Soundcard is only possibility at this time.
527  */
528 
529 	     err = waveOutOpen (&(A->audio_out_handle), out_dev_no[a], &wf, (DWORD_PTR)out_callback, a, CALLBACK_FUNCTION);
530 	     if (err != MMSYSERR_NOERROR) {
531 	       text_color_set(DW_COLOR_ERROR);
532 	       dw_printf ("Could not open audio device for output.\n");
533 	       return (-1);
534 	     }
535 
536 
537 /*
538  * Set up the output buffers.
539  * We use dwUser to indicate it is available for filling.
540  */
541 
542 	     memset ((void*)(A->out_wavehdr), 0, sizeof(A->out_wavehdr));
543 
544 	     for (n = 0; n < NUM_OUT_BUF; n++) {
545 	       A->out_wavehdr[n].lpData = malloc(A->outbuf_size);
546 	       A->out_wavehdr[n].dwUser = DWU_FILLING;
547 	       A->out_wavehdr[n].dwBufferLength = 0;
548 	     }
549 	     A->out_current = 0;
550 
551 
552 /*
553  * Open audio input device.
554  * More possibilities here:  soundcard, UDP port, stdin.
555  */
556 
557 	     switch (A->g_audio_in_type) {
558 
559 /*
560  * Soundcard.
561  */
562 	       case AUDIO_IN_TYPE_SOUNDCARD:
563 
564 	         InitializeCriticalSection (&(A->in_cs));
565 
566 	         err = waveInOpen (&(A->audio_in_handle), in_dev_no[a], &wf, (DWORD_PTR)in_callback, a, CALLBACK_FUNCTION);
567 	         if (err != MMSYSERR_NOERROR) {
568 	           text_color_set(DW_COLOR_ERROR);
569 	           dw_printf ("Could not open audio device for input.\n");
570 	           return (-1);
571 	         }
572 
573 
574 	         /*
575 	          * Set up the input buffers.
576 	          */
577 
578 	         memset ((void*)(A->in_wavehdr), 0, sizeof(A->in_wavehdr));
579 
580 	         for (n = 0; n < NUM_OUT_BUF; n++) {
581 	           A->in_wavehdr[n].dwBufferLength = A->outbuf_size;  /* all the same size */
582 	           A->in_wavehdr[n].lpData = malloc(A->outbuf_size);
583 	         }
584 	         A->in_headp = NULL;
585 
586 	         /*
587 	          * Give them to the sound input system.
588 	          */
589 
590 	         for (n = 0; n < NUM_OUT_BUF; n++) {
591 	           waveInPrepareHeader(A->audio_in_handle, &(A->in_wavehdr[n]), sizeof(WAVEHDR));
592 	           waveInAddBuffer(A->audio_in_handle, &(A->in_wavehdr[n]), sizeof(WAVEHDR));
593 	         }
594 
595 	         /*
596 	          * Start it up.
597 	          * The callback function is called when one is filled.
598 	          */
599 
600 	         waveInStart (A->audio_in_handle);
601 	         break;
602 
603 /*
604  * UDP.
605  */
606 	       case AUDIO_IN_TYPE_SDR_UDP:
607 
608 	         {
609 	           WSADATA wsadata;
610 	           struct sockaddr_in si_me;
611 	           //int slen=sizeof(si_me);
612 	           //int data_size = 0;
613 	           int err;
614 
615 	           err = WSAStartup (MAKEWORD(2,2), &wsadata);
616 	           if (err != 0) {
617 	               text_color_set(DW_COLOR_ERROR);
618 	               dw_printf("WSAStartup failed: %d\n", err);
619 	               return (-1);
620 	           }
621 
622 	           if (LOBYTE(wsadata.wVersion) != 2 || HIBYTE(wsadata.wVersion) != 2) {
623 	             text_color_set(DW_COLOR_ERROR);
624                      dw_printf("Could not find a usable version of Winsock.dll\n");
625                      WSACleanup();
626                      return (-1);
627 	           }
628 
629 	           // Create UDP Socket
630 
631 	           A->udp_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
632 	           if (A->udp_sock == INVALID_SOCKET) {
633 	             text_color_set(DW_COLOR_ERROR);
634 	             dw_printf ("Couldn't create socket, errno %d\n", WSAGetLastError());
635 	             return -1;
636 	           }
637 
638 	           memset((char *) &si_me, 0, sizeof(si_me));
639 	           si_me.sin_family = AF_INET;
640 	           si_me.sin_port = htons((short)atoi(pa->adev[a].adevice_in + 4));
641 	           si_me.sin_addr.s_addr = htonl(INADDR_ANY);
642 
643 	           // Bind to the socket
644 
645 	           if (bind(A->udp_sock, (SOCKADDR *) &si_me, sizeof(si_me)) != 0) {
646 	             text_color_set(DW_COLOR_ERROR);
647 	             dw_printf ("Couldn't bind socket, errno %d\n", WSAGetLastError());
648 	             return -1;
649 	           }
650 	           A->stream_next= 0;
651 	           A->stream_len = 0;
652 	         }
653 
654 	         break;
655 
656 /*
657  * stdin.
658  */
659    	       case AUDIO_IN_TYPE_STDIN:
660 
661   	         setmode (STDIN_FILENO, _O_BINARY);
662 	         A->stream_next= 0;
663 	         A->stream_len = 0;
664 
665 	         break;
666 
667 	       default:
668 
669 	         text_color_set(DW_COLOR_ERROR);
670 	         dw_printf ("Internal error, invalid audio_in_type\n");
671 	         return (-1);
672   	     }
673 
674 	  }
675     	}
676 
677 	return (0);
678 
679 } /* end audio_open */
680 
681 
682 
683 /*
684  * Called when input audio block is ready.
685  */
686 
in_callback(HWAVEIN handle,UINT msg,DWORD_PTR instance,DWORD_PTR param1,DWORD_PTR param2)687 static void CALLBACK in_callback (HWAVEIN handle, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
688 {
689 
690 	//dw_printf ("in_callback, handle = %p, msg = %d, instance = %I64d\n", handle, msg, instance);
691 
692 	int a = instance;
693 	assert (a >= 0 && a < MAX_ADEVS);
694 	struct adev_s *A = &(adev[a]);
695 
696 	if (msg == WIM_DATA) {
697 
698 	  WAVEHDR *p = (WAVEHDR*)param1;
699 
700 	  p->dwUser = 0x5a5a5a5a;	/* needs to be unprepared. */
701 					/* dwUser can be 32 or 64 bit unsigned int. */
702 	  p->lpNext = NULL;
703 
704 	  // dw_printf ("dwBytesRecorded = %ld\n", p->dwBytesRecorded);
705 
706 	  EnterCriticalSection (&(A->in_cs));
707 
708 	  if (A->in_headp == NULL) {
709 	    A->in_headp = p;		/* first one in list */
710 	  }
711 	  else {
712 	    WAVEHDR *last = (WAVEHDR*)(A->in_headp);
713 
714 	    while (last->lpNext != NULL) {
715 	      last = last->lpNext;
716 	    }
717 	    last->lpNext = p;		/* append to last one */
718 	  }
719 
720 	  LeaveCriticalSection (&(A->in_cs));
721 	}
722 }
723 
724 /*
725  * Called when output system is done with a block and it
726  * is again available for us to fill.
727  */
728 
729 
out_callback(HWAVEOUT handle,UINT msg,DWORD_PTR instance,DWORD_PTR param1,DWORD_PTR param2)730 static void CALLBACK out_callback (HWAVEOUT handle, UINT msg, DWORD_PTR instance, DWORD_PTR param1, DWORD_PTR param2)
731 {
732 	if (msg == WOM_DONE) {
733 
734 	  WAVEHDR *p = (WAVEHDR*)param1;
735 
736 	  p->dwBufferLength = 0;
737 	  p->dwUser = DWU_DONE;
738 	}
739 }
740 
741 
742 /*------------------------------------------------------------------
743  *
744  * Name:        audio_get
745  *
746  * Purpose:     Get one byte from the audio device.
747  *
748  *
749  * Inputs:	a	- Audio soundcard number.
750  *
751  * Returns:     0 - 255 for a valid sample.
752  *              -1 for any type of error.
753  *
754  * Description:	The caller must deal with the details of mono/stereo
755  *		and number of bytes per sample.
756  *
757  *		This will wait if no data is currently available.
758  *
759  *----------------------------------------------------------------*/
760 
761 // Use hot attribute for all functions called for every audio sample.
762 
763 __attribute__((hot))
audio_get(int a)764 int audio_get (int a)
765 {
766 	struct adev_s *A;
767 
768 	WAVEHDR *p;
769 	int n;
770 	int sample;
771 
772         A = &(adev[a]);
773 
774 	switch (A->g_audio_in_type) {
775 
776 /*
777  * Soundcard.
778  */
779 	  case AUDIO_IN_TYPE_SOUNDCARD:
780 
781 	    while (1) {
782 
783 	      /*
784 	       * Wait if nothing available.
785 	       * Could use an event to wake up but this is adequate.
786 	       */
787 	      int timeout = 25;
788 
789 	      while (A->in_headp == NULL) {
790 	        //SLEEP_MS (ONE_BUF_TIME / 5);
791 	        SLEEP_MS (ONE_BUF_TIME);
792 	        timeout--;
793 	        if (timeout <= 0) {
794 	          text_color_set(DW_COLOR_ERROR);
795 
796 // TODO1.2: Need more details.  Can we keep going?
797 
798 	          dw_printf ("Timeout waiting for input from audio device %d.\n", a);
799 
800 	          audio_stats (a,
801 			save_audio_config_p->adev[a].num_channels,
802 			0,
803 			save_audio_config_p->statistics_interval);
804 
805 	          return (-1);
806 	        }
807 	      }
808 
809 	      p = (WAVEHDR*)(A->in_headp);		/* no need to be volatile at this point */
810 
811 	      if (p->dwUser == 0x5a5a5a5a) {		// dwUser can be 32 or bit unsigned.
812 	        waveInUnprepareHeader(A->audio_in_handle, p, sizeof(WAVEHDR));
813 	        p->dwUser = 0;	/* Index for next byte. */
814 
815 	        audio_stats (a,
816 			save_audio_config_p->adev[a].num_channels,
817 			p->dwBytesRecorded / (save_audio_config_p->adev[a].num_channels * save_audio_config_p->adev[a].bits_per_sample / 8),
818 			save_audio_config_p->statistics_interval);
819 	      }
820 
821 	      if (p->dwUser < p->dwBytesRecorded) {
822 	        n = ((unsigned char*)(p->lpData))[p->dwUser++];
823 #if DEBUGx
824 
825 	        text_color_set(DW_COLOR_DEBUG);
826 	        dw_printf ("audio_get(): returns %d\n", n);
827 
828 #endif
829 	        return (n);
830 	      }
831 	      /*
832 	       * Buffer is all used up.  Give it back to sound input system.
833 	       */
834 
835 	      EnterCriticalSection (&(A->in_cs));
836 	      A->in_headp = p->lpNext;
837 	      LeaveCriticalSection (&(A->in_cs));
838 
839 	      p->dwFlags = 0;
840 	      waveInPrepareHeader(A->audio_in_handle, p, sizeof(WAVEHDR));
841 	      waveInAddBuffer(A->audio_in_handle, p, sizeof(WAVEHDR));
842 	    }
843 	    break;
844 /*
845  * UDP.
846  */
847 	  case AUDIO_IN_TYPE_SDR_UDP:
848 
849 	    while (A->stream_next >= A->stream_len) {
850 	      int res;
851 
852               assert (A->udp_sock > 0);
853 
854 	      res = SOCK_RECV (A->udp_sock, A->stream_data, SDR_UDP_BUF_MAXLEN);
855 	      if (res <= 0) {
856 	        text_color_set(DW_COLOR_ERROR);
857 	        dw_printf ("Can't read from udp socket, errno %d", WSAGetLastError());
858 	        A->stream_len = 0;
859 	        A->stream_next = 0;
860 
861 	        audio_stats (a,
862 			save_audio_config_p->adev[a].num_channels,
863 			0,
864 			save_audio_config_p->statistics_interval);
865 
866 	        return (-1);
867 	      }
868 
869 	      audio_stats (a,
870 			save_audio_config_p->adev[a].num_channels,
871 			res / (save_audio_config_p->adev[a].num_channels * save_audio_config_p->adev[a].bits_per_sample / 8),
872 			save_audio_config_p->statistics_interval);
873 
874 	      A->stream_len = res;
875 	      A->stream_next = 0;
876 	    }
877 	    sample = A->stream_data[A->stream_next] & 0xff;
878 	    A->stream_next++;
879 	    return (sample);
880 	    break;
881 /*
882  * stdin.
883  */
884    	  case AUDIO_IN_TYPE_STDIN:
885 
886 	    while (A->stream_next >= A->stream_len) {
887 	      int res;
888 
889 	      res = read(STDIN_FILENO, A->stream_data, 1024);
890 	      if (res <= 0) {
891 	        text_color_set(DW_COLOR_INFO);
892 	        dw_printf ("\nEnd of file on stdin.  Exiting.\n");
893 	        exit (0);
894 	      }
895 
896 	      audio_stats (a,
897 			save_audio_config_p->adev[a].num_channels,
898 			res / (save_audio_config_p->adev[a].num_channels * save_audio_config_p->adev[a].bits_per_sample / 8),
899 			save_audio_config_p->statistics_interval);
900 
901 	      A->stream_len = res;
902 	      A->stream_next = 0;
903 	    }
904 	    return (A->stream_data[A->stream_next++] & 0xff);
905 	    break;
906   	}
907 
908 	return (-1);
909 
910 } /* end audio_get */
911 
912 
913 /*------------------------------------------------------------------
914  *
915  * Name:        audio_put
916  *
917  * Purpose:     Send one byte to the audio device.
918  *
919  * Inputs:	a	- Index for audio device.
920  *
921  *		c	- One byte in range of 0 - 255.
922  *
923  *
924  * Global In:	out_current	- index of output buffer currenly being filled.
925  *
926  * Returns:     Normally non-negative.
927  *              -1 for any type of error.
928  *
929  * Description:	The caller must deal with the details of mono/stereo
930  *		and number of bytes per sample.
931  *
932  * See Also:	audio_flush
933  *		audio_wait
934  *
935  *----------------------------------------------------------------*/
936 
audio_put(int a,int c)937 int audio_put (int a, int c)
938 {
939 	WAVEHDR *p;
940 
941 	struct adev_s *A;
942 	A = &(adev[a]);
943 
944 /*
945  * Wait if no buffers are available.
946  * Don't use p yet because compiler might might consider dwFlags a loop invariant.
947  */
948 
949 	int timeout = 10;
950 	while ( A->out_wavehdr[A->out_current].dwUser == DWU_PLAYING) {
951 	  SLEEP_MS (ONE_BUF_TIME);
952 	  timeout--;
953 	  if (timeout <= 0) {
954 	    text_color_set(DW_COLOR_ERROR);
955 
956 // TODO: open issues 78 & 165.  How can we avoid/improve this?
957 
958 	    dw_printf ("Audio output failure waiting for buffer.\n");
959 	    dw_printf ("This can occur when we are producing audio output for\n");
960 	    dw_printf ("transmit and the operating system doesn't provide buffer\n");
961 	    dw_printf ("space after waiting and retrying many times.\n");
962 	    //dw_printf ("In recent years, this has been reported only when running the\n");
963 	    //dw_printf ("Windows version with VMWare on a Macintosh.\n");
964 	    ptt_term ();
965 	    return (-1);
966 	  }
967 	}
968 
969 	p = (LPWAVEHDR)(&(A->out_wavehdr[A->out_current]));
970 
971 	if (p->dwUser == DWU_DONE) {
972 	  waveOutUnprepareHeader (A->audio_out_handle, p, sizeof(WAVEHDR));
973 	  p->dwBufferLength = 0;
974 	  p->dwUser = DWU_FILLING;
975 	}
976 
977 	/* Should never be full at this point. */
978 
979 	assert (p->dwBufferLength >= 0);
980 	assert (p->dwBufferLength < (DWORD)(A->outbuf_size));
981 
982 	p->lpData[p->dwBufferLength++] = c;
983 
984 	if (p->dwBufferLength == (DWORD)(A->outbuf_size)) {
985 	  return (audio_flush(a));
986 	}
987 
988 	return (0);
989 
990 } /* end audio_put */
991 
992 
993 /*------------------------------------------------------------------
994  *
995  * Name:        audio_flush
996  *
997  * Purpose:     Send current buffer to the audio output system.
998  *
999  * Inputs:	a	- Index for audio device.
1000  *
1001  * Returns:     Normally non-negative.
1002  *              -1 for any type of error.
1003  *
1004  * See Also:	audio_flush
1005  *		audio_wait
1006  *
1007  *----------------------------------------------------------------*/
1008 
audio_flush(int a)1009 int audio_flush (int a)
1010 {
1011 	WAVEHDR *p;
1012 	MMRESULT e;
1013 	struct adev_s *A;
1014 
1015 	A = &(adev[a]);
1016 
1017 	p = (LPWAVEHDR)(&(A->out_wavehdr[A->out_current]));
1018 
1019 	if (p->dwUser == DWU_FILLING && p->dwBufferLength > 0) {
1020 
1021 	  p->dwUser = DWU_PLAYING;
1022 
1023 	  waveOutPrepareHeader(A->audio_out_handle, p, sizeof(WAVEHDR));
1024 
1025 	  e = waveOutWrite(A->audio_out_handle, p, sizeof(WAVEHDR));
1026 	  if (e != MMSYSERR_NOERROR) {
1027 	    text_color_set (DW_COLOR_ERROR);
1028 	    dw_printf ("audio out write error %d\n", e);
1029 
1030 	    /* I don't expect this to ever happen but if it */
1031 	    /* does, make the buffer available for filling. */
1032 
1033 	    p->dwUser = DWU_DONE;
1034 	    return (-1);
1035 	  }
1036 	  A->out_current = (A->out_current + 1) % NUM_OUT_BUF;
1037 	}
1038 	return (0);
1039 
1040 } /* end audio_flush */
1041 
1042 
1043 /*------------------------------------------------------------------
1044  *
1045  * Name:        audio_wait
1046  *
1047  * Purpose:	Finish up audio output before turning PTT off.
1048  *
1049  * Inputs:	a		- Index for audio device (not channel!)
1050  *
1051  * Returns:     None.
1052  *
1053  * Description:	Flush out any partially filled audio output buffer.
1054  *		Wait until all the queued up audio out has been played.
1055  *		Take any other necessary actions to stop audio output.
1056  *
1057  * In an ideal world:
1058  *
1059  *		We would like to ask the hardware when all the queued
1060  *		up sound has actually come out the speaker.
1061  *
1062  * In reality:
1063  *
1064  * 		This has been found to be less than reliable in practice.
1065  *
1066  *		Caller does the following:
1067  *
1068  *		(1) Make note of when PTT is turned on.
1069  *		(2) Calculate how long it will take to transmit the
1070  *			frame including TXDELAY, frame (including
1071  *			"flags", data, FCS and bit stuffing), and TXTAIL.
1072  *		(3) Call this function, which might or might not wait long enough.
1073  *		(4) Add (1) and (2) resulting in when PTT should be turned off.
1074  *		(5) Take difference between current time and desired PPT off time
1075  *			and wait for additoinal time if required.
1076  *
1077  *----------------------------------------------------------------*/
1078 
audio_wait(int a)1079 void audio_wait (int a)
1080 {
1081 
1082 	audio_flush (a);
1083 
1084 } /* end audio_wait */
1085 
1086 
1087 /*------------------------------------------------------------------
1088  *
1089  * Name:        audio_close
1090  *
1091  *
1092  * Purpose:     Close all of the audio devices.
1093  *
1094  * Returns:     Normally non-negative.
1095  *              -1 for any type of error.
1096  *
1097  *
1098  *----------------------------------------------------------------*/
1099 
audio_close(void)1100 int audio_close (void)
1101 {
1102 	int err = 0;
1103 
1104 	int n;
1105 
1106 	int a;
1107 
1108     	for (a=0; a<MAX_ADEVS; a++) {
1109       	  if (save_audio_config_p->adev[a].defined) {
1110 
1111             struct adev_s *A = &(adev[a]);
1112 
1113 	    assert (A->audio_in_handle != 0);
1114 	    assert (A->audio_out_handle != 0);
1115 
1116 	    audio_wait (a);
1117 
1118 /* Shutdown audio input. */
1119 
1120 	    waveInReset(A->audio_in_handle);
1121 	    waveInStop(A->audio_in_handle);
1122 	    waveInClose(A->audio_in_handle);
1123 	    A->audio_in_handle = 0;
1124 
1125 	    for (n = 0; n < NUM_IN_BUF; n++) {
1126 
1127 	      waveInUnprepareHeader (A->audio_in_handle, (LPWAVEHDR)(&(A->in_wavehdr[n])), sizeof(WAVEHDR));
1128 	      A->in_wavehdr[n].dwFlags = 0;
1129 	      free (A->in_wavehdr[n].lpData);
1130  	      A->in_wavehdr[n].lpData = NULL;
1131 	    }
1132 
1133 	    DeleteCriticalSection (&(A->in_cs));
1134 
1135 
1136 /* Make sure all output buffers have been played then free them. */
1137 
1138 	    for (n = 0; n < NUM_OUT_BUF; n++) {
1139 	      if (A->out_wavehdr[n].dwUser == DWU_PLAYING) {
1140 
1141 	        int timeout = 2 * NUM_OUT_BUF;
1142 	        while (A->out_wavehdr[n].dwUser == DWU_PLAYING) {
1143 	          SLEEP_MS (ONE_BUF_TIME);
1144 	          timeout--;
1145 	          if (timeout <= 0) {
1146 	            text_color_set(DW_COLOR_ERROR);
1147 	            dw_printf ("Audio output failure on close.\n");
1148 	          }
1149 	        }
1150 
1151 	        waveOutUnprepareHeader (A->audio_out_handle, (LPWAVEHDR)(&(A->out_wavehdr[n])), sizeof(WAVEHDR));
1152 
1153 	        A->out_wavehdr[n].dwUser = DWU_DONE;
1154 	      }
1155 	      free (A->out_wavehdr[n].lpData);
1156  	      A->out_wavehdr[n].lpData = NULL;
1157 	    }
1158 
1159 	    waveOutClose (A->audio_out_handle);
1160 	    A->audio_out_handle = 0;
1161 
1162           }  /* if device configured */
1163         }  /* for each device. */
1164 
1165         /* Not right.  always returns 0 but at this point, doesn't matter. */
1166 
1167 	return (err);
1168 
1169 } /* end audio_close */
1170 
1171 /* end audio_win.c */
1172 
1173