decouple input/frame limiter from GPU plugin
[pcsx_rearmed.git] / plugins / dfsound / oss.c
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 "stdafx.h"
19
20 #define _IN_OSS
21
22 #include "externals.h"
23
24 ////////////////////////////////////////////////////////////////////////
25 // oss globals
26 ////////////////////////////////////////////////////////////////////////
27
28 #define OSS_MODE_STEREO     1
29 #define OSS_MODE_MONO       0
30
31 #define OSS_SPEED_44100     44100
32
33 static int oss_audio_fd = -1;
34 extern int errno;
35
36 ////////////////////////////////////////////////////////////////////////
37 // SETUP SOUND
38 ////////////////////////////////////////////////////////////////////////
39
40 void SetupSound(void)
41 {
42  int pspeed=44100;
43  int pstereo;
44  int format;
45  int fragsize = 0;
46  int myfrag;
47  int oss_speed, oss_stereo;
48
49  if(iDisStereo) pstereo=OSS_MODE_MONO;
50  else           pstereo=OSS_MODE_STEREO;
51
52  oss_speed = pspeed;
53  oss_stereo = pstereo;
54
55  if((oss_audio_fd=open("/dev/dsp",O_WRONLY,0))==-1)
56   {
57    printf("Sound device not available!\n");
58    return;
59   }
60
61  if(ioctl(oss_audio_fd,SNDCTL_DSP_RESET,0)==-1)
62   {
63    printf("Sound reset failed\n");
64    return;
65   }
66
67  // we use 64 fragments with 1024 bytes each
68
69  fragsize=10;
70  myfrag=(63<<16)|fragsize;
71
72  if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFRAGMENT,&myfrag)==-1)
73   {
74    printf("Sound set fragment failed!\n");
75    return;        
76   }
77
78  format = AFMT_S16_NE;
79
80  if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFMT,&format) == -1)
81   {
82    printf("Sound format not supported!\n");
83    return;
84   }
85
86  if(format!=AFMT_S16_NE)
87   {
88    printf("Sound format not supported!\n");
89    return;
90   }
91
92  if(ioctl(oss_audio_fd,SNDCTL_DSP_STEREO,&oss_stereo)==-1)
93   {
94    printf("Stereo mode not supported!\n");
95    return;
96   }
97
98  if(oss_stereo!=1)
99   {
100    iDisStereo=1;
101   }
102
103  if(ioctl(oss_audio_fd,SNDCTL_DSP_SPEED,&oss_speed)==-1)
104   {
105    printf("Sound frequency not supported\n");
106    return;
107   }
108
109  if(oss_speed!=pspeed)
110   {
111    printf("Sound frequency not supported\n");
112    return;
113   }
114 }
115
116 ////////////////////////////////////////////////////////////////////////
117 // REMOVE SOUND
118 ////////////////////////////////////////////////////////////////////////
119
120 void RemoveSound(void)
121 {
122  if(oss_audio_fd != -1 )
123   {
124    close(oss_audio_fd);
125    oss_audio_fd = -1;
126   }
127 }
128
129 ////////////////////////////////////////////////////////////////////////
130 // GET BYTES BUFFERED
131 ////////////////////////////////////////////////////////////////////////
132
133 unsigned long SoundGetBytesBuffered(void)
134 {
135  audio_buf_info info;
136  unsigned long l;
137
138  if(oss_audio_fd == -1) return SOUNDSIZE;
139  if(ioctl(oss_audio_fd,SNDCTL_DSP_GETOSPACE,&info)==-1)
140   l=0;
141  else
142   {
143    if(info.fragments<(info.fragstotal>>1))             // can we write in at least the half of fragments?
144         l=SOUNDSIZE;                                   // -> no? wait
145    else l=0;                                           // -> else go on
146   }
147
148  return l;
149 }
150
151 ////////////////////////////////////////////////////////////////////////
152 // FEED SOUND DATA
153 ////////////////////////////////////////////////////////////////////////
154
155 void SoundFeedStreamData(unsigned char* pSound,long lBytes)
156 {
157  if(oss_audio_fd == -1) return;
158  write(oss_audio_fd,pSound,lBytes);
159 }