1,46 → 1,25 |
#include "SDL_audio.h" |
#include <kos32sys.h> |
#include <menuet/os.h> |
#include <stdint.h> |
#include <sys/ksys.h> |
#include <stdlib.h> |
#include <string.h> |
#include <sound.h> |
#include <stdio.h> |
|
static void GetNotify(__u32* event) |
{ |
__asm__("int $0x40" :: "a"(68),"b"(14),"c"(event)); |
} |
static int CreateThread(void* fn, char* p_stack) |
{ |
int res; |
__asm__("int $0x40" : "=a"(res) : "a"(51),"b"(1),"c"(fn),"d"(p_stack)); |
return res; |
} |
static char pinfo[1024]; |
static int GetProcessInfo(int slot) |
{ |
int res; |
__asm__("int $0x40" : "=a"(res) : "a"(9),"b"(pinfo),"c"(slot)); |
return res; |
} |
static void ActivateWnd(int slot) |
{ |
__asm__("int $0x40" :: "a"(18),"b"(3),"c"(slot)); |
} |
static void Yield(void) |
{ |
__asm__("int $0x40" :: "a"(68),"b"(1)); |
} |
extern void SDL_printf(const char * fmt,...); |
|
#define AUDIO_THREAD_STACK_SIZE 40960 |
|
static ksys_thread_t thread_info; |
static int bInitialized=0; |
static SNDBUF hBuff=0; |
static char* data=NULL; |
static uint8_t* data = NULL; |
static int audio_tid=0; |
static int main_slot; |
static __u32 main_tid; |
static char audio_thread_stack[40960]; |
static __u32 used_format=0; |
static volatile int mix_size=0; |
static uint32_t main_tid; |
static char audio_thread_stack[AUDIO_THREAD_STACK_SIZE]; |
static uint32_t used_format = 0; |
static int mix_size = 0; |
|
static void (*callback)(void* userdata, Uint8* stream, int len); |
static void* userdata; |
47,14 → 26,12 |
|
int SDL_AudioInit(const char* driver_name) |
{ |
if (bInitialized) |
{ |
SDL_SetError("audio already initialized"); |
if (bInitialized) { |
SDL_SetError("Audio already initialized"); |
return -1; |
} |
int ver; |
if (InitSound(&ver)) |
{ |
if (InitSound(&ver)) { |
SDL_printf("Warning: cannot load drivers, sound output will be disabled\n"); |
return 0; |
} |
62,9 → 39,7 |
return 0; |
} |
|
void SDL_AudioQuit(void) |
{ |
} |
void SDL_AudioQuit(void) {/*STUB*/} |
|
char* SDL_AudioDriverName(char* namebuf, int maxlen) |
{ |
77,18 → 52,20 |
#define AUDIO_SUSPEND 1 |
#define AUDIO_RESUME 2 |
#define AUDIO_DIE 3 |
|
static volatile int audio_command=0,audio_response=0,bLocked=0,bInCallback=0; |
|
static void audio_thread(void) |
{ |
SDL_printf("audio_thread created\n"); |
SDL_printf("Audio_thread created\n"); |
int bPaused; |
__u32 event[6]; |
ksys_signal_info_t snd_signal; |
// initialize |
if (CreateBuffer(used_format|PCM_RING, 0, &hBuff)) |
{ |
if (CreateBuffer(used_format|PCM_RING, 0, &hBuff)) { |
audio_response=1; |
exit(0); |
} |
|
GetBufferSize(hBuff, &mix_size); |
SDL_printf("buffer created, size is %d\n",mix_size); |
mix_size >>= 1; |
95,66 → 72,52 |
data = malloc(mix_size); |
audio_response=1; |
if (!data) exit(0); |
|
// wait for resume |
while (audio_command!=AUDIO_RESUME) |
Yield(); |
// initialize |
/* bInCallback=1; |
callback(userdata,data,mix_size); |
SetBuffer(hBuff,data,0,mix_size); |
callback(userdata,data,mix_size); |
SetBuffer(hBuff,data,mix_size,mix_size); |
bInCallback=0;*/ |
_ksys_thread_yield(); |
audio_command=0; |
bPaused=0; |
audio_response=1; |
PlayBuffer(hBuff,0); |
|
// main loop |
for (;;) |
{ |
if (audio_command==AUDIO_RESUME) |
{ |
while(1) { |
if (audio_command == AUDIO_RESUME) { |
PlayBuffer(hBuff,0); |
audio_command = 0; |
bPaused = 0; |
audio_response = 1; |
} |
else if (audio_command==AUDIO_SUSPEND) |
{ |
} else if (audio_command == AUDIO_SUSPEND) { |
StopBuffer(hBuff); |
audio_command = 0; |
bPaused = 1; |
audio_response = 1; |
} |
else if (audio_command==AUDIO_DIE) |
{ |
}else if (audio_command == AUDIO_DIE) { |
audio_response = 1; |
StopBuffer(hBuff); |
DestroyBuffer(hBuff); |
exit(0); |
} |
else |
{ |
GetProcessInfo(main_slot); |
if (pinfo[0x32]==9 || *(__u32*)(pinfo+0x1E)!=main_tid) |
{ |
} else { |
_ksys_thread_info(&thread_info, main_slot); |
if (thread_info.slot_state == KSYS_SLOT_STATE_FREE || thread_info.pid !=main_tid) { |
audio_command = AUDIO_DIE; |
continue; |
} |
} |
if (bPaused) |
delay(5); |
else |
{ |
GetNotify(event); |
if (event[0] != 0xFF000001) |
if (bPaused) { |
_ksys_delay(5); |
} else { |
_ksys_wait_signal(&snd_signal); |
if (snd_signal.id != 0xFF000001) |
continue; |
while (bLocked) |
Yield(); |
_ksys_thread_yield(); |
|
bInCallback=1; |
callback(userdata,data,mix_size); |
bInCallback=0; |
SetBuffer(hBuff,data,event[3],mix_size); |
SetBuffer(hBuff, data, ((int*)snd_signal.data)[2], mix_size); |
} |
} |
} |
161,24 → 124,22 |
|
int SDL_OpenAudio(SDL_AudioSpec* desired, SDL_AudioSpec* obtained) |
{ |
if (!bInitialized) |
{ |
if (!bInitialized) { |
SDL_SetError("Audio device was not initialized"); |
return -1; |
} |
if (!obtained) |
{ |
|
if (!obtained) { |
SDL_SetError("Audio format: software emulation is not supported"); |
return -1; |
} |
if (used_format) |
{ |
|
if (used_format) { |
SDL_SetError("Audio device was already opened"); |
return -1; |
} |
memcpy(obtained,desired,sizeof(SDL_AudioSpec)); |
switch (desired->freq) |
{ |
switch (desired->freq) { |
|
#define HANDLE_FREQ(freq,symb) \ |
case freq: \ |
223,37 → 184,37 |
HANDLE_FREQ(11025,11); |
HANDLE_FREQ(8000,8); |
} |
if (!used_format) |
{ |
|
if (!used_format) { |
SDL_SetError("Unknown audio format"); |
return -1; |
} |
|
callback=desired->callback; |
userdata=desired->userdata; |
GetProcessInfo(-1); |
main_tid = *(__u32*)(pinfo+0x1E); |
for (main_slot=0;;main_slot++) |
{ |
GetProcessInfo(main_slot); |
if (pinfo[0x32]!=9 && *(__u32*)(pinfo+0x1E)==main_tid) |
|
_ksys_thread_info(&thread_info, KSYS_THIS_SLOT); |
main_tid = thread_info.pid; |
for (main_slot=0 ;; main_slot++) { |
_ksys_thread_info(&thread_info, main_slot); |
if (thread_info.slot_state != KSYS_SLOT_STATE_FREE && thread_info.pid == main_tid) |
break; |
} |
audio_tid=CreateThread(audio_thread,audio_thread_stack+40960); |
if (audio_tid<0) |
{ |
audio_tid = _ksys_create_thread(audio_thread, audio_thread_stack+AUDIO_THREAD_STACK_SIZE); |
if (audio_tid < 0) { |
SDL_SetError("Cannot create audio thread"); |
return -1; |
} |
ActivateWnd(main_slot); |
|
_ksys_focus_window(main_slot); |
while (!audio_response) |
Yield(); |
if (!hBuff) |
{ |
_ksys_thread_yield(); |
|
if (!hBuff) { |
SDL_SetError("Cannot create audio buffer"); |
return -1; |
} |
if (!data) |
{ |
if (!data){ |
SDL_SetError("Cannot allocate audio buffer"); |
return -1; |
} |
260,10 → 221,11 |
obtained->silence = (desired->format == AUDIO_U8 ? 0x80 : 0); |
obtained->size = mix_size; |
obtained->samples = obtained->size / obtained->channels; |
|
if (desired->format == AUDIO_U16SYS || desired->format == AUDIO_S16SYS) |
obtained->samples /= 2; |
SDL_printf("obtained size is %d, samples %d\n",obtained->size, |
obtained->samples); |
|
SDL_printf("obtained size is %d, samples %d\n", obtained->size, obtained->samples); |
return 0; |
} |
void SDL_CloseAudio(void) |
271,8 → 233,7 |
if (!audio_tid) return; |
audio_response = 0; |
audio_command = AUDIO_DIE; |
while (!audio_response) |
Yield(); |
while (!audio_response) _ksys_thread_yield(); |
free(data); |
used_format = 0; |
} |
282,15 → 243,13 |
if (!audio_tid) return; |
audio_response = 0; |
audio_command = pause_on?AUDIO_SUSPEND:AUDIO_RESUME; |
while (!audio_response) |
Yield(); |
while (!audio_response) _ksys_thread_yield(); |
} |
void SDL_LockAudio(void) |
{ |
if (!audio_tid) return; |
bLocked = 1; |
while (bInCallback) |
Yield(); |
while (bInCallback) _ksys_thread_yield(); |
} |
void SDL_UnlockAudio(void) |
{ |