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