1 /***************************************************************************
4 begin : Wed May 15 2002
5 copyright : (C) 2002 by Pete Bernert
6 email : BlackDove@addcom.de
7 ***************************************************************************/
8 /***************************************************************************
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. See also the license.txt file for *
14 * additional informations. *
16 ***************************************************************************/
20 #include <sys/types.h>
23 #include <sys/ioctl.h>
25 #include <sys/soundcard.h>
28 ////////////////////////////////////////////////////////////////////////
30 ////////////////////////////////////////////////////////////////////////
32 #define OSS_MODE_STEREO 1
33 #define OSS_MODE_MONO 0
35 #define OSS_SPEED_44100 44100
37 #define FRAGMENT_SHIFT 12
38 #define FRAGMENT_SIZE (1 << FRAGMENT_SHIFT)
40 static int oss_audio_fd = -1;
43 ////////////////////////////////////////////////////////////////////////
45 ////////////////////////////////////////////////////////////////////////
47 static int oss_init(void)
53 int oss_speed, oss_stereo;
55 pstereo = OSS_MODE_STEREO;
59 if((oss_audio_fd=open("/dev/dsp",O_WRONLY,0))==-1)
61 printf("OSS device not available\n");
65 if(ioctl(oss_audio_fd,SNDCTL_DSP_RESET,0)==-1)
67 printf("Sound reset failed\n");
71 // we use 64 fragments with 1024 bytes each
72 // rearmed: now using 10*4096 for better latency
74 myfrag = (10<<16) | FRAGMENT_SHIFT;
76 if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFRAGMENT,&myfrag)==-1)
78 printf("Sound set fragment failed!\n");
84 if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFMT,&format) == -1)
86 printf("Sound format not supported!\n");
90 if(format!=AFMT_S16_NE)
92 printf("Sound format not supported!\n");
96 if(ioctl(oss_audio_fd,SNDCTL_DSP_STEREO,&oss_stereo)==-1 || !oss_stereo)
98 printf("Stereo mode not supported!\n");
102 if(ioctl(oss_audio_fd,SNDCTL_DSP_SPEED,&oss_speed)==-1)
104 printf("Sound frequency not supported\n");
108 if(oss_speed!=pspeed)
110 printf("Sound frequency not supported\n");
117 ////////////////////////////////////////////////////////////////////////
119 ////////////////////////////////////////////////////////////////////////
121 static void oss_finish(void)
123 if(oss_audio_fd != -1 )
130 ////////////////////////////////////////////////////////////////////////
131 // GET BUFFERED STATUS
132 ////////////////////////////////////////////////////////////////////////
134 static int oss_busy(void)
139 if(oss_audio_fd == -1) return 1;
140 if(ioctl(oss_audio_fd,SNDCTL_DSP_GETOSPACE,&info)==-1)
144 if(info.fragments<(info.fragstotal>>1)) // can we write in at least the half of fragments?
146 else l=0; // -> else go on
152 ////////////////////////////////////////////////////////////////////////
154 ////////////////////////////////////////////////////////////////////////
156 static void oss_feed(void *buf, int bytes)
161 if(oss_audio_fd == -1) return;
162 if(ioctl(oss_audio_fd,SNDCTL_DSP_GETOSPACE,&info)==0)
165 if(bytes > info.fragments * FRAGMENT_SIZE)
166 bytes = info.fragments * FRAGMENT_SIZE;
170 if(info.fragments==info.fragstotal)
172 memset(sbuf, 0, sizeof(sbuf));
173 write(oss_audio_fd, sbuf, sizeof(sbuf));
174 write(oss_audio_fd, sbuf, sizeof(sbuf));
175 write(oss_audio_fd, sbuf, sizeof(sbuf));
179 write(oss_audio_fd, buf, bytes);
182 void out_register_oss(struct out_driver *drv)
185 drv->init = oss_init;
186 drv->finish = oss_finish;
187 drv->busy = oss_busy;
188 drv->feed = oss_feed;