Update of /cvsroot/pure-data/pd/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6097
Modified Files: Tag: desiredata s_audio_oss.c Log Message: cleanup
Index: s_audio_oss.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/s_audio_oss.c,v retrieving revision 1.6.4.2.2.2.2.6 retrieving revision 1.6.4.2.2.2.2.7 diff -C2 -d -r1.6.4.2.2.2.2.6 -r1.6.4.2.2.2.2.7 *** s_audio_oss.c 10 Jul 2007 06:13:33 -0000 1.6.4.2.2.2.2.6 --- s_audio_oss.c 10 Jul 2007 07:04:55 -0000 1.6.4.2.2.2.2.7 *************** *** 5,9 ****
/* this file inputs and outputs audio using the OSS API available on linux. */ - #include <linux/soundcard.h>
--- 5,8 ---- *************** *** 24,28 **** #include <sys/mman.h>
- /* Defines */ #define DEBUG(x) x --- 23,26 ---- *************** *** 59,85 **** static int linux_nindevs = 0;
! /* exported variables */ float sys_dacsr; t_sample *sys_soundout; t_sample *sys_soundin;
! /* OSS-specific private variables */ static int oss_blockmode = 0; /* flag to use "blockmode" */ static int oss_32bit = 0; /* allow 23 bit transfers in OSS */
! /* don't assume we can turn all 31 bits when doing float-to-fix; ! otherwise some audio drivers (e.g. Midiman/ALSA) wrap around. */ #define FMAX 0x7ffff000 #define CLIP32(x) (((x)>FMAX)?FMAX:((x) < -FMAX)?-FMAX:(x))
/* ---------------- public routines ----------------------- */ - static int oss_ndev = 0;
! /* find out how many OSS devices we have. Since this has to ! open the devices to find out if they're there, we have ! to be called before audio is actually started up. So we ! cache the results, which in effect are the number of available ! devices. */ void oss_init() { static int countedthem = 0; --- 57,81 ---- static int linux_nindevs = 0;
! /* exported variables */ float sys_dacsr; t_sample *sys_soundout; t_sample *sys_soundin;
! /* OSS-specific private variables */ static int oss_blockmode = 0; /* flag to use "blockmode" */ static int oss_32bit = 0; /* allow 23 bit transfers in OSS */
! /* don't assume we can turn all 31 bits when doing float-to-fix; ! otherwise some audio drivers (e.g. Midiman/ALSA) wrap around. */ #define FMAX 0x7ffff000 #define CLIP32(x) (((x)>FMAX)?FMAX:((x) < -FMAX)?-FMAX:(x))
/* ---------------- public routines ----------------------- */ static int oss_ndev = 0;
! /* find out how many OSS devices we have. Since this has to ! open the devices to find out if they're there, we have ! to be called before audio is actually started up. So we ! cache the results, which in effect are the number of available devices. */ void oss_init() { static int countedthem = 0; *************** *** 105,111 ****
int oss_reset(int fd) { ! int err; ! if ((err = ioctl(fd,SNDCTL_DSP_RESET)) < 0) ! error("OSS: Could not reset"); return err; } --- 101,106 ----
int oss_reset(int fd) { ! int err = ioctl(fd,SNDCTL_DSP_RESET); ! if (err<0) error("OSS: Could not reset"); return err; } *************** *** 136,141 **** param = wantformat;
! if (sys_verbose) ! post("bytes per sample = %d", dev->bytespersamp); if (ioctl(fd, SNDCTL_DSP_SETFMT, ¶m) == -1) fprintf(stderr,"OSS: Could not set DSP format\n"); --- 131,135 ---- param = wantformat;
! if (sys_verbose) post("bytes per sample = %d", dev->bytespersamp); if (ioctl(fd, SNDCTL_DSP_SETFMT, ¶m) == -1) fprintf(stderr,"OSS: Could not set DSP format\n"); *************** *** 185,194 **** is greater than this buffer size; for now, we just print something out. */ - int defect; ! if (ioctl(fd, SOUND_PCM_GETOSPACE,&ainfo) < 0) ! fprintf(stderr,"OSS: ioctl on output device failed"); dev->bufsize = ainfo.bytes; - defect = sys_advance_samples * (dev->bytespersamp * nchannels) - dev->bufsize - OSS_XFERSIZE(nchannels, dev->bytespersamp); --- 179,185 ---- is greater than this buffer size; for now, we just print something out. */ int defect; ! if (ioctl(fd, SOUND_PCM_GETOSPACE,&ainfo) < 0) fprintf(stderr,"OSS: ioctl on output device failed"); dev->bufsize = ainfo.bytes; defect = sys_advance_samples * (dev->bytespersamp * nchannels) - dev->bufsize - OSS_XFERSIZE(nchannels, dev->bytespersamp); *************** *** 207,212 **** while (param > 1) { int save = param; ! if (ioctl(fd, SNDCTL_DSP_CHANNELS, ¶m) == -1) ! error("OSS: SNDCTL_DSP_CHANNELS failed %s",devname); else if (param == save) return param; param = save - 1; --- 198,202 ---- while (param > 1) { int save = param; ! if (ioctl(fd, SNDCTL_DSP_CHANNELS, ¶m) == -1) error("OSS: SNDCTL_DSP_CHANNELS failed %s",devname); else if (param == save) return param; param = save - 1; *************** *** 216,219 **** --- 206,210 ----
#define O_AUDIOFLAG O_NDELAY + /* what's the deal with (!O_NDELAY) ? does it make sense to you? */
int oss_open_audio(int nindev, int *indev, int nchin, int *chin, *************** *** 241,249 **** if (!wantchannels) goto end_out_loop; if (thisdevice > 0) sprintf(devname, "/dev/dsp%d", thisdevice); else sprintf(devname, "/dev/dsp"); ! /* search for input request for same device. Succeed only ! if the number of channels matches. */ ! for (j = 0; j < nindev; j++) ! if (indev[j] == thisdevice && chin[j] == wantchannels) inindex = j; ! /* if the same device is requested for input and output, try to open it read/write */ if (inindex >= 0) { sys_setalarm(1000000); --- 232,238 ---- if (!wantchannels) goto end_out_loop; if (thisdevice > 0) sprintf(devname, "/dev/dsp%d", thisdevice); else sprintf(devname, "/dev/dsp"); ! /* search for input request for same device. Succeed only if the number of channels matches. */ ! for (j = 0; j < nindev; j++) if (indev[j] == thisdevice && chin[j] == wantchannels) inindex = j; ! /* if the same device is requested for input and output, try to open it read/write */ if (inindex >= 0) { sys_setalarm(1000000); *************** *** 252,266 **** post("(now will try write-only...)"); } else { ! if (fcntl(fd, F_SETFD, 1) < 0) ! post("couldn't set close-on-exec flag on audio"); ! if ((flags = fcntl(fd, F_GETFL)) < 0) ! post("couldn't get audio device flags"); ! else if (fcntl(fd, F_SETFL, flags & (!O_NDELAY)) < 0) ! post("couldn't set audio device flags"); if (sys_verbose) post("opened %s for reading and writing\n", devname); linux_adcs[inindex].fd = fd; } } ! /* if that didn't happen or if it failed, try write-only */ if (fd == -1) { sys_setalarm(1000000); --- 241,252 ---- post("(now will try write-only...)"); } else { ! if (fcntl(fd, F_SETFD, 1) < 0) post("couldn't set close-on-exec flag on audio"); ! if ((flags = fcntl(fd, F_GETFL)) < 0) post("couldn't get audio device flags"); ! else if (fcntl(fd, F_SETFL, flags & (!O_NDELAY)) < 0) post("couldn't set audio device flags"); if (sys_verbose) post("opened %s for reading and writing\n", devname); linux_adcs[inindex].fd = fd; } } ! /* if that didn't happen or if it failed, try write-only */ if (fd == -1) { sys_setalarm(1000000); *************** *** 269,296 **** break; } ! if (fcntl(fd, F_SETFD, 1) < 0) ! post("couldn't set close-on-exec flag on audio"); ! if ((flags = fcntl(fd, F_GETFL)) < 0) ! post("couldn't get audio device flags"); ! else if (fcntl(fd, F_SETFL, flags & (!O_NDELAY)) < 0) ! post("couldn't set audio device flags"); ! if (sys_verbose) ! post("opened %s for writing only\n", devname); } ! if (ioctl(fd, SNDCTL_DSP_GETCAPS, &capabilities) == -1) ! error("OSS: SNDCTL_DSP_GETCAPS failed %s", devname); ! gotchans = oss_setchannels(fd, (wantchannels>OSS_MAXCHPERDEV)?OSS_MAXCHPERDEV:wantchannels, devname); - if (sys_verbose) post("opened audio output on %s; got %d channels", devname, gotchans); - if (gotchans < 2) { ! /* can't even do stereo? just give up. */ ! close(fd); } else { linux_dacs[linux_noutdevs].nchannels = gotchans; linux_dacs[linux_noutdevs].fd = fd; oss_configure(&linux_dacs[linux_noutdevs], rate, 1, 0); - linux_noutdevs++; outchannels += gotchans; --- 255,272 ---- break; } ! if (fcntl(fd, F_SETFD, 1) < 0) post("couldn't set close-on-exec flag on audio"); ! if ((flags = fcntl(fd, F_GETFL)) < 0) post("couldn't get audio device flags"); ! else if (fcntl(fd, F_SETFL, flags & (!O_NDELAY)) < 0) post("couldn't set audio device flags"); ! if (sys_verbose) post("opened %s for writing only\n", devname); } ! if (ioctl(fd, SNDCTL_DSP_GETCAPS, &capabilities) == -1) error("OSS: SNDCTL_DSP_GETCAPS failed %s", devname); gotchans = oss_setchannels(fd, (wantchannels>OSS_MAXCHPERDEV)?OSS_MAXCHPERDEV:wantchannels, devname); if (sys_verbose) post("opened audio output on %s; got %d channels", devname, gotchans); if (gotchans < 2) { ! close(fd); /* can't even do stereo? just give up. */ } else { linux_dacs[linux_noutdevs].nchannels = gotchans; linux_dacs[linux_noutdevs].fd = fd; oss_configure(&linux_dacs[linux_noutdevs], rate, 1, 0); linux_noutdevs++; outchannels += gotchans; *************** *** 332,344 **** } linux_adcs[linux_nindevs].fd = fd; - gotchans = oss_setchannels(fd, (wantchannels>OSS_MAXCHPERDEV)?OSS_MAXCHPERDEV:wantchannels, devname); if (sys_verbose) post("opened audio input device %s; got %d channels", devname, gotchans); - if (gotchans < 1) { close(fd); goto end_in_loop; } - linux_adcs[linux_nindevs].nchannels = gotchans; oss_configure(linux_adcs+linux_nindevs, rate, 0, alreadyopened); --- 308,317 ---- *************** *** 349,365 **** end_in_loop: ; } ! ! /* We have to do a read to start the engine. This is ! necessary because sys_send_dacs waits until the input ! buffer is filled and only reads on a filled buffer. ! This is good, because it's a way to make sure that we ! will not block. But I wonder why we only have to read ! from one of the devices and not all of them??? */ ! if (linux_nindevs) { if (sys_verbose) fprintf(stderr,("OSS: issuing first ADC 'read' ... ")); read(linux_adcs[0].fd, buf, linux_adcs[0].bytespersamp * linux_adcs[0].nchannels * sys_dacblocksize); ! if (sys_verbose) ! fprintf(stderr, "...done.\n"); } /* now go and fill all the output buffers. */ --- 322,332 ---- end_in_loop: ; } ! /* We have to do a read to start the engine. This is necessary because sys_send_dacs waits until the input ! buffer is filled and only reads on a filled buffer. This is good, because it's a way to make sure that we ! will not block. But I wonder why we only have to read from one of the devices and not all of them??? */ if (linux_nindevs) { if (sys_verbose) fprintf(stderr,("OSS: issuing first ADC 'read' ... ")); read(linux_adcs[0].fd, buf, linux_adcs[0].bytespersamp * linux_adcs[0].nchannels * sys_dacblocksize); ! if (sys_verbose) fprintf(stderr, "...done.\n"); } /* now go and fill all the output buffers. */ *************** *** 377,383 ****
void oss_close_audio() { ! int i; ! for (i=0;i<linux_nindevs ;i++) close(linux_adcs[i].fd); ! for (i=0;i<linux_noutdevs;i++) close(linux_dacs[i].fd); linux_nindevs = linux_noutdevs = 0; } --- 344,349 ----
void oss_close_audio() { ! for (int i=0;i<linux_nindevs ;i++) close(linux_adcs[i].fd); ! for (int i=0;i<linux_noutdevs;i++) close(linux_dacs[i].fd); linux_nindevs = linux_noutdevs = 0; } *************** *** 416,420 **** char buf[OSS_MAXSAMPLEWIDTH * sys_dacblocksize * OSS_MAXCHPERDEV]; audio_buf_info ainfo; - /* 1. if any input devices are ahead (have more than 1 buffer stored), drop one or more buffers worth */ for (int dev=0; dev<linux_nindevs; dev++) { --- 382,385 ---- *************** *** 431,435 **** } } - /* 2. if any output devices are behind, feed them zeros to catch them up */ for (int dev=0; dev<linux_noutdevs; dev++) { --- 396,399 ---- *************** *** 448,453 **** } } ! /* 3. if any DAC devices are too far ahead, plan to drop the ! number of frames which will let the others catch up. */ for (int dev=0; dev<linux_noutdevs; dev++) { t_oss_dev d = linux_dacs[dev]; --- 412,416 ---- } } ! /* 3. if any DAC devices are too far ahead, plan to drop the number of frames which will let the others catch up. */ for (int dev=0; dev<linux_noutdevs; dev++) { t_oss_dev d = linux_dacs[dev]; *************** *** 467,471 **** int idle = 0; double timeref, timenow; - if (!linux_nindevs && !linux_noutdevs) return SENDDACS_NO; if (!oss_blockmode) { --- 430,433 ---- *************** *** 510,514 **** for (int dev=0; dev<linux_nindevs; dev++) if (linux_adcs[dev].space > 3 * OSS_XFERSIZE(linux_adcs[dev].nchannels, linux_adcs[dev].bytespersamp)) goto badsync; - /* return zero to tell the scheduler we're idle. */ return SENDDACS_NO; --- 472,475 ---- *************** *** 518,522 **** return SENDDACS_NO; } - /* do output */ timeref = sys_getrealtime(); --- 479,482 ---- *************** *** 536,541 **** for (j=0, fp2 = fp1; j<nchannels; j++, fp2 += sys_dacblocksize) { int s = int(*fp2 * 32767.); ! if (s > 32767) s = 32767; ! else if (s < -32767) s = -32767; sp[j] = s; } --- 496,500 ---- for (j=0, fp2 = fp1; j<nchannels; j++, fp2 += sys_dacblocksize) { int s = int(*fp2 * 32767.); ! if (s > 32767) s = 32767; else if (s < -32767) s = -32767; sp[j] = s; } *************** *** 551,555 **** } memset(sys_soundout, 0, sys_outchannels * (sizeof(float) * sys_dacblocksize)); - for (int dev=0, thischan = 0; dev < linux_nindevs; dev++) { int nchannels = linux_adcs[dev].nchannels; --- 510,513 ----