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