1 /*
2 Small library for reading and writing audio.
3
4 This library forks an audio task and communicates with it
5 via a shared memory segment.
6
7 All what this library does can be done in principal
8 with ordinary read/write calls on the sound device.
9
10 The Linux audio driver uses so small buffers, however,
11 that overruns/underruns are unavoidable in many cases.
12
13 Copyright (C) 2000 Rainer Johanni <Rainer@Johanni.de>
14
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30 #ifdef HAVE_CONFIG_H
31 #include "../config.h"
32 #endif
33
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <fcntl.h>
37 #include <unistd.h>
38 #include <signal.h>
39 #include <string.h>
40 #include <errno.h>
41
42 #ifdef HAVE_SYS_SOUNDCARD_H
43 #include <sys/soundcard.h>
44 #endif
45
46 #include <sys/time.h>
47 #include <sys/resource.h>
48 #include <sys/mman.h>
49 #include <sys/types.h>
50 #include <sys/wait.h>
51 #include <sys/ioctl.h>
52
53 /* The shared memory things */
54
55 #include <sys/ipc.h>
56 #include <sys/shm.h>
57
58 #ifndef FORK_NOT_THREAD
59 #include <pthread.h>
60 #endif
61
62 #include "mjpeg_logging.h"
63
64 #include "audiolib.h"
65
66
67 #ifdef FORK_NOT_THREAD
68 static int pid; /* pid of child */
69 static int shm_seg;
70 #else
71 static pthread_t capture_thread;
72 #endif
73 #define TIME_STAMP_TOL 100000 /* tolerance for timestamps in us */
74
75 #define N_SHM_BUFFS 256 /* Number of buffers, must be a power of 2 */
76 #define SHM_BUFF_MASK (N_SHM_BUFFS-1)
77 /* #define BUFFSIZE (8192) */
78 /* A.Stevens Jul 2000: Several drivers for modern PCI cards can't deliver
79 frags larger than 4096 so lets not even try for 8192 byte buffer chunks
80 */
81 #define BUFFSIZE (4096)
82 #define NBUF(x) ((x)&SHM_BUFF_MASK)
83
84 struct shm_buff_s
85 {
86 volatile uint8_t audio_data[N_SHM_BUFFS][BUFFSIZE];
87 volatile int used_flag[N_SHM_BUFFS];
88 volatile struct timeval tmstmp[N_SHM_BUFFS];
89 volatile int status[N_SHM_BUFFS];
90 volatile int exit_flag; /* set by parent */
91 volatile int audio_status; /* set by audio task */
92 volatile int audio_start; /* trigger start in playing */
93 volatile char error_string[4096];
94 } *shmemptr;
95
96 static int audio_buffer_size = BUFFSIZE; /* The buffer size actually used */
97
98 /* The parameters for audio capture/playback */
99
100 static int initialized=0;
101 static int audio_capt; /* Flag for capture/playback */
102 static int mmap_io; /* Flag for using either mmap or read,write */
103 static int stereo; /* 0: capture mono, 1: capture stereo */
104 static int audio_size; /* size of an audio sample: 8 or 16 bits */
105 static int audio_rate; /* sampling rate for audio */
106 static int audio_byte_rate; /* sampling rate for audio Bps*/
107
108 /* Buffer counter */
109
110 static int n_audio;
111
112 /* Bookkeeping of the write buffers */
113
114 static char audio_left_buf[BUFFSIZE];
115 static int audio_bytes_left; /* Number of bytes in audio_left_buf */
116 static unsigned int n_buffs_output, n_buffs_error;
117 static struct timeval buffer_timestamp;
118 static int usecs_per_buff;
119
120 /* Forward declarations: */
121
122 void do_audio(void);
123 char *audio_strerror(void);
124 void set_timestamp(struct timeval tmstmp);
125 void swpcpy(char *dst, char *src, int num);
126
127
128 typedef void *(*start_routine_p)(void *);
129
130
131 /* some (internally used only) error numbers */
132
133 static int audio_errno = 0;
134
135 #define AUDIO_ERR_INIT 1 /* Not initialized */
136 #define AUDIO_ERR_INIT2 2 /* allready initialized */
137 #define AUDIO_ERR_ASIZE 3 /* audio size not 8 or 16 */
138 #define AUDIO_ERR_SHMEM 4 /* Error getting shared memory segment */
139 #define AUDIO_ERR_FORK 5 /* Can not fork audio task */
140 #define AUDIO_ERR_MODE 6 /* Wrong read/write mode */
141 #define AUDIO_ERR_BSIZE 7 /* Buffer size for read too small */
142 #define AUDIO_ERR_TMOUT 8 /* Timeout waiting for audio */
143 #define AUDIO_ERR_BOVFL 9 /* Buffer overflow when writing */
144 #define AUDIO_ERR_ATASK 99 /* Audio task died - more in shmemptr->error_string */
145
146 static char errstr[4096];
147
audio_strerror(void)148 char *audio_strerror(void)
149 {
150 switch(audio_errno)
151 {
152 case 0:
153 strcpy(errstr,"No Error");
154 break;
155 case AUDIO_ERR_INIT:
156 strcpy(errstr,"Audio not initialized");
157 break;
158 case AUDIO_ERR_INIT2:
159 strcpy(errstr,"audio_init called but audio allready initialized");
160 break;
161 case AUDIO_ERR_ASIZE:
162 strcpy(errstr,"audio sample size not 8 or 16");
163 break;
164 case AUDIO_ERR_SHMEM:
165 strcpy(errstr,"Audio: Error getting shared memory segment");
166 break;
167 case AUDIO_ERR_FORK:
168 strcpy(errstr,"Can not fork audio task");
169 break;
170 case AUDIO_ERR_MODE:
171 strcpy(errstr,"Audio: Wrong read/write mode");
172 break;
173 case AUDIO_ERR_BSIZE:
174 strcpy(errstr,"Audio: Buffer size for read too small");
175 break;
176 case AUDIO_ERR_TMOUT:
177 strcpy(errstr,"Timeout waiting for audio initialization");
178 break;
179 case AUDIO_ERR_BOVFL:
180 strcpy(errstr,"Buffer overflow writing audio");
181 break;
182 case AUDIO_ERR_ATASK:
183 sprintf(errstr,"Audio task died. Reason: %s",shmemptr->error_string);
184 break;
185 default:
186 strcpy(errstr,"Audio: Unknown error");
187 }
188 return errstr;
189 }
190
191 /*
192 * audio_init: Initialize audio system.
193 *
194 * a_read 0: User is going to write (output) audio
195 * 1: User is going to read (input) audio
196 * use_read_write 0: use mmap io as opposed to
197 * 1: read/write system calls
198 * a_stereo 0: mono, 1: stereo
199 * a_size size of an audio sample: 8 or 16 bits
200 * a_rate sampling rate for audio
201 *
202 * returns 0 for success, -1 for failure
203 *
204 */
205
audio_init(int a_read,int use_read_write,int a_stereo,int a_size,int a_rate)206 int audio_init(int a_read, int use_read_write,
207 int a_stereo, int a_size, int a_rate)
208 {
209 int i;
210
211 /* Check if the audio task is allready initialized */
212
213 if(initialized) { audio_errno = AUDIO_ERR_INIT2; return -1; }
214
215 /* Checks of parameters */
216
217 if (a_size != 8 && a_size != 16) { audio_errno = AUDIO_ERR_ASIZE; return -1; }
218
219 if( use_read_write )
220 mjpeg_info( "Using read(2)/write(2) system call for capture/playpack");
221 else
222 mjpeg_info( "Using mmap(2) system call for capture/playback");
223 /* Copy our parameters into static space */
224
225 audio_capt = a_read;
226 mmap_io = !use_read_write;
227 stereo = a_stereo;
228 audio_size = a_size;
229 audio_rate = a_rate;
230
231 /* Reset counters */
232
233 n_audio = 0;
234 audio_bytes_left = 0;
235 n_buffs_output = 0;
236 n_buffs_error = 0;
237 buffer_timestamp.tv_sec = 0;
238 buffer_timestamp.tv_usec = 0;
239
240 /*
241 * Calculate bytes/second of the audio stream
242 */
243
244 audio_byte_rate = audio_rate;
245 if (stereo) audio_byte_rate *= 2;
246 if (audio_size==16) audio_byte_rate *= 2;
247
248 /* Set audio buffer size */
249
250 audio_buffer_size = BUFFSIZE;
251 /* A.Stevens Jul 2000 modified to allow cards with max frag size of
252 4096.... if(tmp<88200) audio_buffer_size = 4096; */
253 if(audio_byte_rate<44100) audio_buffer_size = BUFFSIZE/2;
254 if(audio_byte_rate<22050) audio_buffer_size = BUFFSIZE/4;
255
256 /* Do not change the following calculations,
257 they are this way to avoid overflows ! */
258 usecs_per_buff = audio_buffer_size*100000/audio_byte_rate;
259 usecs_per_buff *= 10;
260
261 #ifdef FORK_NOT_THREAD
262 /* Allocate shared memory segment */
263
264 shm_seg = shmget(IPC_PRIVATE, sizeof(struct shm_buff_s), IPC_CREAT | 0777);
265 if(shm_seg < 0) { audio_errno = AUDIO_ERR_SHMEM; return -1; }
266
267 /* attach the segment and get its address */
268
269 shmemptr = (struct shm_buff_s *) shmat(shm_seg,0,0);
270 if(shmemptr < 0) { audio_errno = AUDIO_ERR_SHMEM; return -1; }
271
272 /* mark the segment as destroyed, it will be removed after
273 the last process which had attached it is gone */
274
275 if( shmctl( shm_seg, IPC_RMID, (struct shmid_ds *)0 ) == -1 )
276 {
277 audio_errno = AUDIO_ERR_SHMEM;
278 return -1;
279 }
280 #else
281 shmemptr = (struct shm_buff_s *) malloc(sizeof(struct shm_buff_s));
282 if( shmemptr == NULL )
283 { audio_errno = AUDIO_ERR_SHMEM; return -1; }
284 #endif
285 /* set the flags in the shared memory */
286
287 for(i=0;i<N_SHM_BUFFS;i++) shmemptr->used_flag[i] = 0;
288 for(i=0;i<N_SHM_BUFFS;i++) shmemptr->status[i] = 0;
289 shmemptr->exit_flag = 0;
290 shmemptr->audio_status = 0;
291 shmemptr->audio_start = 0;
292
293 /* do the fork */
294
295 #ifdef FORK_NOT_THREAD
296 pid = fork();
297 if(pid<0)
298 {
299 audio_errno = AUDIO_ERR_FORK;
300 return -1;
301 }
302
303 /* the child goes into the audio task */
304
305 if (pid==0)
306 {
307 /* The audio buffers in Linux are ridiculosly small,
308 therefore the audio task must have a high priority,
309 This call will fail if we are not superuser, we don't care.
310 */
311
312 setpriority(PRIO_PROCESS, getpid(), -20);
313
314 /* Ignore SIGINT while capturing, the parent wants to catch it */
315
316 if(audio_capt) signal(SIGINT,SIG_IGN);
317 do_audio();
318 exit(0);
319 }
320 #else
321
322 if( pthread_create( &capture_thread, NULL, (start_routine_p)do_audio, NULL) )
323 {
324 audio_errno = AUDIO_ERR_FORK;
325 return -1;
326 }
327
328 #endif
329 /* Since most probably errors happen during initialization,
330 we wait until the audio task signals either success or failure */
331
332 for(i=0;;i++)
333 {
334 /* Check for timeout, 10 Seconds should be plenty */
335 if(i>1000)
336 {
337 #ifdef FORK_NOT_THREAD
338 kill(pid,SIGKILL);
339 shmemptr->exit_flag = 1;
340 waitpid(pid,0,0);
341 #else
342 shmemptr->exit_flag = 1;
343 pthread_cancel( capture_thread );
344 pthread_join( capture_thread, NULL );
345 #endif
346 audio_errno = AUDIO_ERR_TMOUT;
347 return -1;
348 }
349 if(shmemptr->audio_status<0)
350 {
351 audio_errno = AUDIO_ERR_ATASK;
352 return -1;
353 }
354 if(shmemptr->audio_status>0) break;
355 usleep(10000);
356 }
357
358 initialized = 1;
359 return 0;
360 }
361
362 /*
363 * audio_shutdown: Shutdown audio system
364 *
365 * It is important that this routine is called whenever the host
366 * program finished, or else there will be the audio task
367 * left over, having the sound device still opened and preventing
368 * other programs from using sound.
369 *
370 */
371
audio_shutdown(void)372 void audio_shutdown(void)
373 {
374 if(!initialized) return;
375
376 /* show the child we want to exit */
377
378 shmemptr->exit_flag = 1;
379 #ifdef FORK_NOT_THREAD
380 waitpid(pid,0,0);
381 #else
382 pthread_join( capture_thread, NULL );
383 #endif
384
385 initialized = 0;
386 }
387
audio_get_buffer_size(void)388 long audio_get_buffer_size(void)
389 {
390 return audio_buffer_size;
391 }
392
393 /*
394 * audio_start: Actually trigger the start of audio after all
395 * initializations have been done.
396 * Only for playing!
397 *
398 * returns 0 for success, -1 for failure
399 */
400
audio_start(void)401 void audio_start(void)
402 {
403 /* signal the audio task that we want to start */
404
405 shmemptr->audio_start = 1;
406 }
407
408 /*
409 * set_timestamp:
410 * Set buffer timestamp either to the value of the tmstmp parameter
411 * or calculate it from previous value
412 */
413
414 void
set_timestamp(struct timeval tmstmp)415 set_timestamp(struct timeval tmstmp)
416 {
417 if( tmstmp.tv_sec != 0 )
418 {
419 /* Time stamp is realiable */
420 buffer_timestamp = tmstmp;
421 }
422 else
423 {
424 /* Time stamp not reliable - calculate from previous */
425 if(buffer_timestamp.tv_sec != 0)
426 {
427 buffer_timestamp.tv_usec += usecs_per_buff;
428 while(buffer_timestamp.tv_usec>=1000000)
429 {
430 buffer_timestamp.tv_usec -= 1000000;
431 buffer_timestamp.tv_sec += 1;
432 }
433 }
434 }
435 }
436
437
438 /*
439 * swpcpy: like memcpy, but bytes are swapped during copy
440 */
441
swpcpy(char * dst,char * src,int num)442 void swpcpy(char *dst, char *src, int num)
443 {
444 int i;
445
446 num &= ~1; /* Safety first */
447
448 for(i=0;i<num;i+=2)
449 {
450 dst[i ] = src[i+1];
451 dst[i+1] = src[i ];
452 }
453 }
454
455 /*
456 * audio_read: Get audio data, if available
457 * Behaves like a nonblocking read
458 *
459 * buf Buffer where to copy the data
460 * size Size of the buffer
461 * swap Flag if to swap the endian-ness of 16 bit data
462 * tmstmp returned: timestamp when buffer was finished reading
463 * contains 0 if time could not be reliably determined
464 * status returned: 0 if buffer is corrupted
465 * 1 if buffer is ok.
466 * tmstmp and status are set only if something was read
467 *
468 * returns the number of bytes in the buffer,
469 * 0 if nothing available
470 * -1 if an error occured
471 *
472 */
473
audio_read(uint8_t * buf,int size,int swap,struct timeval * tmstmp,int * status)474 int audio_read( uint8_t *buf, int size, int swap,
475 struct timeval *tmstmp, int *status)
476 {
477 if(!initialized) { audio_errno = AUDIO_ERR_INIT; return -1; }
478
479 /* Is audio task still ok ? */
480
481 if(shmemptr->audio_status < 0) { audio_errno = AUDIO_ERR_ATASK; return -1; }
482
483 if(!audio_capt) { audio_errno = AUDIO_ERR_MODE; return -1; }
484
485 if(size<audio_buffer_size) { audio_errno = AUDIO_ERR_BSIZE; return -1; }
486
487 /* Check if a new audio sample is ready */
488
489 if(shmemptr->used_flag[NBUF(n_audio)])
490 {
491 /* Got an audio sample, copy it to the output buffer */
492
493 if(swap && audio_size==16)
494 swpcpy((void*)buf,(void*)shmemptr->audio_data[NBUF(n_audio)],audio_buffer_size);
495 else
496 memcpy((void*)buf,(void*)shmemptr->audio_data[NBUF(n_audio)],audio_buffer_size);
497
498 /* set the other return values */
499
500 set_timestamp(shmemptr->tmstmp[NBUF(n_audio)]);
501 if(tmstmp) *tmstmp = buffer_timestamp;
502 if(status) *status = shmemptr->status[NBUF(n_audio)] > 0;
503
504 /* reset used_flag, increment n-audio */
505
506 shmemptr->status[NBUF(n_audio)] = 0;
507 shmemptr->used_flag[NBUF(n_audio)] = 0;
508 n_audio++;
509 return audio_buffer_size;
510 }
511
512 return 0;
513 }
514
update_output_status(void)515 static void update_output_status(void)
516 {
517 while(shmemptr->status[NBUF(n_buffs_output)])
518 {
519 if(shmemptr->status[NBUF(n_buffs_output)] < 0) n_buffs_error++;
520 set_timestamp(shmemptr->tmstmp[NBUF(n_buffs_output)]);
521 shmemptr->status[NBUF(n_buffs_output)] = 0;
522 n_buffs_output++;
523 }
524 }
525
audio_get_output_status(struct timeval * tmstmp,unsigned int * nb_out,unsigned int * nb_err)526 void audio_get_output_status(struct timeval *tmstmp, unsigned int *nb_out, unsigned int *nb_err)
527 {
528 if(tmstmp) *tmstmp = buffer_timestamp;
529 if(nb_out) *nb_out = n_buffs_output;
530 if(nb_err) *nb_err = n_buffs_error;
531 }
532
533
534 /*
535 * audio_write: Buffer audio data for output
536 * Behaves like a nonblocking write
537 *
538 * buf Buffer with audio data
539 * size Size of the buffer
540 * swap Flag if to swap the endian-ness of 16 bit data
541 *
542 * returns the number of bytes actually written
543 * -1 if an error occured
544 *
545 * If the number of bytes actually written is smaller
546 * than size, the audio ringbuffer is completely filled
547 *
548 */
549
audio_write(uint8_t * buf,int size,int swap)550 int audio_write(uint8_t *buf, int size, int swap)
551 {
552 int nb;
553
554 if(!initialized) { audio_errno = AUDIO_ERR_INIT; return -1; }
555
556 /* Is audio task still ok ? */
557
558 if(shmemptr->audio_status < 0) { audio_errno = AUDIO_ERR_ATASK; return -1; }
559
560 if(audio_capt) { audio_errno = AUDIO_ERR_MODE; return -1; }
561
562 update_output_status();
563
564 /* If the number of bytes we got isn't big enough to fill
565 the next buffer, copy buf into audio_left_buf */
566
567 if (audio_bytes_left+size < audio_buffer_size)
568 {
569 memcpy(audio_left_buf+audio_bytes_left,buf,size);
570 audio_bytes_left += size;
571 return size;
572 }
573
574 nb = 0;
575
576 /* if audio_left_buf contains something, output that first */
577
578 if (audio_bytes_left)
579 {
580 memcpy(audio_left_buf+audio_bytes_left,buf,audio_buffer_size-audio_bytes_left);
581
582 if(shmemptr->used_flag[NBUF(n_audio)])
583 {
584 audio_errno = AUDIO_ERR_BOVFL;
585 return -1;
586 }
587
588 if(swap && audio_size==16)
589 swpcpy((void*)shmemptr->audio_data[NBUF(n_audio)],audio_left_buf,audio_buffer_size);
590 else
591 memcpy((void*)shmemptr->audio_data[NBUF(n_audio)],audio_left_buf,audio_buffer_size);
592
593 shmemptr->used_flag[NBUF(n_audio)] = 1;
594
595 nb = audio_buffer_size-audio_bytes_left;
596 audio_bytes_left = 0;
597 n_audio++;
598 }
599
600 /* copy directly to the shmem buffers */
601
602 while(size-nb >= audio_buffer_size)
603 {
604 if(shmemptr->used_flag[NBUF(n_audio)])
605 {
606 audio_errno = AUDIO_ERR_BOVFL;
607 return -1;
608 }
609
610 if(swap && audio_size==16)
611 swpcpy((void*)shmemptr->audio_data[NBUF(n_audio)],(void*)(buf+nb),audio_buffer_size);
612 else
613 memcpy((void*)shmemptr->audio_data[NBUF(n_audio)],(void*)(buf+nb),audio_buffer_size);
614
615 shmemptr->used_flag[NBUF(n_audio)] = 1;
616
617 nb += audio_buffer_size;
618 n_audio++;
619 }
620
621 /* copy the remainder into audio_left_buf */
622
623 if(nb<size)
624 {
625 audio_bytes_left = size-nb;
626 memcpy(audio_left_buf,buf+nb,audio_bytes_left);
627 }
628
629 return size;
630 }
631
632 /*
633 * The audio task
634 */
635
636 #ifdef HAVE_SYS_SOUNDCARD_H
system_error(const char * str,int fd,int use_strerror)637 static void system_error(const char *str, int fd, int use_strerror)
638 {
639 if(use_strerror)
640 sprintf((char*)shmemptr->error_string, "Error %s - %s",str,strerror(errno));
641 else
642 sprintf((char*)shmemptr->error_string, "Error %s",str);
643
644 shmemptr->audio_status = -1;
645 if( fd >= 0 )
646 close(fd);
647 #ifdef FORK_NOT_THREAD
648 exit(1);
649 #else
650 pthread_exit(NULL);
651 #endif
652 }
653 #endif /* HAVE_SYS_SOUNDCARD_H */
654
655 #ifdef HAVE_SYS_SOUNDCARD_H
do_audio(void)656 void do_audio(void)
657 {
658
659 int fd = -1;
660 int tmp, ret, caps, afmt, frag;
661 int nbdone, nbque, ndiff, nbpend, nbset, maxdiff;
662
663 uint8_t *buf = NULL;
664 fd_set selectset;
665
666 struct count_info count;
667 struct audio_buf_info info;
668 struct timeval tv;
669
670 const char *audio_dev_name;
671
672 #ifndef FORK_NOT_THREAD
673 struct sched_param schedparam;
674 sigset_t blocked_signals;
675
676 /* Set the capture thread in a reasonable state - cancellation enabled
677 and asynchronous, SIGINT's ignored... */
678 /* PTHREAD_CANCEL_ASYNCHRONOUS is evil. */
679 /* if( pthread_setcancelstate( PTHREAD_CANCEL_ENABLE, NULL) )
680 {
681 system_error( "Bad pthread_setcancelstate", fd, 0 );
682 }
683 if( pthread_setcanceltype( PTHREAD_CANCEL_ASYNCHRONOUS, NULL) )
684 {
685 system_error( "Bad pthread_setcanceltype", fd, 0 );
686 }*/
687
688 sigaddset( &blocked_signals, SIGINT );
689 if( pthread_sigmask( SIG_BLOCK, &blocked_signals, NULL ))
690 {
691 system_error( "Bad pthread_sigmask", fd, 0 );
692 }
693 #endif
694
695
696 /*
697 * Fragment size and max possible number of frags
698 */
699
700 switch (audio_buffer_size)
701 {
702 case 8192: frag = 0x7fff000d; break;
703 case 4096: frag = 0x7fff000c; break;
704 case 2048: frag = 0x7fff000b; break;
705 case 1024: frag = 0x7fff000a; break;
706 default:
707 system_error("Audio internal error - audio_buffer_size",fd,0);
708 }
709 /* if somebody plays with BUFFSIZE without knowing what he does ... */
710 if (audio_buffer_size>BUFFSIZE)
711 system_error("Audio internal error audio_buffer_size > BUFFSIZE",fd,0);
712
713 /*
714 * Open Audio device, set number of frags wanted
715 */
716
717 audio_dev_name = getenv("LAV_AUDIO_DEV");
718 if(!audio_dev_name) audio_dev_name = "/dev/dsp";
719
720 if(audio_capt)
721 fd=open(audio_dev_name, O_RDONLY, 0);
722 else
723 fd=open(audio_dev_name, O_RDWR, 0);
724
725 if (fd<0) system_error(audio_dev_name,fd,1);
726
727 ret = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag);
728 if(ret<0) system_error("in ioctl SNDCTL_DSP_SETFRAGMENT", fd, 1);
729
730 /*
731 * Setup sampling parameters.
732 */
733
734 afmt = (audio_size==16) ? AFMT_S16_LE : AFMT_U8;
735 tmp = afmt;
736 ret = ioctl(fd, SNDCTL_DSP_SETFMT, &tmp);
737 if(ret<0 || tmp!=afmt) system_error("setting sound format",fd,0);
738
739 tmp = stereo; /* 0=mono, 1=stereo */
740 ret = ioctl(fd, SNDCTL_DSP_STEREO, &tmp);
741 if(ret<0 || tmp!=stereo) system_error("setting mono/stereo",fd,0);
742
743 tmp = audio_rate;
744 ret = ioctl(fd, SNDCTL_DSP_SPEED, &tmp);
745 if(ret<0) {
746 system_error("setting sound rate",fd,0);
747 } else if(tmp != audio_rate) {
748 mjpeg_warn("Sound card told us it's using rate %dHz instead of %dHz", tmp, audio_rate);
749 }
750
751 /* Calculate number of bytes corresponding to TIME_STAMP_TOL */
752
753 maxdiff = audio_byte_rate / (1000000/TIME_STAMP_TOL);
754
755 /*
756 * Check that the device has capability to do mmap and trigger
757 */
758
759 if(mmap_io) {
760 ret = ioctl(fd, SNDCTL_DSP_GETCAPS, &caps);
761 if(ret<0) system_error("getting audio device capabilities",fd,1);
762 if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP))
763 system_error("Soundcard cant do mmap or trigger",fd,0);
764 }
765
766 /*
767 * Get the size of the input/output buffer and do the mmap
768 */
769
770 if (audio_capt)
771 ret = ioctl(fd, SNDCTL_DSP_GETISPACE, &info);
772 else
773 ret = ioctl(fd, SNDCTL_DSP_GETOSPACE, &info);
774
775 if(ret<0) system_error("in ioctl SNDCTL_DSP_GET[IO]SPACE",fd,1);
776
777 if (info.fragsize != audio_buffer_size)
778 system_error("Soundcard fragment size unexpected",fd,0);
779
780 /*
781 * Original comment:
782 * Normally we should get at least 8 fragments (if we use 8KB buffers)
783 * or even more if we use 4KB od 2 KB buffers
784 * We consider 4 fragments as the absolut minimum here!
785 *
786 * A.Stevens Jul 2000: I'm a bit puzzled by the above. A 4096 byte
787 * buffer takes 1/20th second to fill at 44100 stereo. So provide we
788 * empty one frag in less than this we should be o.k. hardly onerous.
789 * Presumably the problem was that this code wasn't running real-time
790 * and so could get starved on a load system.
791 * Anyway, insisting on 8 frags of 8192 bytes puts us sure out of luck
792 * drivers for quite a few modern PCI soundcards ... so lets try for 2
793 * and see what real-time scheduling can do!
794 */
795
796 if (info.fragstotal < 2)
797 {
798 system_error("Could not get enough audio buffer fragments",fd,0);
799 }
800
801 tmp = info.fragstotal*info.fragsize;
802
803 if( mmap_io )
804 {
805 if (audio_capt)
806 buf=mmap(NULL, tmp, PROT_READ , MAP_SHARED, fd, 0);
807 else
808 buf=mmap(NULL, tmp, PROT_WRITE, MAP_SHARED, fd, 0);
809
810 if (buf==MAP_FAILED)
811 system_error("mapping audio buffer "
812 "(consider using read/write instead of mmap)",fd, 1);
813
814 /*
815 * Put device into hold
816 */
817
818 tmp = 0;
819 ret = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp);
820 if(ret<0) system_error("in ioctl SNDCTL_DSP_SETTRIGGER",fd,1);
821
822 }
823
824
825 /*
826 * Signal the parent that initialization is done
827 */
828
829 shmemptr->audio_status = 1;
830
831 /*
832 * nbdone is the number of buffers processed by the audio driver
833 * so far (ie. the number of buffers read or written)
834 * nbque is the number of buffers which have been queued so far
835 * for playing (not used in audio capture)
836 * nbset Number of buffers set (with real data or 0s)
837 *
838 * If we do playback: Wait until the first buffer arrives
839 */
840
841 nbdone = 0;
842 nbque = 0;
843 nbset = 0;
844 if(!audio_capt)
845 {
846 while(!shmemptr->audio_start)
847 {
848 usleep(10000);
849 if(shmemptr->exit_flag)
850 {
851 #ifndef FORK_NOT_THREAD
852 exit(0);
853 #else
854 pthread_exit(NULL);
855 #endif
856 }
857 }
858 /* Copy as many buffers as are allready here */
859 for(nbque=0;nbque<info.fragstotal;nbque++)
860 {
861 if(!shmemptr->used_flag[NBUF(nbque)]) break;
862 if (mmap_io) {
863 memcpy(buf+nbque*info.fragsize,
864 (void*) shmemptr->audio_data[NBUF(nbque)],
865 info.fragsize);
866 } else {
867 write(fd,(void *)shmemptr->audio_data[NBUF(nbque)],
868 info.fragsize);
869 }
870 /* Mark the buffer as free */
871 shmemptr->used_flag[NBUF(nbque)] = 0;
872 }
873 for(nbset=nbque;nbset<info.fragstotal;nbset++)
874 if (mmap_io) {
875 memset(buf+nbset*info.fragsize,0,info.fragsize);
876 } else {
877 char buf[info.fragsize];
878 memset(buf,0,info.fragsize);
879 write(fd,buf,info.fragsize);
880 }
881 }
882
883 #ifndef FORK_NOT_THREAD
884 /* Now we're ready to go move to Real-time scheduling... */
885 schedparam.sched_priority = 1;
886
887 if(setpriority(PRIO_PROCESS, 0, -20)) { /* Give myself maximum priority */
888 mjpeg_warn("Unable to set negative priority for audio thread.");
889 }
890 if( (ret = pthread_setschedparam( pthread_self(), SCHED_FIFO, &schedparam ) ) ) {
891 mjpeg_warn("Pthread Real-time scheduling for audio thread could not be enabled.");
892 }
893 #endif
894
895 /*
896 * Fire up audio device for mmap capture playback (not necessary for read)
897 */
898
899 if( mmap_io )
900 {
901 if(audio_capt)
902 tmp = PCM_ENABLE_INPUT;
903 else
904 tmp = PCM_ENABLE_OUTPUT;
905
906 ret = ioctl(fd, SNDCTL_DSP_SETTRIGGER, &tmp);
907 if(ret<0) system_error("in ioctl SNDCTL_DSP_SETTRIGGER",fd,1);
908 }
909
910
911 /* The recording/playback loop */
912
913 while(1)
914 {
915 /* Wait until new audio data can be read/written */
916
917
918 if( mmap_io )
919 {
920 FD_ZERO(&selectset);
921 FD_SET(fd, &selectset);
922 retry:
923 if(audio_capt)
924 ret = select(fd+1, &selectset, NULL, NULL, NULL);
925 else
926 ret = select(fd+1, NULL, &selectset, NULL, NULL);
927
928 if(ret<0)
929 {
930 if (errno == EINTR)
931 goto retry;
932 else
933 system_error("waiting on audio with select",fd,1);
934 }
935 }
936 else
937 {
938 if (audio_capt) {
939 if( read(fd, (void *)shmemptr->audio_data[NBUF(nbdone)], info.fragsize )
940 != info.fragsize )
941 {
942 system_error( "Sound driver returned partial fragment!\n", fd,1 );
943 }
944 }
945 }
946
947 /* Get time - this time is after at least one buffer has been
948 recorded/played (because select did return), and before the
949 the audio status obtained by the following ioctl */
950
951 gettimeofday(&tv,NULL);
952
953 /* Get the status of the sound buffer */
954 usleep(1000);
955 if(audio_capt)
956 ret = ioctl(fd, SNDCTL_DSP_GETIPTR, &count);
957 else
958 ret = ioctl(fd, SNDCTL_DSP_GETOPTR, &count);
959
960 if (ret<0) system_error("in ioctl SNDCTL_DSP_GET[IO]PTR",fd,1);
961
962 /* Get the difference of minimum number of bytes after the select call
963 and bytes actually present - this gives us a measure of accuracy
964 of the time in tv.
965 TODO
966 Note: count.bytes can overflow in extreme situations (more than
967 3 hrs recording with 44.1 KHz, 16bit stereo), ndiff should
968 be calculated correctly.
969 */
970
971 ndiff = count.bytes - audio_buffer_size*(nbdone+1);
972
973 /* Uncomment this and run testrec if you're getting audio capture
974 problems...
975 */
976 /*
977 mjpeg_info( "CB=%08d ND=%06d BL=%03d NB=%d", count.bytes, ndiff, count.blocks, NBUF(nbdone) );
978 */
979 if(ndiff>maxdiff)
980 {
981 tv.tv_sec = tv.tv_usec = 0;
982 }
983 else
984 {
985 /* Adjust timestamp to take into account delay between sync
986 and now indicated by ndiff */
987 tv.tv_usec -= ndiff * 1000000 / audio_byte_rate;
988 if( tv.tv_usec < 0 )
989 {
990 tv.tv_usec += 1000000;
991 tv.tv_sec -= 1;
992 }
993 }
994
995 if(audio_capt)
996 {
997 /* if exit_flag is set, exit immediatly */
998
999 if(shmemptr->exit_flag)
1000 {
1001 shmemptr->audio_status = -1;
1002 close(fd);
1003 #ifdef FORK_NOT_THREAD
1004 exit(0);
1005 #else
1006 pthread_exit( NULL );
1007 #endif
1008 }
1009
1010 /* copy the ready buffers to our audio ring buffer */
1011
1012 if( mmap_io )
1013 nbpend = count.blocks;
1014 else
1015 nbpend = 1;
1016
1017 while(nbpend)
1018 {
1019
1020 /* Check if buffer nbdone in the ring buffer is free */
1021
1022 if(shmemptr->used_flag[NBUF(nbdone)])
1023 system_error("Audio ring buffer overflow",fd,0);
1024
1025 if( mmap_io )
1026 memcpy((void*) shmemptr->audio_data[NBUF(nbdone)],
1027 buf+(nbdone%info.fragstotal)*info.fragsize,
1028 info.fragsize);
1029
1030 /* Get the status of the sound buffer after copy,
1031 this permits us to see if an overrun occured */
1032
1033 ret = ioctl(fd, SNDCTL_DSP_GETIPTR, &count);
1034 if(ret<0) system_error("in ioctl SNDCTL_DSP_GETIPTR",fd,1);
1035
1036 if( mmap_io )
1037 nbpend += count.blocks;
1038
1039 /* if nbpend >= total frags, a overrun most probably occured */
1040 shmemptr->status[NBUF(nbdone)] = (nbpend >= info.fragstotal) ? -1 : 1;
1041 shmemptr->tmstmp[NBUF(nbdone)] = tv;
1042 shmemptr->used_flag[NBUF(nbdone)] = 1;
1043
1044 nbdone++;
1045 nbpend--;
1046 /* timestamps of all following buffers are unreliable */
1047 tv.tv_sec = tv.tv_usec = 0;
1048 }
1049 }
1050 else
1051 {
1052 /* Update the number and status of frags(=buffers) already output */
1053
1054 nbpend = count.blocks;
1055
1056 while(nbpend)
1057 {
1058 /* check for overflow of the status flags in the ringbuffer */
1059 if(shmemptr->status[NBUF(nbdone)])
1060 system_error("Audio ring buffer overflow",fd,0);
1061 /* We have a buffer underrun during write if nbdone>=nbque */
1062 shmemptr->tmstmp[NBUF(nbdone)] = tv;
1063 shmemptr->status[NBUF(nbdone)] = (nbdone<nbque) ? 1 : -1;
1064 nbdone++;
1065 nbpend--;
1066 /* timestamps of all following buffers are unreliable */
1067 tv.tv_sec = tv.tv_usec = 0;
1068 }
1069
1070 /* If exit_flag is set and all buffers are played, exit */
1071
1072 if(shmemptr->exit_flag && nbdone >= nbque)
1073 {
1074 shmemptr->audio_status = -1;
1075 close(fd);
1076 #ifdef FORK_NOT_THREAD
1077 exit(0);
1078 #else
1079 pthread_exit( NULL );
1080 #endif
1081 }
1082
1083 /* Fill into the soundcard memory as many buffers
1084 as fit and are available */
1085
1086 while(nbque-nbdone < info.fragstotal)
1087 {
1088 if(!shmemptr->used_flag[NBUF(nbque)]) break;
1089
1090 if(nbque>nbdone)
1091 if (mmap_io) {
1092 memcpy(buf+(nbque%info.fragstotal)*info.fragsize,
1093 (void*) shmemptr->audio_data[NBUF(nbque)],
1094 info.fragsize);
1095 } else {
1096 write(fd,(void *)shmemptr->audio_data[NBUF(nbque)],
1097 info.fragsize);
1098 }
1099
1100 /* Mark the buffer as free */
1101 shmemptr->used_flag[NBUF(nbque)] = 0;
1102
1103 nbque++;
1104 }
1105 if(nbset<nbque) nbset = nbque;
1106 while(nbset-nbdone < info.fragstotal)
1107 {
1108 if (mmap_io) {
1109 memset(buf+(nbset%info.fragstotal)*info.fragsize,0,info.fragsize);
1110 } else {
1111 char buf[info.fragsize];
1112 memset(buf,0,info.fragsize);
1113 write(fd,buf,info.fragsize);
1114 }
1115 nbset++;
1116 }
1117 }
1118 }
1119 }
1120 #else
do_audio()1121 void do_audio()
1122 {
1123 fprintf(stderr, "Unsupported audio system in audiolib.c: no soundcard.hn");
1124 }
1125 #endif
1126