/* GSPLUS - Advanced Apple IIGS Emulator Environment Based on the KEGS emulator written by Kent Dickey See COPYRIGHT.txt for Copyright information See LICENSE.txt for license (GPL v2) */ #include #include "defc.h" #include "sound.h" #include "SDL.h" extern int Verbose; extern int g_audio_rate; unsigned int __stdcall child_sound_loop_win32(void *param); void check_wave_error(int res, char *str); #define NUM_WAVE_HEADERS 8 //HWAVEOUT g_wave_handle = NULL; // OG Default value must be set //WAVEHDR g_wavehdr[NUM_WAVE_HEADERS]; extern int g_audio_enable; extern word32 *g_sound_shm_addr; extern int g_preferred_rate; int g_sdlsnd_buflen = 0x1000; word32 *bptr = NULL; int g_sdlsnd_write_idx; int g_sdlsnd_read_idx; // just to makeit stand out #ifdef HAVE_SDL static Uint8 *audio_chunk; static Uint8 *audio_pos; static Uint32 audio_len; static byte *sdlsnd_buf = 0; SDL_AudioSpec want, have; SDL_AudioDeviceID dev; static byte *playbuf = 0; static int g_playbuf_buffered = 0; static SDL_AudioSpec spec; static int snd_buf; static int snd_write; /* write position into playbuf */ static /* volatile */ int snd_read = 0; static void _snd_callback(void*, Uint8 *stream, int len); static void sound_write_sdl(int real_samps, int size); #endif void sdlsnd_init(word32 *shmaddr) { printf("sdlsnd_init\n"); if (SDL_Init(SDL_INIT_AUDIO) < 0) { printf("Cannot initialize SDL audio\n"); g_audio_enable = 0; } child_sound_loop(-1, -1, shmaddr); return; } void win32snd_init(word32 *shmaddr) { printf("win32snd_init\n"); child_sound_loop(-1, -1, shmaddr); return; } void sdl_send_audio(word32 *ptr, int size, int real_samps) { /* code */ //printf(" sdl_s_a %d\t 0x%08x ",size, &ptr); int i; for (i=0; ig_sdlsnd_buflen) { g_sdlsnd_write_idx=0; } } g_playbuf_buffered += size; } void handle_sdl_snd(void *userdata, Uint8 *stream, int len) { /* Only play if we have data left */ /* if ( g_playbuf_buffered == 0) { return; } */ for(int i = 0; i < len; ++i) { if(g_playbuf_buffered <= 0) { stream[i] = 0; } else { stream[i] = bptr[g_sdlsnd_read_idx++]; if(g_sdlsnd_read_idx == g_sdlsnd_buflen) g_sdlsnd_read_idx = 0; g_playbuf_buffered--; } } return; /* Mix as much data as possible */ len = ( len > g_playbuf_buffered ? g_playbuf_buffered : len ); //len = ( g_sdlsnd_read_idx+len < g_sdlsnd_buflen ? len : g_sdlsnd_read_idx+len); SDL_memset(stream, 0, len); if (g_sdlsnd_read_idx+len < g_sdlsnd_buflen) { SDL_memcpy (stream, &bptr[g_sdlsnd_read_idx], len); g_sdlsnd_read_idx += len; g_playbuf_buffered -= len; } else { /* int top_len = 0; top_len = g_sdlsnd_buflen - g_sdlsnd_read_idx; SDL_memcpy (stream, &bptr[g_sdlsnd_read_idx], top_len); g_sdlsnd_read_idx = 0; g_playbuf_buffered -= top_len; // SDL_memcpy (stream+top_len, bptr[g_sdlsnd_read_idx], len-top_len); g_sdlsnd_read_idx += len-top_len; g_playbuf_buffered -= len-top_len; */ } //SDL_MixAudio(stream, pointer, len, SDL_MIX_MAXVOLUME); } void child_sound_init_sdl() { printf("child_sound_init_sdl"); SDL_memset(&want, 0, sizeof(want)); // or SDL_zero(want) want.freq = g_preferred_rate; // 48000 ? want.format = AUDIO_S16SYS; // AUDIO_F32 want.channels = NUM_CHANNELS; //2 want.samples = 512; //4096 want.callback = handle_sdl_snd; // you wrote this function elsewhere. dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, SDL_AUDIO_ALLOW_FORMAT_CHANGE); if (dev == 0) { printf("Failed to open audio: %s\n", SDL_GetError()); } else { if (have.format != want.format) { // we let this one thing change. printf("We didn't get Float32 audio format.\n"); } } // super experimental unknown g_playbuf_buffered = 0; // init buffered state int blen; blen = (SOUND_SHM_SAMP_SIZE * SAMPLE_CHAN_SIZE * 2); // *2 unnecessary? g_sdlsnd_buflen = blen; bptr = (byte*)malloc(blen); if(bptr == NULL) { printf("Unabled to allocate sound buffer\n"); exit(1); } memset(bptr, 0, SOUND_SHM_SAMP_SIZE*SAMPLE_CHAN_SIZE *2); // zero out the buffer g_sdlsnd_write_idx = 0; // initialize g_sdlsnd_read_idx = 0; SDL_PauseAudioDevice(dev, 0); // start audio playing. g_audio_rate = have.freq; printf("g_audio_rate: %d\n", g_audio_rate); set_audio_rate(g_audio_rate); // let kegs simulator know the rate } void sdlsnd_shutdown() { //SDL_Delay(5000); // let the audio callback play some sound for 5 seconds. SDL_CloseAudioDevice(dev); printf("sdlsnd_shutdown"); }