cdrom: attempt to deal with broken subq :(
[pcsx_rearmed.git] / plugins / dfsound / oss.c
... / ...
CommitLineData
1/***************************************************************************
2 oss.c - description
3 -------------------
4 begin : Wed May 15 2002
5 copyright : (C) 2002 by Pete Bernert
6 email : BlackDove@addcom.de
7 ***************************************************************************/
8/***************************************************************************
9 * *
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. *
15 * *
16 ***************************************************************************/
17
18#include <stdio.h>
19#include <sys/types.h>
20#include <sys/stat.h>
21#include <fcntl.h>
22#include <sys/ioctl.h>
23#include <unistd.h>
24#include <sys/soundcard.h>
25#include "out.h"
26
27////////////////////////////////////////////////////////////////////////
28// oss globals
29////////////////////////////////////////////////////////////////////////
30
31#define OSS_MODE_STEREO 1
32#define OSS_MODE_MONO 0
33
34#define OSS_SPEED_44100 44100
35
36static int oss_audio_fd = -1;
37extern int errno;
38
39////////////////////////////////////////////////////////////////////////
40// SETUP SOUND
41////////////////////////////////////////////////////////////////////////
42
43static int oss_init(void)
44{
45 int pspeed=44100;
46 int pstereo;
47 int format;
48 int fragsize = 0;
49 int myfrag;
50 int oss_speed, oss_stereo;
51
52 pstereo = OSS_MODE_STEREO;
53 oss_speed = pspeed;
54 oss_stereo = pstereo;
55
56 if((oss_audio_fd=open("/dev/dsp",O_WRONLY,0))==-1)
57 {
58 printf("OSS device not available\n");
59 return -1;
60 }
61
62 if(ioctl(oss_audio_fd,SNDCTL_DSP_RESET,0)==-1)
63 {
64 printf("Sound reset failed\n");
65 return -1;
66 }
67
68 // we use 64 fragments with 1024 bytes each
69 // rearmed: now using 10*4096 for better latency
70
71 fragsize=12;
72 myfrag=(10<<16)|fragsize;
73
74 if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFRAGMENT,&myfrag)==-1)
75 {
76 printf("Sound set fragment failed!\n");
77 return -1;
78 }
79
80 format = AFMT_S16_NE;
81
82 if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFMT,&format) == -1)
83 {
84 printf("Sound format not supported!\n");
85 return -1;
86 }
87
88 if(format!=AFMT_S16_NE)
89 {
90 printf("Sound format not supported!\n");
91 return -1;
92 }
93
94 if(ioctl(oss_audio_fd,SNDCTL_DSP_STEREO,&oss_stereo)==-1 || !oss_stereo)
95 {
96 printf("Stereo mode not supported!\n");
97 return -1;
98 }
99
100 if(ioctl(oss_audio_fd,SNDCTL_DSP_SPEED,&oss_speed)==-1)
101 {
102 printf("Sound frequency not supported\n");
103 return -1;
104 }
105
106 if(oss_speed!=pspeed)
107 {
108 printf("Sound frequency not supported\n");
109 return -1;
110 }
111
112 return 0;
113}
114
115////////////////////////////////////////////////////////////////////////
116// REMOVE SOUND
117////////////////////////////////////////////////////////////////////////
118
119static void oss_finish(void)
120{
121 if(oss_audio_fd != -1 )
122 {
123 close(oss_audio_fd);
124 oss_audio_fd = -1;
125 }
126}
127
128////////////////////////////////////////////////////////////////////////
129// GET BUFFERED STATUS
130////////////////////////////////////////////////////////////////////////
131
132static int oss_busy(void)
133{
134 audio_buf_info info;
135 unsigned long l;
136
137 if(oss_audio_fd == -1) return 1;
138 if(ioctl(oss_audio_fd,SNDCTL_DSP_GETOSPACE,&info)==-1)
139 l=0;
140 else
141 {
142 if(info.fragments<(info.fragstotal>>1)) // can we write in at least the half of fragments?
143 l=1; // -> no? wait
144 else l=0; // -> else go on
145 }
146
147 return l;
148}
149
150////////////////////////////////////////////////////////////////////////
151// FEED SOUND DATA
152////////////////////////////////////////////////////////////////////////
153
154static void oss_feed(void *buf, int bytes)
155{
156 if(oss_audio_fd == -1) return;
157 write(oss_audio_fd, buf, bytes);
158}
159
160void out_register_oss(struct out_driver *drv)
161{
162 drv->name = "oss";
163 drv->init = oss_init;
164 drv->finish = oss_finish;
165 drv->busy = oss_busy;
166 drv->feed = oss_feed;
167}