Rev 9288 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 9288 | Rev 9789 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | #include "SDL_audio.h" |
1 | #include "SDL_audio.h" |
2 | #include |
2 | #include |
3 | #include |
3 | #include |
4 | #include |
4 | #include |
5 | #include |
5 | #include |
6 | #include |
6 | #include |
7 | #include |
7 | #include |
Line 8... | Line -... | ||
8 | - | ||
9 | static void GetNotify(__u32* event) |
- | |
10 | { |
- | |
11 | __asm__("int $0x40" :: "a"(68),"b"(14),"c"(event)); |
- | |
12 | } |
8 | |
13 | static int CreateThread(void* fn, char* p_stack) |
- | |
14 | { |
- | |
15 | int res; |
- | |
16 | __asm__("int $0x40" : "=a"(res) : "a"(51),"b"(1),"c"(fn),"d"(p_stack)); |
- | |
17 | return res; |
9 | extern void SDL_printf(const char * fmt,...); |
18 | } |
- | |
19 | static char pinfo[1024]; |
10 | |
20 | static int GetProcessInfo(int slot) |
- | |
21 | { |
- | |
22 | int res; |
- | |
23 | __asm__("int $0x40" : "=a"(res) : "a"(9),"b"(pinfo),"c"(slot)); |
- | |
24 | return res; |
- | |
25 | } |
- | |
26 | static void ActivateWnd(int slot) |
- | |
27 | { |
- | |
28 | __asm__("int $0x40" :: "a"(18),"b"(3),"c"(slot)); |
- | |
29 | } |
- | |
30 | static void Yield(void) |
- | |
31 | { |
- | |
32 | __asm__("int $0x40" :: "a"(68),"b"(1)); |
- | |
Line -... | Line 11... | ||
- | 11 | #define AUDIO_THREAD_STACK_SIZE 40960 |
|
33 | } |
12 | |
34 | 13 | static ksys_thread_t thread_info; |
|
35 | static int bInitialized=0; |
14 | static int bInitialized = 0; |
36 | static SNDBUF hBuff=0; |
15 | static SNDBUF hBuff = 0; |
37 | static char* data=NULL; |
16 | static uint8_t* data = NULL; |
38 | static int audio_tid=0; |
17 | static int audio_tid = 0; |
39 | static int main_slot; |
18 | static int main_slot; |
40 | static __u32 main_tid; |
19 | static uint32_t main_tid; |
41 | static char audio_thread_stack[40960]; |
20 | static char audio_thread_stack[AUDIO_THREAD_STACK_SIZE]; |
Line 42... | Line 21... | ||
42 | static __u32 used_format=0; |
21 | static uint32_t used_format = 0; |
43 | static volatile int mix_size=0; |
22 | static int mix_size = 0; |
Line 44... | Line 23... | ||
44 | 23 | ||
45 | static void (*callback)(void* userdata, Uint8* stream, int len); |
24 | static void (*callback)(void* userdata, Uint8* stream, int len); |
46 | static void* userdata; |
25 | static void* userdata; |
47 | - | ||
48 | int SDL_AudioInit(const char* driver_name) |
26 | |
49 | { |
27 | int SDL_AudioInit(const char* driver_name) |
50 | if (bInitialized) |
28 | { |
51 | { |
29 | if (bInitialized) { |
52 | SDL_SetError("audio already initialized"); |
30 | SDL_SetError("Audio already initialized"); |
53 | return -1; |
- | |
54 | } |
31 | return -1; |
55 | int ver; |
32 | } |
56 | if (InitSound(&ver)) |
33 | int ver; |
57 | { |
34 | if (InitSound(&ver)) { |
58 | SDL_printf("Warning: cannot load drivers, sound output will be disabled\n"); |
35 | SDL_printf("Warning: cannot load drivers, sound output will be disabled\n"); |
59 | return 0; |
36 | return 0; |
Line 60... | Line 37... | ||
60 | } |
37 | } |
61 | bInitialized = 1; |
- | |
62 | return 0; |
- | |
Line 63... | Line 38... | ||
63 | } |
38 | bInitialized = 1; |
64 | 39 | return 0; |
|
65 | void SDL_AudioQuit(void) |
40 | } |
66 | { |
41 | |
Line 75... | Line 50... | ||
75 | } |
50 | } |
Line 76... | Line 51... | ||
76 | 51 | ||
77 | #define AUDIO_SUSPEND 1 |
52 | #define AUDIO_SUSPEND 1 |
78 | #define AUDIO_RESUME 2 |
53 | #define AUDIO_RESUME 2 |
- | 54 | #define AUDIO_DIE 3 |
|
79 | #define AUDIO_DIE 3 |
55 | |
- | 56 | static volatile int audio_command=0, audio_response=0, bLocked=0, bInCallback=0; |
|
80 | static volatile int audio_command=0,audio_response=0,bLocked=0,bInCallback=0; |
57 | |
81 | static void audio_thread(void) |
58 | static void audio_thread(void) |
82 | { |
59 | { |
83 | SDL_printf("audio_thread created\n"); |
60 | SDL_printf("Audio_thread created\n"); |
84 | int bPaused; |
61 | int bPaused; |
85 | __u32 event[6]; |
62 | ksys_signal_info_t snd_signal; |
86 | // initialize |
63 | // initialize |
87 | if (CreateBuffer(used_format|PCM_RING, 0, &hBuff)) |
- | |
88 | { |
64 | if (CreateBuffer(used_format|PCM_RING, 0, &hBuff)) { |
89 | audio_response=1; |
65 | audio_response=1; |
90 | exit(0); |
66 | exit(0); |
- | 67 | } |
|
91 | } |
68 | |
92 | GetBufferSize(hBuff, &mix_size); |
69 | GetBufferSize(hBuff, &mix_size); |
93 | SDL_printf("buffer created, size is %d\n",mix_size); |
70 | SDL_printf("buffer created, size is %d\n", mix_size); |
94 | mix_size >>= 1; |
71 | mix_size >>= 1; |
95 | data = malloc(mix_size); |
72 | data = malloc(mix_size); |
96 | audio_response=1; |
73 | audio_response = 1; |
- | 74 | if (!data) exit(0); |
|
97 | if (!data) exit(0); |
75 | |
98 | // wait for resume |
76 | // wait for resume |
99 | while (audio_command!=AUDIO_RESUME) |
77 | while (audio_command != AUDIO_RESUME) |
100 | Yield(); |
- | |
101 | // initialize |
- | |
102 | /* bInCallback=1; |
- | |
103 | callback(userdata,data,mix_size); |
- | |
104 | SetBuffer(hBuff,data,0,mix_size); |
- | |
105 | callback(userdata,data,mix_size); |
- | |
106 | SetBuffer(hBuff,data,mix_size,mix_size); |
- | |
107 | bInCallback=0;*/ |
78 | _ksys_thread_yield(); |
108 | audio_command=0; |
79 | audio_command = 0; |
109 | bPaused=0; |
80 | bPaused = 0; |
110 | audio_response=1; |
81 | audio_response = 1; |
- | 82 | PlayBuffer(hBuff, 0); |
|
111 | PlayBuffer(hBuff,0); |
83 | |
112 | // main loop |
- | |
113 | for (;;) |
84 | // main loop |
114 | { |
85 | while(1) { |
115 | if (audio_command==AUDIO_RESUME) |
- | |
116 | { |
86 | if (audio_command == AUDIO_RESUME) { |
117 | PlayBuffer(hBuff,0); |
87 | PlayBuffer(hBuff, 0); |
118 | audio_command = 0; |
88 | audio_command = 0; |
119 | bPaused = 0; |
89 | bPaused = 0; |
120 | audio_response = 1; |
- | |
121 | } |
90 | audio_response = 1; |
122 | else if (audio_command==AUDIO_SUSPEND) |
- | |
123 | { |
91 | } else if (audio_command == AUDIO_SUSPEND) { |
124 | StopBuffer(hBuff); |
92 | StopBuffer(hBuff); |
125 | audio_command = 0; |
93 | audio_command = 0; |
126 | bPaused = 1; |
94 | bPaused = 1; |
127 | audio_response = 1; |
- | |
128 | } |
95 | audio_response = 1; |
129 | else if (audio_command==AUDIO_DIE) |
- | |
130 | { |
96 | }else if (audio_command == AUDIO_DIE) { |
131 | audio_response = 1; |
97 | audio_response = 1; |
132 | StopBuffer(hBuff); |
98 | StopBuffer(hBuff); |
133 | DestroyBuffer(hBuff); |
99 | DestroyBuffer(hBuff); |
134 | exit(0); |
- | |
135 | } |
- | |
136 | else |
100 | exit(0); |
137 | { |
101 | } else { |
138 | GetProcessInfo(main_slot); |
102 | _ksys_thread_info(&thread_info, main_slot); |
139 | if (pinfo[0x32]==9 || *(__u32*)(pinfo+0x1E)!=main_tid) |
- | |
140 | { |
103 | if (thread_info.slot_state == KSYS_SLOT_STATE_FREE || thread_info.pid !=main_tid) { |
141 | audio_command = AUDIO_DIE; |
104 | audio_command = AUDIO_DIE; |
142 | continue; |
105 | continue; |
143 | } |
106 | } |
144 | } |
107 | } |
145 | if (bPaused) |
108 | if (bPaused) { |
146 | delay(5); |
- | |
147 | else |
109 | _ksys_delay(5); |
148 | { |
110 | } else { |
149 | GetNotify(event); |
111 | _ksys_wait_signal(&snd_signal); |
150 | if (event[0] != 0xFF000001) |
112 | if (snd_signal.id != 0xFF000001) |
151 | continue; |
113 | continue; |
152 | while (bLocked) |
114 | while (bLocked) |
- | 115 | _ksys_thread_yield(); |
|
153 | Yield(); |
116 | |
154 | bInCallback=1; |
117 | bInCallback=1; |
155 | callback(userdata,data,mix_size); |
118 | callback(userdata, data, mix_size); |
156 | bInCallback=0; |
119 | bInCallback=0; |
157 | SetBuffer(hBuff,data,event[3],mix_size); |
120 | SetBuffer(hBuff, data, ((int*)snd_signal.data)[2], mix_size); |
158 | } |
121 | } |
159 | } |
122 | } |
Line 160... | Line 123... | ||
160 | } |
123 | } |
161 | 124 | ||
162 | int SDL_OpenAudio(SDL_AudioSpec* desired, SDL_AudioSpec* obtained) |
125 | int SDL_OpenAudio(SDL_AudioSpec* desired, SDL_AudioSpec* obtained) |
163 | { |
- | |
164 | if (!bInitialized) |
126 | { |
165 | { |
127 | if (!bInitialized) { |
166 | SDL_SetError("Audio device was not initialized"); |
128 | SDL_SetError("Audio device was not initialized"); |
- | 129 | return -1; |
|
167 | return -1; |
130 | } |
168 | } |
- | |
169 | if (!obtained) |
131 | |
170 | { |
132 | if (!obtained) { |
171 | SDL_SetError("Audio format: software emulation is not supported"); |
133 | SDL_SetError("Audio format: software emulation is not supported"); |
- | 134 | return -1; |
|
172 | return -1; |
135 | } |
173 | } |
- | |
174 | if (used_format) |
136 | |
175 | { |
137 | if (used_format) { |
176 | SDL_SetError("Audio device was already opened"); |
138 | SDL_SetError("Audio device was already opened"); |
177 | return -1; |
139 | return -1; |
178 | } |
140 | } |
179 | memcpy(obtained,desired,sizeof(SDL_AudioSpec)); |
- | |
Line 180... | Line 141... | ||
180 | switch (desired->freq) |
141 | memcpy(obtained, desired, sizeof(SDL_AudioSpec)); |
181 | { |
142 | switch (desired->freq) { |
182 | 143 | ||
183 | #define HANDLE_FREQ(freq,symb) \ |
144 | #define HANDLE_FREQ(freq,symb) \ |
Line 221... | Line 182... | ||
221 | HANDLE_FREQ(16000,16); |
182 | HANDLE_FREQ(16000,16); |
222 | HANDLE_FREQ(12000,12); |
183 | HANDLE_FREQ(12000,12); |
223 | HANDLE_FREQ(11025,11); |
184 | HANDLE_FREQ(11025,11); |
224 | HANDLE_FREQ(8000,8); |
185 | HANDLE_FREQ(8000,8); |
225 | } |
186 | } |
- | 187 | ||
226 | if (!used_format) |
188 | if (!used_format) { |
227 | { |
- | |
228 | SDL_SetError("Unknown audio format"); |
189 | SDL_SetError("Unknown audio format"); |
229 | return -1; |
190 | return -1; |
230 | } |
191 | } |
- | 192 | ||
231 | callback=desired->callback; |
193 | callback = desired->callback; |
232 | userdata=desired->userdata; |
194 | userdata = desired->userdata; |
- | 195 | ||
233 | GetProcessInfo(-1); |
196 | _ksys_thread_info(&thread_info, KSYS_THIS_SLOT); |
234 | main_tid = *(__u32*)(pinfo+0x1E); |
197 | main_tid = thread_info.pid; |
235 | for (main_slot=0;;main_slot++) |
198 | for (main_slot=0 ;; main_slot++) { |
236 | { |
- | |
237 | GetProcessInfo(main_slot); |
199 | _ksys_thread_info(&thread_info, main_slot); |
238 | if (pinfo[0x32]!=9 && *(__u32*)(pinfo+0x1E)==main_tid) |
200 | if (thread_info.slot_state != KSYS_SLOT_STATE_FREE && thread_info.pid == main_tid) |
239 | break; |
201 | break; |
240 | } |
202 | } |
241 | audio_tid=CreateThread(audio_thread,audio_thread_stack+40960); |
203 | audio_tid = _ksys_create_thread(audio_thread, audio_thread_stack+AUDIO_THREAD_STACK_SIZE); |
242 | if (audio_tid<0) |
204 | if (audio_tid < 0) { |
243 | { |
- | |
244 | SDL_SetError("Cannot create audio thread"); |
205 | SDL_SetError("Cannot create audio thread"); |
245 | return -1; |
206 | return -1; |
246 | } |
207 | } |
- | 208 | ||
247 | ActivateWnd(main_slot); |
209 | _ksys_focus_window(main_slot); |
248 | while (!audio_response) |
210 | while (!audio_response) |
249 | Yield(); |
211 | _ksys_thread_yield(); |
- | 212 | ||
250 | if (!hBuff) |
213 | if (!hBuff) { |
251 | { |
- | |
252 | SDL_SetError("Cannot create audio buffer"); |
214 | SDL_SetError("Cannot create audio buffer"); |
253 | return -1; |
215 | return -1; |
254 | } |
216 | } |
255 | if (!data) |
217 | if (!data){ |
256 | { |
- | |
257 | SDL_SetError("Cannot allocate audio buffer"); |
218 | SDL_SetError("Cannot allocate audio buffer"); |
258 | return -1; |
219 | return -1; |
259 | } |
220 | } |
260 | obtained->silence = (desired->format == AUDIO_U8 ? 0x80 : 0); |
221 | obtained->silence = (desired->format == AUDIO_U8 ? 0x80 : 0); |
261 | obtained->size = mix_size; |
222 | obtained->size = mix_size; |
262 | obtained->samples = obtained->size / obtained->channels; |
223 | obtained->samples = obtained->size / obtained->channels; |
- | 224 | ||
263 | if (desired->format == AUDIO_U16SYS || desired->format == AUDIO_S16SYS) |
225 | if (desired->format == AUDIO_U16SYS || desired->format == AUDIO_S16SYS) |
264 | obtained->samples /= 2; |
226 | obtained->samples /= 2; |
- | 227 | ||
265 | SDL_printf("obtained size is %d, samples %d\n",obtained->size, |
228 | SDL_printf("obtained size is %d, samples %d\n", obtained->size, obtained->samples); |
266 | obtained->samples); |
- | |
267 | return 0; |
229 | return 0; |
268 | } |
230 | } |
269 | void SDL_CloseAudio(void) |
231 | void SDL_CloseAudio(void) |
270 | { |
232 | { |
271 | if (!audio_tid) return; |
233 | if (!audio_tid) return; |
272 | audio_response = 0; |
234 | audio_response = 0; |
273 | audio_command = AUDIO_DIE; |
235 | audio_command = AUDIO_DIE; |
274 | while (!audio_response) |
236 | while (!audio_response) _ksys_thread_yield(); |
275 | Yield(); |
- | |
276 | free(data); |
237 | free(data); |
277 | used_format = 0; |
238 | used_format = 0; |
278 | } |
239 | } |
Line 279... | Line 240... | ||
279 | 240 | ||
280 | void SDL_PauseAudio(int pause_on) |
241 | void SDL_PauseAudio(int pause_on) |
281 | { |
242 | { |
282 | if (!audio_tid) return; |
243 | if (!audio_tid) return; |
283 | audio_response = 0; |
244 | audio_response = 0; |
284 | audio_command = pause_on?AUDIO_SUSPEND:AUDIO_RESUME; |
245 | audio_command = pause_on ? AUDIO_SUSPEND : AUDIO_RESUME; |
285 | while (!audio_response) |
- | |
286 | Yield(); |
246 | while (!audio_response) _ksys_thread_yield(); |
287 | } |
247 | } |
288 | void SDL_LockAudio(void) |
248 | void SDL_LockAudio(void) |
289 | { |
249 | { |
290 | if (!audio_tid) return; |
250 | if (!audio_tid) return; |
291 | bLocked = 1; |
251 | bLocked = 1; |
292 | while (bInCallback) |
- | |
293 | Yield(); |
252 | while (bInCallback) _ksys_thread_yield(); |
294 | } |
253 | } |
295 | void SDL_UnlockAudio(void) |
254 | void SDL_UnlockAudio(void) |
296 | { |
255 | { |
297 | bLocked = 0; |
256 | bLocked = 0; |