e14743d1 |
1 | /* |
2 | SDL - Simple DirectMedia Layer |
3 | Copyright (C) 1997-2009 Sam Lantinga |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | This library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with this library; if not, write to the Free Software |
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
18 | |
19 | Sam Lantinga |
20 | slouken@libsdl.org |
21 | */ |
22 | #include "SDL_config.h" |
23 | |
24 | /* Get the name of the audio device we use for output */ |
25 | |
26 | #if SDL_AUDIO_DRIVER_BSD || SDL_AUDIO_DRIVER_OSS || SDL_AUDIO_DRIVER_SUNAUDIO |
27 | |
28 | #include <fcntl.h> |
29 | #include <sys/types.h> |
30 | #include <sys/stat.h> |
31 | |
32 | #include "SDL_stdinc.h" |
33 | #include "SDL_audiodev_c.h" |
34 | |
35 | #ifndef _PATH_DEV_DSP |
36 | #if defined(__NETBSD__) || defined(__OPENBSD__) |
37 | #define _PATH_DEV_DSP "/dev/audio" |
38 | #else |
39 | #define _PATH_DEV_DSP "/dev/dsp" |
40 | #endif |
41 | #endif |
42 | #ifndef _PATH_DEV_DSP24 |
43 | #define _PATH_DEV_DSP24 "/dev/sound/dsp" |
44 | #endif |
45 | #ifndef _PATH_DEV_AUDIO |
46 | #define _PATH_DEV_AUDIO "/dev/audio" |
47 | #endif |
48 | |
49 | |
50 | int SDL_OpenAudioPath(char *path, int maxlen, int flags, int classic) |
51 | { |
52 | const char *audiodev; |
53 | int audio_fd; |
54 | char audiopath[1024]; |
55 | |
56 | /* Figure out what our audio device is */ |
57 | if ( ((audiodev=SDL_getenv("SDL_PATH_DSP")) == NULL) && |
58 | ((audiodev=SDL_getenv("AUDIODEV")) == NULL) ) { |
59 | if ( classic ) { |
60 | audiodev = _PATH_DEV_AUDIO; |
61 | } else { |
62 | struct stat sb; |
63 | |
64 | /* Added support for /dev/sound/\* in Linux 2.4 */ |
65 | if ( ((stat("/dev/sound", &sb) == 0) && S_ISDIR(sb.st_mode)) && |
66 | ((stat(_PATH_DEV_DSP24, &sb) == 0) && S_ISCHR(sb.st_mode)) ) { |
67 | audiodev = _PATH_DEV_DSP24; |
68 | } else { |
69 | audiodev = _PATH_DEV_DSP; |
70 | } |
71 | } |
72 | } |
73 | audio_fd = open(audiodev, flags, 0); |
74 | |
75 | /* If the first open fails, look for other devices */ |
76 | if ( (audio_fd < 0) && (SDL_strlen(audiodev) < (sizeof(audiopath)-3)) ) { |
77 | int exists, instance; |
78 | struct stat sb; |
79 | |
80 | instance = 1; |
81 | do { /* Don't use errno ENOENT - it may not be thread-safe */ |
82 | SDL_snprintf(audiopath, SDL_arraysize(audiopath), |
83 | "%s%d", audiodev, instance++); |
84 | exists = 0; |
85 | if ( stat(audiopath, &sb) == 0 ) { |
86 | exists = 1; |
87 | audio_fd = open(audiopath, flags, 0); |
88 | } |
89 | } while ( exists && (audio_fd < 0) ); |
90 | audiodev = audiopath; |
91 | } |
92 | if ( path != NULL ) { |
93 | SDL_strlcpy(path, audiodev, maxlen); |
94 | path[maxlen-1] = '\0'; |
95 | } |
96 | return(audio_fd); |
97 | } |
98 | |
99 | #elif SDL_AUDIO_DRIVER_PAUD |
100 | |
101 | /* Get the name of the audio device we use for output */ |
102 | |
103 | #include <sys/types.h> |
104 | #include <sys/stat.h> |
105 | |
106 | #include "SDL_stdinc.h" |
107 | #include "SDL_audiodev_c.h" |
108 | |
109 | #ifndef _PATH_DEV_DSP |
110 | #define _PATH_DEV_DSP "/dev/%caud%c/%c" |
111 | #endif |
112 | |
113 | char devsettings[][3] = |
114 | { |
115 | { 'p', '0', '1' }, { 'p', '0', '2' }, { 'p', '0', '3' }, { 'p', '0', '4' }, |
116 | { 'p', '1', '1' }, { 'p', '1', '2' }, { 'p', '1', '3' }, { 'p', '1', '4' }, |
117 | { 'p', '2', '1' }, { 'p', '2', '2' }, { 'p', '2', '3' }, { 'p', '2', '4' }, |
118 | { 'p', '3', '1' }, { 'p', '3', '2' }, { 'p', '3', '3' }, { 'p', '3', '4' }, |
119 | { 'b', '0', '1' }, { 'b', '0', '2' }, { 'b', '0', '3' }, { 'b', '0', '4' }, |
120 | { 'b', '1', '1' }, { 'b', '1', '2' }, { 'b', '1', '3' }, { 'b', '1', '4' }, |
121 | { 'b', '2', '1' }, { 'b', '2', '2' }, { 'b', '2', '3' }, { 'b', '2', '4' }, |
122 | { 'b', '3', '1' }, { 'b', '3', '2' }, { 'b', '3', '3' }, { 'b', '3', '4' }, |
123 | { '\0', '\0', '\0' } |
124 | }; |
125 | |
126 | static int OpenUserDefinedDevice(char *path, int maxlen, int flags) |
127 | { |
128 | const char *audiodev; |
129 | int audio_fd; |
130 | |
131 | /* Figure out what our audio device is */ |
132 | if ((audiodev=SDL_getenv("SDL_PATH_DSP")) == NULL) { |
133 | audiodev=SDL_getenv("AUDIODEV"); |
134 | } |
135 | if ( audiodev == NULL ) { |
136 | return -1; |
137 | } |
138 | audio_fd = open(audiodev, flags, 0); |
139 | if ( path != NULL ) { |
140 | SDL_strlcpy(path, audiodev, maxlen); |
141 | path[maxlen-1] = '\0'; |
142 | } |
143 | return audio_fd; |
144 | } |
145 | |
146 | int SDL_OpenAudioPath(char *path, int maxlen, int flags, int classic) |
147 | { |
148 | struct stat sb; |
149 | int audio_fd; |
150 | char audiopath[1024]; |
151 | int cycle; |
152 | |
153 | audio_fd = OpenUserDefinedDevice(path,maxlen,flags); |
154 | if ( audio_fd != -1 ) { |
155 | return audio_fd; |
156 | } |
157 | |
158 | cycle = 0; |
159 | while( devsettings[cycle][0] != '\0' ) { |
160 | SDL_snprintf( audiopath, SDL_arraysize(audiopath), |
161 | _PATH_DEV_DSP, |
162 | devsettings[cycle][0], |
163 | devsettings[cycle][1], |
164 | devsettings[cycle][2]); |
165 | |
166 | if ( stat(audiopath, &sb) == 0 ) { |
167 | audio_fd = open(audiopath, flags, 0); |
168 | if ( audio_fd > 0 ) { |
169 | if ( path != NULL ) { |
170 | SDL_strlcpy( path, audiopath, maxlen ); |
171 | } |
172 | return audio_fd; |
173 | } |
174 | } |
175 | } |
176 | return -1; |
177 | } |
178 | |
179 | #endif /* Audio driver selection */ |