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