Thanks all once more for help
I found 2 bugs, the one I had made myself:
I had changed mmap for input to PROT_READ | PROT_WRITE  (W R O N G !!)
which made endless loop system crash.
The other, after removing the first:
"memcpy" gave a segfault
I do not know why - it seems to have worked in old oss times
(I never tested it because I have half duplex card only,
this is in the full duplex driver)
if i look on it it must give a segfault!
Tom what do you think?
I put in a malloc for this memcpy -> now it runs
I append the new code.
please tell me what You think about it

/*****************************************************************************/

/*
 *      oss.c  --  Linux sound I/O.
 *
 *      Copyright (C) 1997  Thomas Sailer ([EMAIL PROTECTED])
 *        Swiss Federal Institute of Technology (ETH), Electronics Lab
 *
......

/* --------------------------------------------------------------------- */

#define EXCESS_FRAGS 3

static void *fdx_driver(void *name_audio)
{
        size_t pagesize = getpagesize();
        int apar, fd_audio, i, brake, brakepoint = 7;
        union {
                caddr_t v;
                short *s;
        } ibuf;
        caddr_t ibuf_ext;
        union {
                caddr_t v;
                short *s;
        } obuf;
        struct audio_buf_info iinfo, oinfo;
        unsigned int isize, osize;
        unsigned int ifragptr, ofragptr;
        fd_set rmask, wmask;
        struct count_info cinfo;
        unsigned int curfrag, lastfrag, nfrags;
        unsigned long long itime, otime, inc_fragment;
        l1_time_t inc_sample;
        int ptt_frames;
        short *s;
        void * m;
        
        if ((fd_audio = open(name_audio, O_RDWR, 0)) < 0)
                errstr(SEV_FATAL, "open");
        /*
         * configure audio
         */
        apar = AUDIO_FMT;
        if (ioctl(fd_audio, SNDCTL_DSP_SETFMT, &apar) == -1)
                errstr(SEV_FATAL, "ioctl: SNDCTL_DSP_SETFMT");
        if (apar != AUDIO_FMT) 
                errprintf(SEV_FATAL, "audio driver does not support the S16 format\n");
        apar = 0;
        if (ioctl(fd_audio, SNDCTL_DSP_STEREO, &apar) == -1)
                errstr(SEV_FATAL, "ioctl: SNDCTL_DSP_STEREO");
        if (apar != 0)
                errprintf(SEV_FATAL, "audio driver does not support mono\n");
        apar = SAMPLE_RATE;
        if (ioctl(fd_audio, SNDCTL_DSP_SPEED, &apar) == -1)
                errstr(SEV_FATAL, "ioctl: SNDCTL_DSP_SPEED");
        if (apar != SAMPLE_RATE) {
                if (abs(apar-SAMPLE_RATE) >= SAMPLE_RATE/100)
                        errprintf(SEV_FATAL, "audio driver does not support 8kHz 
sampling frequency\n");
        }
        inc_sample = 1000000.0*snd_corr/apar;
        inc_fragment = 64*1000000.0*snd_corr/apar*(1<<24);
        ifragptr = 0;
        itime = 0;
        ofragptr = 1;
        otime = ofragptr * inc_fragment;
        ptt_frames = 0;
        lastfrag = 0;
        /*
         * set fragment sizes
         */
        apar = 0xffff0007U;
        if (ioctl(fd_audio, SNDCTL_DSP_SETFRAGMENT, &apar) == -1)
                errstr(SEV_FATAL, "ioctl: SNDCTL_DSP_SETFRAGMENT");
        if (ioctl(fd_audio, SNDCTL_DSP_GETOSPACE, &oinfo) == -1)
                errstr(SEV_FATAL, "ioctl: SNDCTL_DSP_GETOSPACE");
        osize = oinfo.fragstotal * oinfo.fragsize;
        if (ioctl(fd_audio, SNDCTL_DSP_GETISPACE, &iinfo) == -1)
                errstr(SEV_FATAL, "ioctl: SNDCTL_DSP_GETISPACE");
        isize = iinfo.fragstotal * iinfo.fragsize;
        if (EXCESS_FRAGS * iinfo.fragsize > pagesize)
                errprintf(SEV_FATAL, "OSS: input: fragment size %d times excess frags 
> page size %d\n",
                          iinfo.fragsize, pagesize);
        /*
         * mmap buffers
         *
         * BSD people attention: you may need to uncomment the PROT_READ
         * feedback welcome: [EMAIL PROTECTED]
         */
        if ((ibuf.v = mmap(NULL, pagesize + isize, PROT_READ, 
                           MAP_ANON | MAP_PRIVATE, -1, 0)) == MAP_FAILED)
                errstr(SEV_FATAL, "mmap: MAP_ANONYMOUS");
        ibuf_ext = ibuf.v + isize;
        if (munmap(ibuf.v, isize))
                errstr(SEV_FATAL, "munmap: MAP_ANONYMOUS");
        if ((ibuf.v = mmap(ibuf.v, isize , PROT_READ , 
                            MAP_FILE  | MAP_SHARED | MAP_FIXED, 
                          fd_audio, 0)) == MAP_FAILED)
                errstr(SEV_FATAL, "mmap: PROT_READ");
                
/* orig
        if ((obuf.v = mmap(NULL, osize, PROT_WRITE -comment- | PROT_READ -comment, 
                           MAP_FILE | MAP_SHARED, fd_audio, 0)) == MAP_FAILED)
                errstr(SEV_FATAL, "mmap: PROT_WRITE");
*/

        if ((obuf.v = mmap(NULL, pagesize+osize, PROT_WRITE, 
                            MAP_ANON | MAP_PRIVATE, -1, 0)) == MAP_FAILED)
                errstr(SEV_FATAL, "mmap: obuf: MAP_ANONYMOUS");
//      ibuf_ext = ibuf.v + isize;
        if (munmap(obuf.v, osize))
                errstr(SEV_FATAL, "munmap: obuf: MAP_ANONYMOUS");
        if ((obuf.v = mmap(obuf.v, osize, PROT_WRITE /*| PROT_READ*/, 
                            MAP_FILE  | MAP_SHARED | MAP_FIXED, 
                            fd_audio, 0)) == MAP_FAILED)
                errstr(SEV_FATAL, "mmap: obuf: PROT_WRITE");


        errprintf(SEV_INFO, 
                    "\nOSS:  input: #frag: %d  fragsz: %d  totbuf: %d  bufaddr: %p  
mempage: %p\n"
                    "OSS: output: #frag: %d  fragsz: %d  totbuf: %d  bufaddr: %p\n"
                    "OSS: sample time increment: %u  fragment time increment: %u\n",
                    iinfo.fragstotal, iinfo.fragsize, isize, ibuf.s, ibuf_ext, 
                    oinfo.fragstotal, oinfo.fragsize, osize, obuf.s,
                    (unsigned int)inc_sample, (unsigned int)(inc_fragment >> 24));
        /*
         * start playback/recording
         */
        apar = 0;
        if (ioctl(fd_audio, SNDCTL_DSP_SETTRIGGER, &apar) == -1)
                errstr(SEV_FATAL, "ioctl: SNDCTL_DSP_SETTRIGGER");
        apar = PCM_ENABLE_OUTPUT | PCM_ENABLE_INPUT;
        if (ioctl(fd_audio, SNDCTL_DSP_SETTRIGGER, &apar) == -1)
                errstr(SEV_FATAL, "ioctl: SNDCTL_DSP_SETTRIGGER");
        /*
         * loop
         */

        for (;;) {
                FD_ZERO(&rmask);
                FD_ZERO(&wmask);
                FD_SET(fd_audio, &rmask);
                FD_SET(fd_audio, &wmask);
                i = select(fd_audio+1, &rmask, &wmask, NULL, NULL);
                if (i < 0) 
                        errstr(SEV_FATAL, "select");
                if (!FD_ISSET(fd_audio, &rmask) && !FD_ISSET(fd_audio, &wmask))
                        continue;
                /*
                 * process input
                 */
                if (ioctl(fd_audio, SNDCTL_DSP_GETIPTR, &cinfo) == -1)
                        errstr(SEV_FATAL, "ioctl: SNDCTL_DSP_GETIPTR");
                curfrag = cinfo.ptr / iinfo.fragsize;
//              printf( "fdx in:  count info: bytes = %d, blocks = %d, ptr = %d\n", 
cinfo.bytes, cinfo.blocks, cinfo.ptr );
                if (cinfo.blocks > 2) {
                        errprintf(SEV_WARNING, "in:  %d fragments passed since last 
wakeup\n", cinfo.blocks);
                        brake ++;
                        }
                if (brake >= brakepoint) {
                        errprintf(SEV_FATAL, "%d xruns. Exiting.\n", brake);
                        exit (1);
                        }
                
                while (ifragptr != curfrag) {

                        if (!ifragptr) 
                        
                        {
                                m = malloc(pagesize);
                                if (m == NULL)
                                    errstr(SEV_FATAL, "fdx_driver: malloc failed");
                                //      s = (short *)(ibuf.v + isize );
                                s = (short *) m;
                //              printf("\nifragptr: %d, curfrag %d, ibuf.v: %p, s: %p 
\n",
                //              ifragptr, curfrag, ibuf.v, s);                         
  
                //              printf ("shift mem malloced in %p\n", m);
                                memcpy(s, ibuf.v, iinfo.fragsize);
                        } 
                        
                        else
                                s = (short *)(ibuf.v + iinfo.fragsize * ifragptr);
                //      printf("=\nifragptr: %d, curfrag %d, ibuf.v: %p, s: %p \n", 
                //              ifragptr, curfrag, ibuf.v, s);                         
 
                        
                        if (samples_remain > 0) {
                                i = 2*samples_remain;
                                if (i > iinfo.fragsize)
                                        i = iinfo.fragsize;
                                memcpy(samples_ptr, s, i);
                
                //              printf("\nsamples_remain: %d, samples_ptr: %p, i: %d", 
samples_remain, samples_ptr, i);                         
                                                                
                                samples_ptr += i/2;
                                samples_remain -= i/2;
                        }
                        
                        l1_input_samples(itime >> 24, inc_sample, s, iinfo.fragsize/2);
                        itime += inc_fragment;                  
                        if (!ifragptr) free(m);
                        ifragptr++;
                        if (ifragptr >= iinfo.fragstotal)
                                ifragptr = 0;
                }
                /*
                 * process output
                 */
                if (ioctl(fd_audio, SNDCTL_DSP_GETOPTR, &cinfo) == -1)
                        errstr(SEV_FATAL, "ioctl: SNDCTL_DSP_GETOPTR");
                curfrag = cinfo.ptr / oinfo.fragsize;
//              printf( "fdx out: count info: bytes = %d, blocks = %d, ptr = %d\n", 
cinfo.bytes, cinfo.blocks, cinfo.ptr );
                nfrags = oinfo.fragstotal + curfrag - lastfrag;
                lastfrag = curfrag;
                if (nfrags >= oinfo.fragstotal)
                        nfrags -= oinfo.fragstotal;
                if (nfrags != cinfo.blocks)
                        errprintf(SEV_WARNING, "OSS sound driver lost interrupt!\n");
                if (nfrags > 2) {
                        errprintf(SEV_WARNING, "out: %d fragments passed since last 
wakeup\n", nfrags);
                        brake ++;
                        }
                ptt_frames -= nfrags;
                if (ptt_frames < 0) {
                        otime += (-ptt_frames) * inc_fragment;
                        ofragptr -= ptt_frames;
                        while (ofragptr >= oinfo.fragstotal)
                                ofragptr -= oinfo.fragstotal;
                        ptt_frames = 0;
                        memset(obuf.s, 0, oinfo.fragsize * oinfo.fragstotal);
                }
                /* sanity check */
                if (!ptt_frames && ofragptr != (curfrag + 1) % oinfo.fragstotal)
                        errprintf(SEV_FATAL, "output pointers inconsistent %u %u 
%lu\n",
                                  ofragptr, curfrag, (unsigned long)(otime >> 24));
                while (ptt_frames < oinfo.fragstotal && ptt_frames <= 4 && 
                       l1_output_samples(otime >> 24, inc_sample, (short *)(obuf.v + 
oinfo.fragsize * ofragptr), 
                                         oinfo.fragsize/2)) {
                        ofragptr++;
                        if (ofragptr >= oinfo.fragstotal)
                                ofragptr = 0;
                        ptt_frames++;
                        otime += inc_fragment;
                }
                output_ptt(ptt_frames > 0);
        }
}

/* --------------------------------------------------------------------- */

static void *hdx_driver(void *name_audio)
.....

cheers
[EMAIL PROTECTED]


-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Alsa-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/alsa-devel

Reply via email to