gte_neon: implement MVMVA, some fixes
[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  // rearmed: now using 10*4096 for better latency
69
70  fragsize=12;
71  myfrag=(10<<16)|fragsize;
72
73  if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFRAGMENT,&myfrag)==-1)
74   {
75    printf("Sound set fragment failed!\n");
76    return;        
77   }
78
79  format = AFMT_S16_NE;
80
81  if(ioctl(oss_audio_fd,SNDCTL_DSP_SETFMT,&format) == -1)
82   {
83    printf("Sound format not supported!\n");
84    return;
85   }
86
87  if(format!=AFMT_S16_NE)
88   {
89    printf("Sound format not supported!\n");
90    return;
91   }
92
93  if(ioctl(oss_audio_fd,SNDCTL_DSP_STEREO,&oss_stereo)==-1)
94   {
95    printf("Stereo mode not supported!\n");
96    return;
97   }
98
99  if(oss_stereo!=1)
100   {
101    iDisStereo=1;
102   }
103
104  if(ioctl(oss_audio_fd,SNDCTL_DSP_SPEED,&oss_speed)==-1)
105   {
106    printf("Sound frequency not supported\n");
107    return;
108   }
109
110  if(oss_speed!=pspeed)
111   {
112    printf("Sound frequency not supported\n");
113    return;
114   }
115 }
116
117 ////////////////////////////////////////////////////////////////////////
118 // REMOVE SOUND
119 ////////////////////////////////////////////////////////////////////////
120
121 void RemoveSound(void)
122 {
123  if(oss_audio_fd != -1 )
124   {
125    close(oss_audio_fd);
126    oss_audio_fd = -1;
127   }
128 }
129
130 ////////////////////////////////////////////////////////////////////////
131 // GET BYTES BUFFERED
132 ////////////////////////////////////////////////////////////////////////
133
134 unsigned long SoundGetBytesBuffered(void)
135 {
136  audio_buf_info info;
137  unsigned long l;
138
139  if(oss_audio_fd == -1) return SOUNDSIZE;
140  if(ioctl(oss_audio_fd,SNDCTL_DSP_GETOSPACE,&info)==-1)
141   l=0;
142  else
143   {
144    if(info.fragments<(info.fragstotal>>1))             // can we write in at least the half of fragments?
145         l=SOUNDSIZE;                                   // -> no? wait
146    else l=0;                                           // -> else go on
147   }
148
149  return l;
150 }
151
152 ////////////////////////////////////////////////////////////////////////
153 // FEED SOUND DATA
154 ////////////////////////////////////////////////////////////////////////
155
156 void SoundFeedStreamData(unsigned char* pSound,long lBytes)
157 {
158  if(oss_audio_fd == -1) return;
159  write(oss_audio_fd,pSound,lBytes);
160 }