comparison src/audio/dsp/SDL_dspaudio.c @ 3810:2c5387c0a642 SDL-ryan-multiple-audio-device

Multiple audio device code is now working for dsp and dma targets.
author Ryan C. Gordon <icculus@icculus.org>
date Thu, 05 Oct 2006 04:47:13 +0000
parents c8b3d3d13ed1
children 9d070c1a45fa
comparison
equal deleted inserted replaced
3809:7852b5b78af5 3810:2c5387c0a642
53 53
54 /* The tag name used by DSP audio */ 54 /* The tag name used by DSP audio */
55 #define DSP_DRIVER_NAME "dsp" 55 #define DSP_DRIVER_NAME "dsp"
56 56
57 /* Open the audio device for playback, and don't block if busy */ 57 /* Open the audio device for playback, and don't block if busy */
58 #define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) 58 #define OPEN_FLAGS_OUTPUT (O_WRONLY|O_NONBLOCK)
59 #define OPEN_FLAGS_INPUT (O_RDONLY|O_NONBLOCK)
59 60
60 /* Audio driver functions */ 61 /* Audio driver functions */
61 static int DSP_DetectDevices(int iscapture); 62 static int DSP_DetectDevices(int iscapture);
62 static const char *DSP_GetDeviceName(int index, int iscapture); 63 static const char *DSP_GetDeviceName(int index, int iscapture);
63 static int DSP_OpenDevice(_THIS, const char *devname, int iscapture); 64 static int DSP_OpenDevice(_THIS, const char *devname, int iscapture);
64 static void DSP_WaitDevice(_THIS); 65 static void DSP_WaitDevice(_THIS);
65 static void DSP_PlayDevice(_THIS); 66 static void DSP_PlayDevice(_THIS);
66 static Uint8 *DSP_GetDeviceBuf(_THIS); 67 static Uint8 *DSP_GetDeviceBuf(_THIS);
67 static void DSP_CloseDevice(_THIS); 68 static void DSP_CloseDevice(_THIS);
69 static void DSP_Deinitialize(void);
68 70
69 /* Audio driver bootstrap functions */ 71 /* Audio driver bootstrap functions */
72
73 static char **outputDevices = NULL;
74 static int outputDeviceCount = 0;
75 static char **inputDevices = NULL;
76 static int inputDeviceCount = 0;
77
78 static inline void
79 free_device_list(char ***devs, int *count)
80 {
81 SDL_FreeUnixAudioDevices(devs, count);
82 }
83
84 static inline void
85 build_device_list(int iscapture, char ***devs, int *count)
86 {
87 const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
88 free_device_list(devs, count);
89 SDL_EnumUnixAudioDevices(flags, 0, NULL, devs, count);
90 }
91
92 static inline void
93 build_device_lists(void)
94 {
95 build_device_list(0, &outputDevices, &outputDeviceCount);
96 build_device_list(1, &inputDevices, &inputDeviceCount);
97 }
98
99
100 static inline void
101 free_device_lists(void)
102 {
103 free_device_list(&outputDevices, &outputDeviceCount);
104 free_device_list(&inputDevices, &inputDeviceCount);
105 }
106
70 107
71 static int 108 static int
72 DSP_Available(void) 109 DSP_Available(void)
73 { 110 {
74 /*
75 * !!! FIXME: maybe change this to always available, and move this to
76 * !!! FIXME: to device enumeration and opening?
77 */
78 int fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0);
79 int available = 0; 111 int available = 0;
80 if (fd >= 0) { 112 build_device_lists();
81 available = 1; 113 available = ((outputDeviceCount > 0) || (inputDeviceCount > 0));
82 close(fd); 114 free_device_lists();
83 } 115 return available;
84 return (available);
85 } 116 }
86 117
87 118
88 static int 119 static int
89 DSP_Init(SDL_AudioDriverImpl *impl) 120 DSP_Init(SDL_AudioDriverImpl *impl)
90 { 121 {
91 /* Set the function pointers */ 122 /* Set the function pointers */
92 impl->DetectDevices = DSP_DetectDevices; 123 impl->DetectDevices = DSP_DetectDevices;
93 impl->GetDeviceName = DSP_GetDeviceName; 124 impl->GetDeviceName = DSP_GetDeviceName;
94 impl->OpenDevice = DSP_OpenDevice; 125 impl->OpenDevice = DSP_OpenDevice;
95 impl->WaitDevice = DSP_WaitDevice;
96 impl->PlayDevice = DSP_PlayDevice; 126 impl->PlayDevice = DSP_PlayDevice;
97 impl->GetDeviceBuf = DSP_GetDeviceBuf; 127 impl->GetDeviceBuf = DSP_GetDeviceBuf;
98 impl->CloseDevice = DSP_CloseDevice; 128 impl->CloseDevice = DSP_CloseDevice;
99 129 impl->Deinitialize = DSP_Deinitialize;
130
131 build_device_lists();
100 return 1; 132 return 1;
101 } 133 }
102 134
103 135
104 AudioBootStrap DSP_bootstrap = { 136 AudioBootStrap DSP_bootstrap = {
105 DSP_DRIVER_NAME, "OSS /dev/dsp standard audio", 137 DSP_DRIVER_NAME, "OSS /dev/dsp standard audio",
106 DSP_Available, DSP_Init, 0 138 DSP_Available, DSP_Init, 0
107 }; 139 };
108 140
109 141
142 static void DSP_Deinitialize(void)
143 {
144 free_device_lists();
145 }
146
147
110 static int 148 static int
111 DSP_DetectDevices(int iscapture) 149 DSP_DetectDevices(int iscapture)
112 { 150 {
113 return -1; /* !!! FIXME */ 151 if (iscapture) {
114 } 152 build_device_list(1, &inputDevices, &inputDeviceCount);
115 153 return inputDeviceCount;
154 } else {
155 build_device_list(0, &outputDevices, &outputDeviceCount);
156 return outputDeviceCount;
157 }
158
159 return 0; /* shouldn't ever hit this. */
160 }
116 161
117 static const char * 162 static const char *
118 DSP_GetDeviceName(int index, int iscapture) 163 DSP_GetDeviceName(int index, int iscapture)
119 { 164 {
120 SDL_SetError("No such device"); /* !!! FIXME */ 165 if ((iscapture) && (index < inputDeviceCount)) {
166 return inputDevices[index];
167 } else if ((!iscapture) && (index < outputDeviceCount)) {
168 return outputDevices[index];
169 }
170
171 SDL_SetError("No such device");
121 return NULL; 172 return NULL;
122 } 173 }
123 174
124 175
125 static int 176 static int
126 DSP_OpenDevice(_THIS, const char *devname, int iscapture) 177 DSP_OpenDevice(_THIS, const char *devname, int iscapture)
127 { 178 {
128 char dev[1024]; 179 const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
129 int format; 180 int format;
130 int value; 181 int value;
131 int frag_spec; 182 int frag_spec;
132 SDL_AudioFormat test_format; 183 SDL_AudioFormat test_format;
184
185 /* We don't care what the devname is...we'll try to open anything. */
186 /* ...but default to first name in the list... */
187 if (devname == NULL) {
188 if ( ((iscapture) && (inputDeviceCount == 0)) ||
189 ((!iscapture) && (outputDeviceCount == 0)) ) {
190 SDL_SetError("No such audio device");
191 return 0;
192 }
193 devname = ((iscapture) ? inputDevices[0] : outputDevices[0]);
194 }
133 195
134 /* Initialize all variables that we clean on shutdown */ 196 /* Initialize all variables that we clean on shutdown */
135 this->hidden = (struct SDL_PrivateAudioData *) 197 this->hidden = (struct SDL_PrivateAudioData *)
136 SDL_malloc((sizeof *this->hidden)); 198 SDL_malloc((sizeof *this->hidden));
137 if (this->hidden == NULL) { 199 if (this->hidden == NULL) {
139 return 0; 201 return 0;
140 } 202 }
141 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); 203 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
142 this->hidden->audio_fd = -1; 204 this->hidden->audio_fd = -1;
143 205
144 /* !!! FIXME: handle devname */
145 /* !!! FIXME: handle iscapture */
146
147 /* Open the audio device */ 206 /* Open the audio device */
148 this->hidden->audio_fd = SDL_OpenAudioPath(dev, sizeof(dev), OPEN_FLAGS, 0); 207 this->hidden->audio_fd = open(devname, flags, 0);
149 if (this->hidden->audio_fd < 0) { 208 if (this->hidden->audio_fd < 0) {
150 SDL_SetError("Couldn't open %s: %s", dev, strerror(errno)); 209 SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
151 return 0; 210 return 0;
152 } 211 }
153 this->hidden->mixbuf = NULL; 212 this->hidden->mixbuf = NULL;
154 213
155 /* Make the file descriptor use blocking writes with fcntl() */ 214 /* Make the file descriptor use blocking writes with fcntl() */
304 /* We're ready to rock and roll. :-) */ 363 /* We're ready to rock and roll. :-) */
305 return 1; 364 return 1;
306 } 365 }
307 366
308 367
309 /* This function waits until it is possible to write a full sound buffer */
310 static void
311 DSP_WaitDevice(_THIS)
312 {
313 /* Not needed at all since OSS handles waiting automagically */
314 }
315
316
317 static void 368 static void
318 DSP_PlayDevice(_THIS) 369 DSP_PlayDevice(_THIS)
319 { 370 {
320 const Uint8 *mixbuf = this->hidden->mixbuf; 371 const Uint8 *mixbuf = this->hidden->mixbuf;
321 const int mixlen = this->hidden->mixlen; 372 const int mixlen = this->hidden->mixlen;