stubbed in sdl audio

This commit is contained in:
Dagen Brock 2016-01-23 10:12:23 -06:00
parent 3ce1729bb6
commit 800a792359
3 changed files with 402 additions and 77 deletions

309
src/sdlsnd_driver.c Normal file
View File

@ -0,0 +1,309 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 by GSport contributors
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#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_win32snd_buflen = 0x1000;
SDL_AudioSpec want, have;
SDL_AudioDeviceID dev;
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;
}
// OG Added global to free the dedicated win32 sound memory
byte *bptr = NULL;
// OG shut win32 sound resources
void
win32snd_shutdown()
{
/*
//if (g_wave_handle) //////
if (false)
{
MMRESULT res = waveOutReset(g_wave_handle);
if (res!=MMSYSERR_NOERROR )
printf("waveOutReset Failed");
res = waveOutClose(g_wave_handle);
if (res!=MMSYSERR_NOERROR )
printf("waveOutClose Failed");
g_wave_handle=NULL;
}
// OG Free dedicated sound memory
if (bptr)
{
free(bptr);
bptr = NULL;
}
*/
}
/*
void CALLBACK
handle_wav_snd(HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1,
DWORD dwParam2)
{
LPWAVEHDR lpwavehdr;
// Only service "buffer done playing messages
if(uMsg == WOM_DONE) {
lpwavehdr = (LPWAVEHDR)dwParam1;
if(lpwavehdr->dwFlags == (WHDR_DONE | WHDR_PREPARED)) {
lpwavehdr->dwUser = FALSE;
}
}
return;
}
*/
void
check_wave_error(int res, char *str)
{
/*
TCHAR buf[256];
if(res == MMSYSERR_NOERROR) {
return;
}
waveOutGetErrorText(res, &buf[0], sizeof(buf));
printf("%s: %s\n", str, buf);
*/
exit(1);
}
void handle_sdl_snd(/* arguments */) {
/* code */
}
void
sdlsnd_shutdown() {
//SDL_Delay(5000); // let the audio callback play some sound for 5 seconds.
SDL_CloseAudioDevice(dev);
printf("sdlsnd_shutdown");
}
void
child_sound_init_sdl()
{
printf("child_sound_init_sdl");
SDL_memset(&want, 0, sizeof(want)); // or SDL_zero(want)
want.freq = 48000;
want.format = AUDIO_F32;
want.channels = 2;
want.samples = 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");
}
SDL_PauseAudioDevice(dev, 0); // start audio playing.
}
// UNKNOWN?
g_audio_rate = have.freq;
printf("g_audio_rate: %d\n", g_audio_rate);
set_audio_rate(g_audio_rate);
}
void
child_sound_init_win32()
{
/*
WAVEFORMATEX wavefmt;
WAVEOUTCAPS caps;
// OG Moved as global variable (to rename)
// byte *bptr;
int bits_per_sample, channels, block_align;
int blen;
int res;
int i;
memset(&wavefmt, 0, sizeof(WAVEFORMATEX));
wavefmt.wFormatTag = WAVE_FORMAT_PCM;
#ifndef UNDER_CE
bits_per_sample = 16;
wavefmt.nSamplesPerSec = g_audio_rate;
#else
bits_per_sample = 16;
wavefmt.nSamplesPerSec = 12000;
#endif
channels = 2;
wavefmt.wBitsPerSample = bits_per_sample;
wavefmt.nChannels = channels;
block_align = channels * (bits_per_sample / 8);
wavefmt.nBlockAlign = block_align;
wavefmt.nAvgBytesPerSec = block_align * g_audio_rate;
res = waveOutOpen(&g_wave_handle, WAVE_MAPPER, &wavefmt, 0, 0,
WAVE_FORMAT_QUERY);
if(res != MMSYSERR_NOERROR) {
printf("Cannot open audio device\n");
g_audio_enable = 0;
return;
}
res = waveOutOpen(&g_wave_handle, WAVE_MAPPER, &wavefmt,
(DWORD)handle_wav_snd, 0, CALLBACK_FUNCTION | WAVE_ALLOWSYNC);
if(res != MMSYSERR_NOERROR) {
printf("Cannot register audio\n");
g_audio_enable = 0;
return;
}
g_audio_rate = wavefmt.nSamplesPerSec;
blen = (SOUND_SHM_SAMP_SIZE * 4 * 2) / NUM_WAVE_HEADERS;
g_win32snd_buflen = blen;
bptr = (byte*)malloc(blen * NUM_WAVE_HEADERS); // OG Added cast
if(bptr == NULL) {
printf("Unabled to allocate sound buffer\n");
exit(1);
}
for(i = 0; i < NUM_WAVE_HEADERS; i++) {
memset(&g_wavehdr[i], 0, sizeof(WAVEHDR));
g_wavehdr[i].dwUser = FALSE;
g_wavehdr[i].lpData = (LPSTR)&(bptr[i*blen]); // OG Added cast
g_wavehdr[i].dwBufferLength = blen;
g_wavehdr[i].dwFlags = 0;
g_wavehdr[i].dwLoops = 0;
res = waveOutPrepareHeader(g_wave_handle, &g_wavehdr[i],
sizeof(WAVEHDR));
check_wave_error(res, "waveOutPrepareHeader");
}
res = waveOutGetDevCaps((UINT)g_wave_handle, &caps, sizeof(caps));
check_wave_error(res, "waveOutGetDevCaps");
printf("Using %s\n", caps.szPname);
printf(" Bits per Sample = %d. Channels = %d\n",
wavefmt.wBitsPerSample, wavefmt.nChannels);
printf(" Sampling rate = %d, avg_bytes_per_sec = %d\n",
(int)wavefmt.nSamplesPerSec, (int)wavefmt.nAvgBytesPerSec);
set_audio_rate(g_audio_rate);
*/
}
void sdl_send_audio(byte *ptr, int size) {
/* code */
printf(" sdl_send_audio ");
}
void
win32_send_audio2(byte *ptr, int size)
{
/*
int found;
int res;
int i;
found = 0;
for(i = 0; i < NUM_WAVE_HEADERS; i++) {
if(g_wavehdr[i].dwUser == FALSE) {
found = 1;
break;
}
}
if(!found) {
// all audio buffers busy, just get out
return;
}
memcpy(g_wavehdr[i].lpData, ptr, size);
g_wavehdr[i].dwBufferLength = size;
g_wavehdr[i].dwUser = TRUE;
res = waveOutWrite(g_wave_handle, &g_wavehdr[i], sizeof(g_wavehdr));
check_wave_error(res, "waveOutWrite");
*/
return;
}
int
win32_send_audio(byte *ptr, int in_size)
{
int size;
int tmpsize;
size = in_size;
while(size > 0) {
tmpsize = size;
if(size > g_win32snd_buflen) {
tmpsize = g_win32snd_buflen;
}
win32_send_audio2(ptr, tmpsize);
ptr += tmpsize;
size = size - tmpsize;
}
return in_size;
}

View File

@ -1,21 +1,21 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2012 by GSport contributors
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@ -24,11 +24,10 @@
extern int Verbose;
extern int g_use_shmem;
extern word32 g_vbl_count;
extern int g_preferred_rate;
extern int g_c03ef_doc_ptr;
extern double g_last_vbl_dcycs;
extern word32 g_vbl_count;
void U_STACK_TRACE();
@ -46,7 +45,8 @@ int g_queued_samps = 0;
int g_queued_nonsamps = 0;
int g_num_osc_interrupting = 0;
#if defined(HPUX) || defined(__linux__) || defined(WIN_SOUND) || defined(MAC) /* Workaround - gcc in cygwin wasn't defining _WIN32, substituted WIN_SOUND instead */
/* Workaround - gcc in cygwin wasn't defining _WIN32, substituted WIN_SOUND instead */
#if defined(HPUX) || defined(__linux__) || defined(WIN_SOUND) || defined(MAC) || defined(HAVE_SDL)
int g_audio_enable = -1;
#else
# if defined(OSS)
@ -263,17 +263,21 @@ sound_init()
void
sound_init_general()
{
#if !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(MAC) && !defined(__OS2__) /* Workaround - gcc in cygwin wasn't defining _WIN32 */
printf("SOUND INIT GENERAL\n");
/* Workaround - gcc in cygwin wasn't defining _WIN32 */
#if !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(MAC) && !defined(__OS2__) && !defined(HAVE_SDL)
int pid;
int shmid;
int tmp;
int i;
#endif
word32 *shmaddr;
int size;
int ret;
#if !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(MAC) && !defined(__OS2__) /* Workaround - gcc in cygwin wasn't defining _WIN32 */
/* Workaround - gcc in cygwin wasn't defining _WIN32 */
#if !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(MAC) && !defined(__OS2__) && !defined(HAVE_SDL)
if(!g_use_shmem) {
if(g_audio_enable < 0) {
printf("Defaulting audio off for slow X display\n");
@ -281,6 +285,7 @@ sound_init_general()
}
}
#endif
ret = 0;
if(g_audio_enable == 0) {
@ -289,12 +294,11 @@ sound_init_general()
}
size = SOUND_SHM_SAMP_SIZE * SAMPLE_CHAN_SIZE;
#if !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(MAC) && !defined(__OS2__) /* Workaround - gcc in cygwin wasn't defining _WIN32 */
/* Workaround - gcc in cygwin wasn't defining _WIN32 */
#if !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(MAC) && !defined(__OS2__) && !defined(HAVE_SDL)
shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | 0777);
if(shmid < 0) {
printf("sound_init: shmget ret: %d, errno: %d\n", shmid,
errno);
printf("sound_init: shmget ret: %d, errno: %d\n", shmid, errno);
exit(2);
}
@ -312,16 +316,16 @@ sound_init_general()
exit(4);
}
#else
/* windows and mac */
shmaddr = (word32*)malloc(size);
// windows and mac and sdl
shmaddr = (word32*)malloc(size); //size = 131072
memset(shmaddr, 0, size);
#endif
g_sound_shm_addr = shmaddr;
fflush(stdout);
#if !defined(MAC) && !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(__OS2__) /* Workaround - gcc in cygwin wasn't defining _WIN32 */
/* Workaround - gcc in cygwin wasn't defining _WIN32 */
#if !defined(MAC) && !defined(WIN_SOUND) && !defined(__CYGWIN__) && !defined(__OS2__) && !defined(HAVE_SDL)
/* prepare pipe so parent can signal child each other */
/* pipe[0] = read side, pipe[1] = write end */
ret = pipe(&g_pipe_fd[0]);
@ -371,14 +375,15 @@ sound_init_general()
parent_sound_get_sample_rate(g_pipe2_fd[0]);
#else
# ifdef MAC
macsnd_init(shmaddr);
# elif defined (WIN_SOUND) /* Workaround - gcc in cygwin wasn't defining _WIN32 */
/* windows */
# if defined (HAVE_SDL)
sdlsnd_init(shmaddr);
# elif defined (WIN_SOUND)
win32snd_init(shmaddr);
# elif defined (MAC) && !defined(HAVE_SDL)
macsnd_init(shmaddr);
# elif defined (__OS2__)
# endif
#endif /* WIN_SOUND */
#endif
}
@ -449,19 +454,22 @@ sound_shutdown()
#ifdef WIN_SOUND /* Workaround - gcc in cygwin wasn't defining _WIN32 */
win32snd_shutdown();
#elif defined(__OS2__)
#elif defined(HAVE_SDL)
if((g_audio_enable != 0)) {
sdlsnd_shutdown();
}
#else
if((g_audio_enable != 0) && g_pipe_fd[1] != 0) {
close(g_pipe_fd[1]);
}
#endif
// OG Free up allocated memory
if (g_sound_shm_addr)
{
free(g_sound_shm_addr);
g_sound_shm_addr = NULL;
}
}
@ -640,7 +648,8 @@ send_sound(int real_samps, int size)
DOC_LOG("send_sound", -1, g_last_sound_play_dsamp,
(real_samps << 30) + size);
#if defined(MAC) || defined(WIN_SOUND) /* Workaround - gcc in cygwin wasn't defining _WIN32 */
// Workaround - gcc in cygwin wasn't defining _WIN32
#if defined(MAC) || defined(WIN_SOUND) || defined(HAVE_SDL)
ret = 0;
child_sound_playit(tmp);
#elif defined(__OS2__)
@ -917,7 +926,7 @@ sound_play(double dsamps)
done = 0;
ctl = rptr->ctl;
samp_offset = 0;
if(complete_dsamp > last_dsamp) {
samp_offset = (int)(complete_dsamp- last_dsamp);
@ -931,10 +940,10 @@ sound_play(double dsamps)
/* other channel */
outptr += 1;
}
imul = (rptr->vol * g_doc_vol);
off = imul * 128;
samps_to_do = MIN(samps_left, num_samps - samp_offset);
if(imul == 0 || samps_to_do == 0) {
/* produce no sound */
@ -958,13 +967,13 @@ sound_play(double dsamps)
rptr->last_samp_val = val;
continue;
}
if(snd_buf_init == 0) {
memset(outptr_start, 0,
2*sizeof(outptr_start[0])*num_samps);
snd_buf_init++;
}
val = 0;
rptr->complete_dsamp = dsamp_now;
cur_pos = rptr->cur_start + (cur_acc & cur_mask);
@ -973,7 +982,7 @@ sound_play(double dsamps)
cur_pos += cur_inc;
cur_acc += cur_inc;
val = doc_ram[pos];
val2 = (val * imul - off) >> 4;
if((val == 0) || (cur_pos >= cur_end)) {
cur_dsamp = last_dsamp +
@ -988,14 +997,14 @@ sound_play(double dsamps)
val = 0;
break;
}
val2 = outptr[0] + val2;
samps_left--;
*outptr = val2;
outptr += 2;
}
rptr->last_samp_val = val;
if(val != 0) {
@ -1003,7 +1012,7 @@ sound_play(double dsamps)
rptr->samps_left = samps_left;
rptr->complete_dsamp = dsamp_now;
}
samps_played += samps_to_do;
DOC_LOG("splayed", osc, dsamp_now,
(samps_to_do << 16) + (pos & 0xffff));
@ -1031,7 +1040,7 @@ sound_play(double dsamps)
if(snd_buf_init) {
/* convert sound buf */
for(i = 0; i < num_samps; i++) {
val0 = outptr[0];
val1 = outptr[1];
@ -1042,7 +1051,7 @@ sound_play(double dsamps)
if(val0 < -32768) {
val = -32768;
}
val0 = val;
val = val1;
if(val1 > 32767) {
@ -1051,8 +1060,8 @@ sound_play(double dsamps)
if(val1 < -32768) {
val = -32768;
}
outptr += 2;
#if defined(__linux__) || defined(OSS)
@ -1078,18 +1087,18 @@ sound_play(double dsamps)
pos = 0;
}
}
if(g_queued_nonsamps) {
/* force out old 0 samps */
send_sound(0, g_queued_nonsamps);
g_queued_nonsamps = 0;
}
if(g_send_sound_to_file) {
send_sound_to_file(g_sound_shm_addr,
g_sound_shm_pos, num_samps);
}
g_queued_samps += num_samps;
} else {
/* move pos */
@ -1097,18 +1106,18 @@ sound_play(double dsamps)
while(pos >= SOUND_SHM_SAMP_SIZE) {
pos -= SOUND_SHM_SAMP_SIZE;
}
if(g_send_sound_to_file) {
send_sound_to_file(zero_buf, g_sound_shm_pos,
num_samps);
}
if(g_queued_samps) {
/* force out old non-0 samps */
send_sound(1, g_queued_samps);
g_queued_samps = 0;
}
g_queued_nonsamps += num_samps;
}
@ -1586,7 +1595,7 @@ doc_write_ctl_reg(int osc, int val, double dsamps)
/* start sound */
DOC_LOG("ctl_sound_play", osc, eff_dsamps, val);
// OG If the sound_play is executed, it may restart a oscillo we thought was stopped at time,
// OG If the sound_play is executed, it may restart a oscillo we thought was stopped at time,
// hence crashing the start_sound function (cf. game Arrgh!)
//sound_play(eff_dsamps);
g_doc_regs[osc].ctl = val;
@ -1821,7 +1830,7 @@ doc_write_c03d(int val, double dcycs)
/* DOC */
osc = g_c03ef_doc_ptr & 0x1f;
type = (g_c03ef_doc_ptr >> 5) & 0x7;
rptr = &(g_doc_regs[osc]);
ctl = rptr->ctl;
#if 0
@ -1941,7 +1950,7 @@ doc_write_c03d(int val, double dcycs)
UPDATE_G_DCYCS_PER_DOC_UPDATE(tmp);
// OG Update any oscs that were running to take care of the new numbers of oscillo
for(i = 0; i<g_doc_num_osc_en; i++)
for(i = 0; i<g_doc_num_osc_en; i++)
doc_recalc_sound_parms(i,0.0,0.0);
/* Stop any oscs that were running but now */

View File

@ -1,21 +1,21 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2012 by GSport contributors
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
@ -25,6 +25,9 @@
#ifdef HPUX
# include <sys/audio.h>
#endif
#ifdef HAVE_SDL
# include "SDL.h"
#endif
#if defined(__linux__) || defined(OSS)
# include <sys/soundcard.h>
@ -65,10 +68,12 @@ void child_sound_init_linux();
void child_sound_init_hpdev();
void child_sound_initWIN_SOUND();
void child_sound_init_mac();
void child_sound_init_sdl();
void
reliable_buf_write(word32 *shm_addr, int pos, int size)
{
printf("bbbbbb");
byte *ptr;
int ret;
@ -84,14 +89,14 @@ reliable_buf_write(word32 *shm_addr, int pos, int size)
size = size * 4;
while(size > 0) {
#ifdef WIN_SOUND
#if defined(HAVE_SDL)
ret = sdl_send_audio();
#elif defined(WIN_SOUND)
ret = win32_send_audio(ptr, size);
#else
# ifdef MAC
#elif defined(MAC) && !defined(HAVE_SDL)
ret = mac_send_audio(ptr, size);
# else
#else
ret = write(g_audio_socket, ptr, size);
# endif
#endif
if(ret < 0) {
@ -121,6 +126,7 @@ reliable_zero_write(int amt)
void
child_sound_loop(int read_fd, int write_fd, word32 *shm_addr)
{
printf("child_sound_loop\n" );
#ifdef HPUX
long status_return;
#endif
@ -139,17 +145,17 @@ child_sound_loop(int read_fd, int write_fd, word32 *shm_addr)
g_childsnd_vbl = 0;
g_childsnd_shm_addr = shm_addr;
#ifdef HPUX
child_sound_init_hpdev();
#endif
#if defined(__linux__) || defined(OSS)
#if defined(HAVE_SDL)
child_sound_init_sdl();
return;
#elif defined(__linux__) || defined(OSS)
child_sound_init_linux();
#endif
#ifdef WIN_SOUND
#elif HPUX
child_sound_init_hpdev();
#elif WIN_SOUND
child_sound_init_win32();
return;
#endif
#ifdef MAC
#elif defined(MAC) && !defined(HAVE_SDL)
child_sound_init_mac();
return;
#endif
@ -188,11 +194,12 @@ child_sound_loop(int read_fd, int write_fd, word32 *shm_addr)
void
child_sound_playit(word32 tmp)
{
printf("playit ");
int size;
size = tmp & 0xffffff;
//printf("child_sound_playit: %08x\n", tmp);
printf("child_sound_playit: %08x\n", tmp);
if((tmp >> 24) == 0xa2) {
/* play sound here */
@ -432,7 +439,7 @@ child_sound_init_linux()
printf("Audio rate of %d which is < 8000!\n", rate);
exit(1);
}
g_audio_rate = rate;
printf("Sound initialized\n");