comparison src/audio/disk/SDL_diskaudio.c @ 1465:8dfa9a6d69a5

Updated WinCE support by Dmitry (with some tweaks) Converted the disk audio driver to SDL_RWops for portability
author Sam Lantinga <slouken@libsdl.org>
date Sat, 04 Mar 2006 08:24:35 +0000
parents d910939febfa
children 84535f702874
comparison
equal deleted inserted replaced
1464:af30090c0330 1465:8dfa9a6d69a5
24 */ 24 */
25 #include "SDL_config.h" 25 #include "SDL_config.h"
26 26
27 /* Output raw audio data to a file. */ 27 /* Output raw audio data to a file. */
28 28
29 #if HAVE_STDIO_H
29 #include <stdio.h> 30 #include <stdio.h>
30 #include <string.h> /* For strerror() */ 31 #endif
31 #include <errno.h>
32 #include <unistd.h>
33 #include <sys/stat.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37 32
38 33 #include "SDL_rwops.h"
39 #include "SDL_timer.h" 34 #include "SDL_timer.h"
40 #include "SDL_audio.h" 35 #include "SDL_audio.h"
41 #include "../SDL_audiomem.h" 36 #include "../SDL_audiomem.h"
42 #include "../SDL_audio_c.h" 37 #include "../SDL_audio_c.h"
43 #include "../SDL_audiodev_c.h" 38 #include "../SDL_audiodev_c.h"
59 static Uint8 *DISKAUD_GetAudioBuf(_THIS); 54 static Uint8 *DISKAUD_GetAudioBuf(_THIS);
60 static void DISKAUD_CloseAudio(_THIS); 55 static void DISKAUD_CloseAudio(_THIS);
61 56
62 static const char *DISKAUD_GetOutputFilename(void) 57 static const char *DISKAUD_GetOutputFilename(void)
63 { 58 {
64 const char *envr = SDL_getenv(DISKENVR_OUTFILE); 59 const char *envr = SDL_getenv(DISKENVR_OUTFILE);
65 return((envr != NULL) ? envr : DISKDEFAULT_OUTFILE); 60 return((envr != NULL) ? envr : DISKDEFAULT_OUTFILE);
66 } 61 }
67 62
68 /* Audio driver bootstrap functions */ 63 /* Audio driver bootstrap functions */
69 static int DISKAUD_Available(void) 64 static int DISKAUD_Available(void)
70 { 65 {
71 #if 0
72 int fd;
73 int available;
74 int exists = 0;
75 struct stat statbuf;
76 const char *fname = DISKAUD_GetOutputFilename();
77 const char *envr = SDL_getenv("SDL_AUDIODRIVER"); 66 const char *envr = SDL_getenv("SDL_AUDIODRIVER");
78 available = 0; 67 if (envr && (SDL_strcmp(envr, DISKAUD_DRIVER_NAME) == 0)) {
79
80 if ((envr) && (SDL_strcmp(envr, DISKAUD_DRIVER_NAME) == 0)) {
81 if (stat(fname, &statbuf) == 0)
82 exists = 1;
83
84 fd = open(fname, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR);
85 if ( fd != -1 ) {
86 available = 1;
87 close(fd);
88 if (!exists) {
89 unlink(fname);
90 }
91 }
92 }
93 return(available);
94 #else
95 const char *envr = SDL_getenv("SDL_AUDIODRIVER");
96 if ((envr) && (SDL_strcmp(envr, DISKAUD_DRIVER_NAME) == 0)) {
97 return(1); 68 return(1);
98 } 69 }
99
100 return(0); 70 return(0);
101 #endif
102 } 71 }
103 72
104 static void DISKAUD_DeleteDevice(SDL_AudioDevice *device) 73 static void DISKAUD_DeleteDevice(SDL_AudioDevice *device)
105 { 74 {
106 SDL_free(device->hidden); 75 SDL_free(device->hidden);
108 } 77 }
109 78
110 static SDL_AudioDevice *DISKAUD_CreateDevice(int devindex) 79 static SDL_AudioDevice *DISKAUD_CreateDevice(int devindex)
111 { 80 {
112 SDL_AudioDevice *this; 81 SDL_AudioDevice *this;
113 const char *envr; 82 const char *envr;
114 83
115 /* Initialize all variables that we clean on shutdown */ 84 /* Initialize all variables that we clean on shutdown */
116 this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); 85 this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice));
117 if ( this ) { 86 if ( this ) {
118 SDL_memset(this, 0, (sizeof *this)); 87 SDL_memset(this, 0, (sizeof *this));
126 } 95 }
127 return(0); 96 return(0);
128 } 97 }
129 SDL_memset(this->hidden, 0, (sizeof *this->hidden)); 98 SDL_memset(this->hidden, 0, (sizeof *this->hidden));
130 99
131 envr = SDL_getenv(DISKENVR_WRITEDELAY); 100 envr = SDL_getenv(DISKENVR_WRITEDELAY);
132 this->hidden->write_delay = (envr) ? SDL_atoi(envr) : DISKDEFAULT_WRITEDELAY; 101 this->hidden->write_delay = (envr) ? SDL_atoi(envr) : DISKDEFAULT_WRITEDELAY;
133 102
134 /* Set the function pointers */ 103 /* Set the function pointers */
135 this->OpenAudio = DISKAUD_OpenAudio; 104 this->OpenAudio = DISKAUD_OpenAudio;
136 this->WaitAudio = DISKAUD_WaitAudio; 105 this->WaitAudio = DISKAUD_WaitAudio;
137 this->PlayAudio = DISKAUD_PlayAudio; 106 this->PlayAudio = DISKAUD_PlayAudio;
149 }; 118 };
150 119
151 /* This function waits until it is possible to write a full sound buffer */ 120 /* This function waits until it is possible to write a full sound buffer */
152 static void DISKAUD_WaitAudio(_THIS) 121 static void DISKAUD_WaitAudio(_THIS)
153 { 122 {
154 SDL_Delay(this->hidden->write_delay); 123 SDL_Delay(this->hidden->write_delay);
155 } 124 }
156 125
157 static void DISKAUD_PlayAudio(_THIS) 126 static void DISKAUD_PlayAudio(_THIS)
158 { 127 {
159 int written; 128 int written;
160 129
161 /* Write the audio data, checking for EAGAIN on broken audio drivers */ 130 /* Write the audio data */
162 do { 131 written = SDL_RWwrite(this->hidden->output,
163 written = write(this->hidden->audio_fd, 132 this->hidden->mixbuf, 1,
164 this->hidden->mixbuf,
165 this->hidden->mixlen); 133 this->hidden->mixlen);
166 if ( (written < 0) && ((errno == 0) || (errno == EAGAIN)) ) {
167 SDL_Delay(1); /* Let a little CPU time go by */
168 }
169 } while ( (written < 0) &&
170 ((errno == 0) || (errno == EAGAIN) || (errno == EINTR)) );
171 134
172 /* If we couldn't write, assume fatal error for now */ 135 /* If we couldn't write, assume fatal error for now */
173 if ( written < 0 ) { 136 if ( written != this->hidden->mixlen ) {
174 this->enabled = 0; 137 this->enabled = 0;
175 } 138 }
176 #ifdef DEBUG_AUDIO 139 #ifdef DEBUG_AUDIO
177 fprintf(stderr, "Wrote %d bytes of audio data\n", written); 140 fprintf(stderr, "Wrote %d bytes of audio data\n", written);
178 #endif 141 #endif
187 { 150 {
188 if ( this->hidden->mixbuf != NULL ) { 151 if ( this->hidden->mixbuf != NULL ) {
189 SDL_FreeAudioMem(this->hidden->mixbuf); 152 SDL_FreeAudioMem(this->hidden->mixbuf);
190 this->hidden->mixbuf = NULL; 153 this->hidden->mixbuf = NULL;
191 } 154 }
192 if ( this->hidden->audio_fd >= 0 ) { 155 if ( this->hidden->output != NULL ) {
193 close(this->hidden->audio_fd); 156 SDL_RWclose(this->hidden->output);
194 this->hidden->audio_fd = -1; 157 this->hidden->output = NULL;
195 } 158 }
196 } 159 }
197 160
198 static int DISKAUD_OpenAudio(_THIS, SDL_AudioSpec *spec) 161 static int DISKAUD_OpenAudio(_THIS, SDL_AudioSpec *spec)
199 { 162 {
200 const char *fname = DISKAUD_GetOutputFilename(); 163 const char *fname = DISKAUD_GetOutputFilename();
201 164
202 /* Open the audio device */ 165 /* Open the audio device */
203 this->hidden->audio_fd = open(fname, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); 166 this->hidden->output = SDL_RWFromFile(fname, "wb");
204 if ( this->hidden->audio_fd < 0 ) { 167 if ( this->hidden->output == NULL ) {
205 SDL_SetError("Couldn't open %s: %s", fname, strerror(errno));
206 return(-1); 168 return(-1);
207 } 169 }
208 170
209 fprintf(stderr, "WARNING: You are using the SDL disk writer" 171 #if HAVE_STDIO_H
172 fprintf(stderr, "WARNING: You are using the SDL disk writer"
210 " audio driver!\n Writing to file [%s].\n", fname); 173 " audio driver!\n Writing to file [%s].\n", fname);
174 #endif
211 175
212 /* Allocate mixing buffer */ 176 /* Allocate mixing buffer */
213 this->hidden->mixlen = spec->size; 177 this->hidden->mixlen = spec->size;
214 this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen); 178 this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
215 if ( this->hidden->mixbuf == NULL ) { 179 if ( this->hidden->mixbuf == NULL ) {