Subversion Repositories Kolibri OS

Rev

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;