psxcounters: change spu update ~2ms
[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  pstereo = OSS_MODE_STEREO;
50  oss_speed = pspeed;
51  oss_stereo = pstereo;
52
53  if((oss_audio_fd=open("/dev/dsp",O_WRONLY,0))==-1)
54   {
55    printf("Sound device not available!\n");
56    return;
57   }
58
59  if(ioctl(oss_audio_fd,SNDCTL_DSP_RESET,0)==-1)
60   {
61    printf("Sound reset failed\n");
62    return;
63   }
64
65  // we use 64 fragments with 1024 bytes each
66  // rearmed: now using 10*4096 for better latency
67
68  fragsize=12;
69  myfrag=(10<<16)|fragsize;
70
71  if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFRAGMENT,&myfrag)==-1)
72   {
73    printf("Sound set fragment failed!\n");
74    return;        
75   }
76
77  format = AFMT_S16_NE;
78
79  if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFMT,&format) == -1)
80   {
81    printf("Sound format not supported!\n");
82    return;
83   }
84
85  if(format!=AFMT_S16_NE)
86   {
87    printf("Sound format not supported!\n");
88    return;
89   }
90
91  if(ioctl(oss_audio_fd,SNDCTL_DSP_STEREO,&oss_stereo)==-1 || !oss_stereo)
92   {
93    printf("Stereo mode not supported!\n");
94    return;
95   }
96
97  if(ioctl(oss_audio_fd,SNDCTL_DSP_SPEED,&oss_speed)==-1)
98   {
99    printf("Sound frequency not supported\n");
100    return;
101   }
102
103  if(oss_speed!=pspeed)
104   {
105    printf("Sound frequency not supported\n");
106    return;
107   }
108 }
109
110 ////////////////////////////////////////////////////////////////////////
111 // REMOVE SOUND
112 ////////////////////////////////////////////////////////////////////////
113
114 void RemoveSound(void)
115 {
116  if(oss_audio_fd != -1 )
117   {
118    close(oss_audio_fd);
119    oss_audio_fd = -1;
120   }
121 }
122
123 ////////////////////////////////////////////////////////////////////////
124 // GET BYTES BUFFERED
125 ////////////////////////////////////////////////////////////////////////
126
127 unsigned long SoundGetBytesBuffered(void)
128 {
129  audio_buf_info info;
130  unsigned long l;
131
132  if(oss_audio_fd == -1) return SOUNDSIZE;
133  if(ioctl(oss_audio_fd,SNDCTL_DSP_GETOSPACE,&info)==-1)
134   l=0;
135  else
136   {
137    if(info.fragments<(info.fragstotal>>1))             // can we write in at least the half of fragments?
138         l=SOUNDSIZE;                                   // -> no? wait
139    else l=0;                                           // -> else go on
140   }
141
142  return l;
143 }
144
145 ////////////////////////////////////////////////////////////////////////
146 // FEED SOUND DATA
147 ////////////////////////////////////////////////////////////////////////
148
149 void SoundFeedStreamData(unsigned char* pSound,long lBytes)
150 {
151  if(oss_audio_fd == -1) return;
152  write(oss_audio_fd,pSound,lBytes);
153 }