mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-06-26 15:29:41 +00:00
Support for multiple sound buffers/voices
* In preparation for adding mockingboard support * NOTE: ALSA still has a hardcoded 1 buffer assumption with its use of mmapped access
This commit is contained in:
parent
06c6fd9feb
commit
693b9d31bf
|
@ -18,30 +18,28 @@
|
|||
|
||||
typedef struct IDirectSoundBuffer {
|
||||
|
||||
void *implementation_specific;
|
||||
void *_this;
|
||||
|
||||
HRESULT (*SetVolume)(LONG lVolume);
|
||||
HRESULT (*SetVolume)(void* _this, LONG lVolume);
|
||||
|
||||
HRESULT (*GetVolume)(LPLONG lplVolume);
|
||||
HRESULT (*GetVolume)(void* _this, LPLONG lplVolume);
|
||||
|
||||
HRESULT (*GetCurrentPosition)(LPDWORD lpdwCurrentPlayCursor, LPDWORD lpdwCurrentWriteCursor);
|
||||
HRESULT (*GetCurrentPosition)(void* _this, LPDWORD lpdwCurrentPlayCursor, LPDWORD lpdwCurrentWriteCursor);
|
||||
|
||||
HRESULT (*SetCurrentPosition)(DWORD dwNewPosition);
|
||||
|
||||
HRESULT (*Stop)();
|
||||
HRESULT (*Stop)(void* _this);
|
||||
|
||||
// This method restores the memory allocation for a lost sound buffer for the specified DirectSoundBuffer object.
|
||||
HRESULT (*Restore)();
|
||||
HRESULT (*Restore)(void *_this);
|
||||
|
||||
HRESULT (*Play)(DWORD dwReserved1, DWORD dwReserved2, DWORD dwFlags);
|
||||
HRESULT (*Play)(void* _this, DWORD dwReserved1, DWORD dwReserved2, DWORD dwFlags);
|
||||
|
||||
// This method obtains a valid write pointer to the sound buffer's audio data
|
||||
HRESULT (*Lock)(DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOID* lplpvAudioPtr1, LPDWORD lpdwAudioBytes1, LPVOID* lplpvAudioPtr2, LPDWORD lpdwAudioBytes2, DWORD dwFlags);
|
||||
HRESULT (*Lock)(void* _this, DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOID* lplpvAudioPtr1, LPDWORD lpdwAudioBytes1, LPVOID* lplpvAudioPtr2, LPDWORD lpdwAudioBytes2, DWORD dwFlags);
|
||||
|
||||
// This method releases a locked sound buffer.
|
||||
HRESULT (*Unlock)(LPVOID lpvAudioPtr1, DWORD dwAudioBytes1, LPVOID lpvAudioPtr2, DWORD dwAudioBytes2);
|
||||
HRESULT (*Unlock)(void* _this, LPVOID lpvAudioPtr1, DWORD dwAudioBytes1, LPVOID lpvAudioPtr2, DWORD dwAudioBytes2);
|
||||
|
||||
HRESULT (*GetStatus)(LPDWORD lpdwStatus);
|
||||
HRESULT (*GetStatus)(void* _this, LPDWORD lpdwStatus);
|
||||
|
||||
} IDirectSoundBuffer, *LPDIRECTSOUNDBUFFER, **LPLPDIRECTSOUNDBUFFER;
|
||||
|
||||
|
@ -124,6 +122,7 @@ typedef struct IDirectSoundBuffer {
|
|||
#define DSBSTATUS_BUFFERLOST 0x00000002
|
||||
#define DSBSTATUS_LOOPING 0x00000004
|
||||
#define DSBSTATUS_PLAYING 0x00000001
|
||||
#define _DSBSTATUS_NOTPLAYING 0x08000000
|
||||
#define DSBPLAY_LOOPING 0x00000001
|
||||
#define DSBVOLUME_MIN -10000
|
||||
#define DSBVOLUME_MAX 0
|
||||
|
@ -136,7 +135,10 @@ static inline bool SUCCEEDED(HRESULT x) { return x == DS_OK; }
|
|||
#define WAVE_FORMAT_PCM 0x0001
|
||||
#define DSBCAPS_GETCURRENTPOSITION2 0x00010000
|
||||
#define DSBCAPS_STICKYFOCUS 0x00004000
|
||||
#define DSBCAPS_LOCSOFTWARE 0x00000008
|
||||
#define DSBCAPS_CTRLVOLUME 0x00000080
|
||||
#define DSBCAPS_CTRLPOSITIONNOTIFY 0x00000100
|
||||
|
||||
|
||||
typedef struct {
|
||||
WORD wFormatTag;
|
||||
|
|
|
@ -15,45 +15,27 @@
|
|||
// HACK : this is an ugly shoehorning into DirectSound assumptions... Needta rework this once I have a better
|
||||
// understanding of the workings of the sound system :)
|
||||
|
||||
static int resample = 1; /* enable alsa-lib resampling */
|
||||
static int period_event = 0; /* produce poll event after each period */
|
||||
static snd_pcm_format_t format = SND_PCM_FORMAT_S16;
|
||||
static int format_bits = 0;
|
||||
static int bytes_per_sample = 0;
|
||||
static int shift_per_sample = 0;
|
||||
|
||||
static snd_pcm_uframes_t buffer_size;
|
||||
static snd_pcm_uframes_t period_size;
|
||||
|
||||
static snd_pcm_hw_params_t *hwparams = NULL;
|
||||
static snd_pcm_sw_params_t *swparams = NULL;
|
||||
|
||||
extern SoundSystemStruct *g_lpDS; // HACK
|
||||
snd_pcm_uframes_t play_offset;
|
||||
|
||||
static long alsa_create_sound_buffer(ALSABufferParamsStruct *params_struct, ALSASoundBufferStruct **soundbuf_struct, void *extra_data);
|
||||
static long alsa_destroy_sound_buffer(ALSASoundBufferStruct **soundbuf_struct);
|
||||
|
||||
long SoundSystemCreate(const char *sound_device, SoundSystemStruct **sound_struct)
|
||||
{
|
||||
// ugly assumption : this sets the extern g_lpDS ...
|
||||
|
||||
assert(*sound_struct == NULL);
|
||||
|
||||
snd_pcm_t *handle = NULL;
|
||||
int err = -1;
|
||||
|
||||
do {
|
||||
if ((*sound_struct = malloc(sizeof(SoundSystemStruct))) == NULL)
|
||||
{
|
||||
ERRLOG("Not enough memory");
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((err = snd_pcm_open(&handle, sound_device, SND_PCM_STREAM_PLAYBACK, 0)) < 0)
|
||||
{
|
||||
ERRLOG("Playback open error: %s", snd_strerror(err));
|
||||
Free(*sound_struct);
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
|
||||
(*sound_struct)->implementation_specific = handle;
|
||||
|
@ -61,6 +43,15 @@ long SoundSystemCreate(const char *sound_device, SoundSystemStruct **sound_struc
|
|||
(*sound_struct)->DestroySoundBuffer = alsa_destroy_sound_buffer;
|
||||
|
||||
return 0;
|
||||
} while(0);
|
||||
|
||||
// ERRQUIT
|
||||
if (*sound_struct)
|
||||
{
|
||||
Free(*sound_struct);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
long SoundSystemDestroy(SoundSystemStruct **sound_struct)
|
||||
|
@ -81,7 +72,6 @@ long SoundSystemDestroy(SoundSystemStruct **sound_struct)
|
|||
ERRLOG("snd_pcm_drop: %s", snd_strerror(err));
|
||||
}
|
||||
|
||||
(*sound_struct)->implementation_specific = NULL;
|
||||
Free(*sound_struct);
|
||||
|
||||
return 0;
|
||||
|
@ -204,7 +194,7 @@ static long _alsa_create_volume_refs(snd_mixer_t **handle, snd_mixer_selem_id_t
|
|||
return err ?: -1;
|
||||
}
|
||||
|
||||
static long alsa_get_volume(long *volume)
|
||||
static long alsa_get_volume(void *_this, long *volume)
|
||||
{
|
||||
assert(volume != NULL);
|
||||
|
||||
|
@ -241,7 +231,7 @@ static long alsa_get_volume(long *volume)
|
|||
return err;
|
||||
}
|
||||
|
||||
static long alsa_set_volume(long volume)
|
||||
static long alsa_set_volume(void *_this, long volume)
|
||||
{
|
||||
// UNIMPLEMENTED
|
||||
return 0;
|
||||
|
@ -291,34 +281,28 @@ static int xrun_recovery(snd_pcm_t *handle, int err)
|
|||
return err;
|
||||
}
|
||||
|
||||
static long alsa_set_position(unsigned long write_cursor)
|
||||
{
|
||||
// UNIMPLEMENTED
|
||||
assert(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long alsa_stop()
|
||||
static long alsa_stop(void *_this)
|
||||
{
|
||||
// this is a no-op at the moment, just let the sound flow!
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long alsa_restore()
|
||||
static long alsa_restore(void *_this)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long alsa_play(unsigned long reserved1, unsigned long reserved2, unsigned long flags)
|
||||
static long alsa_play(void *_this, unsigned long reserved1, unsigned long reserved2, unsigned long flags)
|
||||
{
|
||||
// this is a no-op presumably because all the alsa setup give us a buffer ready to play
|
||||
return 0;
|
||||
}
|
||||
|
||||
// returns buffer position in bytes
|
||||
static long alsa_get_position(unsigned long *play_cursor, unsigned long *unused_write_cursor)
|
||||
static long alsa_get_position(void *_this, unsigned long *play_cursor, unsigned long *unused_write_cursor)
|
||||
{
|
||||
snd_pcm_t *handle = (snd_pcm_t*)g_lpDS->implementation_specific;
|
||||
ALSAExtras *extras = (ALSAExtras*)_this;
|
||||
snd_pcm_t *handle = extras->handle;
|
||||
snd_pcm_sframes_t avail = 0;
|
||||
long err = 0;
|
||||
|
||||
|
@ -368,7 +352,7 @@ static long alsa_get_position(unsigned long *play_cursor, unsigned long *unused_
|
|||
|
||||
if (avail < 1024) // HACK MAGICK CONSTANT
|
||||
{
|
||||
ERRLOG("OOPS avail(%ld) < period_size(%lu) ... ", avail, period_size);
|
||||
ERRLOG("OOPS avail(%ld) < 1024 ... ", avail);
|
||||
ERRLOG("performing snd_pcm_wait() ...");
|
||||
err = snd_pcm_wait(handle, -1);
|
||||
if (err < 0)
|
||||
|
@ -383,8 +367,8 @@ static long alsa_get_position(unsigned long *play_cursor, unsigned long *unused_
|
|||
break;
|
||||
}
|
||||
|
||||
avail = buffer_size - avail;
|
||||
*play_cursor = avail<<shift_per_sample;
|
||||
avail = extras->buffer_size - avail;
|
||||
*play_cursor = avail<<(extras->shift_per_sample);
|
||||
return 0;
|
||||
|
||||
} while (0);
|
||||
|
@ -394,19 +378,20 @@ static long alsa_get_position(unsigned long *play_cursor, unsigned long *unused_
|
|||
|
||||
// HACK NOTE : audio_ptr2 is unused
|
||||
// DS->Lock()
|
||||
static long alsa_begin(unsigned long unused, unsigned long write_bytes, void **audio_ptr1, unsigned long *audio_bytes1, void **unused_audio_ptr2, unsigned long *audio_bytes2, unsigned long flags)
|
||||
static long alsa_begin(void *_this, unsigned long unused, unsigned long write_bytes, void **audio_ptr1, unsigned long *audio_bytes1, void **unused_audio_ptr2, unsigned long *audio_bytes2, unsigned long flags_unused)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
ALSAExtras *extras = (ALSAExtras*)_this;
|
||||
const snd_pcm_channel_area_t *areas;
|
||||
uint8_t *bytes = NULL;
|
||||
|
||||
snd_pcm_uframes_t offset_frames = 0;
|
||||
snd_pcm_uframes_t size_frames = write_bytes>>shift_per_sample; // HACK : assuming 16bit samples
|
||||
snd_pcm_uframes_t size_frames = write_bytes>>(extras->shift_per_sample); // HACK : assuming 16bit samples
|
||||
|
||||
if (write_bytes == 0)
|
||||
{
|
||||
size_frames = buffer_size;
|
||||
size_frames = extras->buffer_size;
|
||||
}
|
||||
|
||||
*audio_ptr1 = NULL;
|
||||
|
@ -418,7 +403,7 @@ static long alsa_begin(unsigned long unused, unsigned long write_bytes, void **a
|
|||
*audio_bytes2 = 0;
|
||||
|
||||
do {
|
||||
snd_pcm_t *handle = (snd_pcm_t*)g_lpDS->implementation_specific;
|
||||
snd_pcm_t *handle = extras->handle;
|
||||
while ((err = snd_pcm_mmap_begin(handle, &areas, &offset_frames, &size_frames)) < 0)
|
||||
{
|
||||
if ((err = xrun_recovery(handle, err)) < 0)
|
||||
|
@ -434,12 +419,12 @@ static long alsa_begin(unsigned long unused, unsigned long write_bytes, void **a
|
|||
assert((area.first % 8) == 0);
|
||||
|
||||
bytes = (((uint8_t *)area.addr) + (area.first>>3));
|
||||
assert(format_bits == area.step);
|
||||
assert(bytes_per_sample == (area.step>>3));
|
||||
bytes += offset_frames * bytes_per_sample;
|
||||
assert(extras->format_bits == area.step);
|
||||
assert(extras->bytes_per_sample == (area.step>>3));
|
||||
bytes += offset_frames * extras->bytes_per_sample;
|
||||
|
||||
*audio_ptr1 = (void*)bytes;
|
||||
*audio_bytes1 = size_frames<<shift_per_sample;
|
||||
*audio_bytes1 = size_frames<<(extras->shift_per_sample);
|
||||
*audio_bytes2 = offset_frames;
|
||||
return 0;
|
||||
|
||||
|
@ -449,15 +434,16 @@ static long alsa_begin(unsigned long unused, unsigned long write_bytes, void **a
|
|||
}
|
||||
|
||||
// DS->Unlock()
|
||||
static long alsa_commit(void *unused_audio_ptr1, unsigned long audio_bytes1, void *unused_audio_ptr2, unsigned long audio_bytes2)
|
||||
static long alsa_commit(void *_this, void *unused_audio_ptr1, unsigned long audio_bytes1, void *unused_audio_ptr2, unsigned long audio_bytes2)
|
||||
{
|
||||
ALSAExtras *extras = (ALSAExtras*)_this;
|
||||
assert(unused_audio_ptr2 == NULL);
|
||||
int err = 0;
|
||||
|
||||
snd_pcm_uframes_t size_frames = audio_bytes1>>shift_per_sample;
|
||||
snd_pcm_uframes_t size_frames = audio_bytes1>>(extras->shift_per_sample);
|
||||
snd_pcm_uframes_t offset_frames = audio_bytes2;
|
||||
do {
|
||||
snd_pcm_t *handle = (snd_pcm_t*)g_lpDS->implementation_specific;
|
||||
snd_pcm_t *handle = extras->handle;
|
||||
err = snd_pcm_mmap_commit(handle, offset_frames, size_frames);
|
||||
if (err < 0 || (snd_pcm_uframes_t)err != size_frames)
|
||||
{
|
||||
|
@ -484,18 +470,33 @@ static long alsa_commit(void *unused_audio_ptr1, unsigned long audio_bytes1, voi
|
|||
return err ?: -1;
|
||||
}
|
||||
|
||||
static long alsa_get_status(unsigned long *status)
|
||||
static long alsa_get_status(void *_this, unsigned long *status)
|
||||
{
|
||||
// this is actually tested in the alsa_get_position() call
|
||||
snd_pcm_t *handle = ((ALSAExtras*)_this)->handle;
|
||||
|
||||
if (snd_pcm_state(handle) == SND_PCM_STATE_RUNNING)
|
||||
{
|
||||
*status = DSBSTATUS_PLAYING;
|
||||
}
|
||||
else
|
||||
{
|
||||
*status = _DSBSTATUS_NOTPLAYING;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static int set_hwparams(snd_pcm_t *handle, ALSABufferParamsStruct *params_struct)
|
||||
static int set_hwparams(ALSAExtras *extras, ALSABufferParamsStruct *params_struct)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
int resample = 1; // enable alsa-lib resampling
|
||||
|
||||
snd_pcm_t *handle = extras->handle;
|
||||
snd_pcm_hw_params_t *hwparams = extras->hwparams;
|
||||
|
||||
/* choose all parameters */
|
||||
if ((err = snd_pcm_hw_params_any(handle, hwparams)) < 0)
|
||||
{
|
||||
|
@ -517,15 +518,16 @@ static int set_hwparams(snd_pcm_t *handle, ALSABufferParamsStruct *params_struct
|
|||
return err;
|
||||
}
|
||||
|
||||
extras->format = SND_PCM_FORMAT_S16;
|
||||
/* set the sample format as signed 16bit samples */
|
||||
if ((err = snd_pcm_hw_params_set_format(handle, hwparams, format)) < 0)
|
||||
if ((err = snd_pcm_hw_params_set_format(handle, hwparams, extras->format)) < 0)
|
||||
{
|
||||
ERRLOG("Sample format not available for playback: %s", snd_strerror(err));
|
||||
return err;
|
||||
}
|
||||
format_bits = snd_pcm_format_physical_width(format);
|
||||
bytes_per_sample = format_bits / 8;
|
||||
shift_per_sample = (bytes_per_sample>>1); // HACK : ASSUMES 16bit samples ...
|
||||
extras->format_bits = snd_pcm_format_physical_width(extras->format);
|
||||
extras->bytes_per_sample = extras->format_bits / 8;
|
||||
extras->shift_per_sample = (extras->bytes_per_sample>>1); // HACK : ASSUMES 16bit samples ...
|
||||
|
||||
/* set the count of channels */
|
||||
if ((err = snd_pcm_hw_params_set_channels(handle, hwparams, params_struct->lpwfxFormat->nChannels)) < 0)
|
||||
|
@ -548,13 +550,13 @@ static int set_hwparams(snd_pcm_t *handle, ALSABufferParamsStruct *params_struct
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* set the buffer time */
|
||||
/* set the buffer size */
|
||||
int ignored;
|
||||
buffer_size = params_struct->dwBufferBytes;
|
||||
err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &buffer_size);
|
||||
extras->buffer_size = params_struct->dwBufferBytes;
|
||||
err = snd_pcm_hw_params_set_buffer_size_near(handle, hwparams, &(extras->buffer_size));
|
||||
if (err < 0)
|
||||
{
|
||||
ERRLOG("Unable to set buffer size %d for playback: %s", (int)buffer_size, snd_strerror(err));
|
||||
ERRLOG("Unable to set buffer size %d for playback: %s", (int)extras->buffer_size, snd_strerror(err));
|
||||
}
|
||||
|
||||
snd_pcm_uframes_t size;
|
||||
|
@ -563,17 +565,17 @@ static int set_hwparams(snd_pcm_t *handle, ALSABufferParamsStruct *params_struct
|
|||
ERRLOG("Unable to get buffer size for playback: %s", snd_strerror(err));
|
||||
return err;
|
||||
}
|
||||
if (size != buffer_size)
|
||||
if (size != extras->buffer_size)
|
||||
{
|
||||
ERRLOG("Note: buffer_size fetch mismatch using %d -- (%d requested)", (int)size, (int)buffer_size);
|
||||
buffer_size = size;
|
||||
ERRLOG("Note: buffer_size fetch mismatch using %d -- (%d requested)", (int)size, (int)extras->buffer_size);
|
||||
extras->buffer_size = size;
|
||||
}
|
||||
|
||||
period_size = buffer_size / 4;
|
||||
err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, &period_size, &ignored);
|
||||
extras->period_size = (extras->buffer_size)>>3;
|
||||
err = snd_pcm_hw_params_set_period_size_near(handle, hwparams, &(extras->period_size), &ignored);
|
||||
if (err < 0)
|
||||
{
|
||||
ERRLOG("Unable to set period size %d for playback: %s", (int)period_size, snd_strerror(err));
|
||||
ERRLOG("Unable to set period size %d for playback: %s", (int)extras->period_size, snd_strerror(err));
|
||||
}
|
||||
|
||||
if ((err = snd_pcm_hw_params_get_period_size(hwparams, &size, &ignored)) < 0)
|
||||
|
@ -581,10 +583,10 @@ static int set_hwparams(snd_pcm_t *handle, ALSABufferParamsStruct *params_struct
|
|||
ERRLOG("Unable to get period size for playback: %s", snd_strerror(err));
|
||||
return err;
|
||||
}
|
||||
if (size != period_size)
|
||||
if (size != extras->period_size)
|
||||
{
|
||||
ERRLOG("Note: period_size fetch mismatch using %d -- (%d requested)", (int)size, (int)period_size);
|
||||
period_size = size;
|
||||
ERRLOG("Note: period_size fetch mismatch using %d -- (%d requested)", (int)size, (int)extras->period_size);
|
||||
extras->period_size = size;
|
||||
}
|
||||
|
||||
/* write the parameters to device */
|
||||
|
@ -597,10 +599,14 @@ static int set_hwparams(snd_pcm_t *handle, ALSABufferParamsStruct *params_struct
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int set_swparams(snd_pcm_t *handle, ALSABufferParamsStruct *params_struct)
|
||||
static int set_swparams(ALSAExtras *extras, ALSABufferParamsStruct *params_struct)
|
||||
{
|
||||
int err = -1;
|
||||
|
||||
int period_event = 0; // produce poll event after each period
|
||||
snd_pcm_t *handle = extras->handle;
|
||||
snd_pcm_sw_params_t *swparams = extras->swparams;
|
||||
|
||||
/* get the current swparams */
|
||||
if ((err = snd_pcm_sw_params_current(handle, swparams)) < 0)
|
||||
{
|
||||
|
@ -610,7 +616,7 @@ static int set_swparams(snd_pcm_t *handle, ALSABufferParamsStruct *params_struct
|
|||
|
||||
/* start the transfer when the buffer is almost full: */
|
||||
/* (buffer_size / avail_min) * avail_min */
|
||||
if ((err = snd_pcm_sw_params_set_start_threshold(handle, swparams, (buffer_size / period_size) * period_size)) < 0)
|
||||
if ((err = snd_pcm_sw_params_set_start_threshold(handle, swparams, (extras->buffer_size / extras->period_size) * extras->period_size)) < 0)
|
||||
{
|
||||
ERRLOG("Unable to set start threshold mode for playback: %s", snd_strerror(err));
|
||||
return err;
|
||||
|
@ -618,7 +624,7 @@ static int set_swparams(snd_pcm_t *handle, ALSABufferParamsStruct *params_struct
|
|||
|
||||
/* allow the transfer when at least period_size samples can be processed */
|
||||
/* or disable this mechanism when period event is enabled (aka interrupt like style processing) */
|
||||
if ((err = snd_pcm_sw_params_set_avail_min(handle, swparams, period_event ? buffer_size : period_size)) < 0)
|
||||
if ((err = snd_pcm_sw_params_set_avail_min(handle, swparams, period_event ? extras->buffer_size : extras->period_size)) < 0)
|
||||
{
|
||||
ERRLOG("Unable to set avail min for playback: %s", snd_strerror(err));
|
||||
return err;
|
||||
|
@ -652,45 +658,23 @@ static long alsa_create_sound_buffer(ALSABufferParamsStruct *params_struct, ALSA
|
|||
snd_pcm_t *handle = (snd_pcm_t*)(sound_struct->implementation_specific);
|
||||
assert(handle != NULL);
|
||||
|
||||
ALSAExtras *extras = NULL;
|
||||
int err = -1;
|
||||
#if 0
|
||||
ALSASoundStructExtras *extras = NULL;
|
||||
#endif
|
||||
|
||||
if (hwparams == NULL)
|
||||
{
|
||||
snd_pcm_hw_params_alloca(&hwparams);
|
||||
}
|
||||
if (swparams == NULL)
|
||||
{
|
||||
snd_pcm_sw_params_alloca(&swparams);
|
||||
}
|
||||
|
||||
do {
|
||||
#if 0
|
||||
if ((extras = malloc(sizeof(ALSASoundStructExtras))) == NULL)
|
||||
|
||||
if ((extras = calloc(1, sizeof(ALSAExtras))) == NULL)
|
||||
{
|
||||
ERRLOG("Not enough memory");
|
||||
break;
|
||||
}
|
||||
|
||||
signed short *samples = NULL;
|
||||
if ((samples = malloc((period_size * format_bits) / 8)) == NULL)
|
||||
{
|
||||
ERRLOG("Not enough memory");
|
||||
break;
|
||||
}
|
||||
|
||||
snd_pcm_channel_area_t *area;
|
||||
if ((area = malloc(sizeof(snd_pcm_channel_area_t))) == NULL)
|
||||
{
|
||||
ERRLOG("Not enough memory");
|
||||
break;
|
||||
}
|
||||
area->addr = samples;
|
||||
area->first = 0;
|
||||
area->step = format_bits;
|
||||
#endif
|
||||
extras->handle = handle;
|
||||
snd_pcm_hw_params_alloca(&(extras->hwparams));
|
||||
snd_pcm_sw_params_alloca(&(extras->swparams));
|
||||
|
||||
if ((*soundbuf_struct = malloc(sizeof(ALSASoundBufferStruct))) == NULL)
|
||||
{
|
||||
|
@ -698,17 +682,10 @@ static long alsa_create_sound_buffer(ALSABufferParamsStruct *params_struct, ALSA
|
|||
break;
|
||||
}
|
||||
|
||||
#if 0
|
||||
extras->hwparams = hwparams;
|
||||
extras->swparams = swparams;
|
||||
extras->area = area;
|
||||
|
||||
(*soundbuf_struct)->implementation_specific = extras;
|
||||
#endif
|
||||
(*soundbuf_struct)->_this = extras;
|
||||
(*soundbuf_struct)->SetVolume = alsa_set_volume;
|
||||
(*soundbuf_struct)->GetVolume = alsa_get_volume;
|
||||
(*soundbuf_struct)->GetCurrentPosition = alsa_get_position;
|
||||
(*soundbuf_struct)->SetCurrentPosition = alsa_set_position;
|
||||
(*soundbuf_struct)->Stop = alsa_stop;
|
||||
(*soundbuf_struct)->Restore = alsa_restore;
|
||||
(*soundbuf_struct)->Play = alsa_play;
|
||||
|
@ -718,13 +695,13 @@ static long alsa_create_sound_buffer(ALSABufferParamsStruct *params_struct, ALSA
|
|||
|
||||
// configuration ...
|
||||
|
||||
if ((err = set_hwparams(handle, params_struct)) < 0)
|
||||
if ((err = set_hwparams(extras, params_struct)) < 0)
|
||||
{
|
||||
ERRLOG("Setting of hwparams failed: %s", snd_strerror(err));
|
||||
break;
|
||||
}
|
||||
|
||||
if ((err = set_swparams(handle, params_struct)) < 0)
|
||||
if ((err = set_swparams(extras, params_struct)) < 0)
|
||||
{
|
||||
ERRLOG("Setting of swparams failed: %s", snd_strerror(err));
|
||||
break;
|
||||
|
@ -743,20 +720,14 @@ static long alsa_create_sound_buffer(ALSABufferParamsStruct *params_struct, ALSA
|
|||
|
||||
} while(0);
|
||||
|
||||
if (extras)
|
||||
{
|
||||
Free(extras);
|
||||
}
|
||||
if (*soundbuf_struct)
|
||||
{
|
||||
alsa_destroy_sound_buffer(soundbuf_struct);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
if (hwparams) { Free(hwparams); }
|
||||
if (swparams) { Free(swparams); }
|
||||
if (area) { Free(area); }
|
||||
if (samples) { Free(samples); }
|
||||
if (extras) { Free(extras); }
|
||||
#endif
|
||||
}
|
||||
|
||||
return err ?: -1;
|
||||
}
|
||||
|
|
|
@ -27,10 +27,19 @@ typedef struct IDirectSoundBuffer ALSASoundBufferStruct;
|
|||
typedef struct DSBUFFERDESC ALSABufferParamsStruct;
|
||||
|
||||
typedef struct {
|
||||
snd_pcm_t *handle;
|
||||
snd_pcm_hw_params_t *hwparams;
|
||||
snd_pcm_sw_params_t *swparams;
|
||||
snd_pcm_channel_area_t *area;
|
||||
} ALSASoundStructExtras;
|
||||
|
||||
snd_pcm_format_t format;
|
||||
int format_bits;
|
||||
int bytes_per_sample;
|
||||
int shift_per_sample;
|
||||
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
snd_pcm_uframes_t period_size;
|
||||
|
||||
} ALSAExtras;
|
||||
|
||||
#endif /* whole file */
|
||||
|
||||
|
|
|
@ -162,8 +162,12 @@ bool DSGetLock(LPDIRECTSOUNDBUFFER pVoice, DWORD dwOffset, DWORD dwBytes,
|
|||
SHORT** ppDSLockedBuffer0, DWORD* pdwDSLockedBufferSize0,
|
||||
SHORT** ppDSLockedBuffer1, DWORD* pdwDSLockedBufferSize1)
|
||||
{
|
||||
DWORD nStatus;
|
||||
DWORD nStatus = 0;
|
||||
#ifdef APPLE2IX
|
||||
HRESULT hr = pVoice->GetStatus(pVoice->_this, &nStatus);
|
||||
#else
|
||||
HRESULT hr = pVoice->GetStatus(&nStatus);
|
||||
#endif
|
||||
if(hr != DS_OK)
|
||||
return false;
|
||||
|
||||
|
@ -171,7 +175,11 @@ bool DSGetLock(LPDIRECTSOUNDBUFFER pVoice, DWORD dwOffset, DWORD dwBytes,
|
|||
{
|
||||
do
|
||||
{
|
||||
#ifdef APPLE2IX
|
||||
hr = pVoice->Restore(pVoice->_this);
|
||||
#else
|
||||
hr = pVoice->Restore();
|
||||
#endif
|
||||
if(hr == DSERR_BUFFERLOST)
|
||||
Sleep(10);
|
||||
}
|
||||
|
@ -181,7 +189,11 @@ bool DSGetLock(LPDIRECTSOUNDBUFFER pVoice, DWORD dwOffset, DWORD dwBytes,
|
|||
// Get write only pointer(s) to sound buffer
|
||||
if(dwBytes == 0)
|
||||
{
|
||||
#ifdef APPLE2IX
|
||||
if(FAILED(hr = pVoice->Lock(pVoice->_this, 0, 0,
|
||||
#else
|
||||
if(FAILED(hr = pVoice->Lock(0, 0,
|
||||
#endif
|
||||
(void**)ppDSLockedBuffer0, pdwDSLockedBufferSize0,
|
||||
(void**)ppDSLockedBuffer1, pdwDSLockedBufferSize1,
|
||||
DSBLOCK_ENTIREBUFFER)))
|
||||
|
@ -189,7 +201,11 @@ bool DSGetLock(LPDIRECTSOUNDBUFFER pVoice, DWORD dwOffset, DWORD dwBytes,
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifdef APPLE2IX
|
||||
if(FAILED(hr = pVoice->Lock(pVoice->_this, dwOffset, dwBytes,
|
||||
#else
|
||||
if(FAILED(hr = pVoice->Lock(dwOffset, dwBytes,
|
||||
#endif
|
||||
(void**)ppDSLockedBuffer0, pdwDSLockedBufferSize0,
|
||||
(void**)ppDSLockedBuffer1, pdwDSLockedBufferSize1,
|
||||
0)))
|
||||
|
@ -227,6 +243,7 @@ HRESULT DSGetSoundBuffer(VOICE* pVoice, DWORD dwFlags, DWORD dwBufferSize, DWORD
|
|||
if (pVoice->lpDSBvoice)
|
||||
{
|
||||
g_lpDS->DestroySoundBuffer(&pVoice->lpDSBvoice);
|
||||
//DSReleaseSoundBuffer(pVoice);
|
||||
}
|
||||
HRESULT hr = g_lpDS->CreateSoundBuffer(&dsbdesc, &pVoice->lpDSBvoice, g_lpDS);
|
||||
#else
|
||||
|
@ -287,7 +304,7 @@ bool DSZeroVoiceBuffer(PVOICE Voice, char* pszDevName, DWORD dwBufferSize)
|
|||
|
||||
#ifdef APPLE2IX
|
||||
DWORD argX = 0;
|
||||
HRESULT hr = Voice->lpDSBvoice->Stop();
|
||||
HRESULT hr = Voice->lpDSBvoice->Stop(Voice->lpDSBvoice->_this);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
if(g_fh) fprintf(g_fh, "%s: DSStop failed (%08X)\n",pszDevName,hr);
|
||||
|
@ -308,7 +325,7 @@ bool DSZeroVoiceBuffer(PVOICE Voice, char* pszDevName, DWORD dwBufferSize)
|
|||
memset(pDSLockedBuffer, 0x00, dwDSLockedBufferSize);
|
||||
|
||||
#ifdef APPLE2IX
|
||||
hr = Voice->lpDSBvoice->Unlock((void*)pDSLockedBuffer, dwDSLockedBufferSize, NULL, argX);
|
||||
hr = Voice->lpDSBvoice->Unlock(Voice->lpDSBvoice->_this, (void*)pDSLockedBuffer, dwDSLockedBufferSize, NULL, argX);
|
||||
#else
|
||||
hr = Voice->lpDSBvoice->Unlock((void*)pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0);
|
||||
#endif
|
||||
|
@ -318,7 +335,11 @@ bool DSZeroVoiceBuffer(PVOICE Voice, char* pszDevName, DWORD dwBufferSize)
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifdef APPLE2IX
|
||||
hr = Voice->lpDSBvoice->Play(Voice->lpDSBvoice->_this, 0,0,DSBPLAY_LOOPING);
|
||||
#else
|
||||
hr = Voice->lpDSBvoice->Play(0,0,DSBPLAY_LOOPING);
|
||||
#endif
|
||||
if(FAILED(hr))
|
||||
{
|
||||
if(g_fh) fprintf(g_fh, "%s: DSPlay failed (%08X)\n",pszDevName,hr);
|
||||
|
@ -353,7 +374,11 @@ bool DSZeroVoiceWritableBuffer(PVOICE Voice, char* pszDevName, DWORD dwBufferSiz
|
|||
if(pDSLockedBuffer1)
|
||||
memset(pDSLockedBuffer1, 0x00, dwDSLockedBufferSize1);
|
||||
|
||||
#ifdef APPLE2IX
|
||||
hr = Voice->lpDSBvoice->Unlock(Voice->lpDSBvoice->_this, (void*)pDSLockedBuffer0, dwDSLockedBufferSize0,
|
||||
#else
|
||||
hr = Voice->lpDSBvoice->Unlock((void*)pDSLockedBuffer0, dwDSLockedBufferSize0,
|
||||
#endif
|
||||
(void*)pDSLockedBuffer1, dwDSLockedBufferSize1);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
|
@ -542,6 +567,7 @@ void SoundCore_SetFade(eFADE FadeType)
|
|||
// If AppleWin started by double-clicking a .dsk, then our window won't have focus when volumes are set (so gets ignored).
|
||||
// Subsequent setting (to the same volume) will get ignored, as DirectSound thinks that volume is already set.
|
||||
|
||||
#ifndef APPLE2IX
|
||||
void SoundCore_TweakVolumes()
|
||||
{
|
||||
for (UINT i=0; i<g_uNumVoices; i++)
|
||||
|
@ -550,6 +576,7 @@ void SoundCore_TweakVolumes()
|
|||
g_pVoices[i]->lpDSBvoice->SetVolume(g_pVoices[i]->nVolume);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
//#define RIFF_SPKR
|
||||
//#define RIFF_MB
|
||||
|
||||
#ifdef APPLE2IX
|
||||
extern bool g_bDisableDirectSound;
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -91,7 +94,6 @@ extern bool g_bDSAvailable;
|
|||
|
||||
#ifdef APPLE2IX
|
||||
typedef struct IDirectSound SoundSystemStruct;
|
||||
int SoundSystemInitialize();
|
||||
long SoundSystemCreate(const char *sound_device, SoundSystemStruct **sound_struct);
|
||||
long SoundSystemDestroy(SoundSystemStruct **sound_struct);
|
||||
long SoundSystemEnumerate(char ***sound_devices, const int maxcount);
|
||||
|
|
|
@ -72,7 +72,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
#define SOUND_WAVE 3
|
||||
|
||||
#ifdef APPLE2IX
|
||||
extern bool g_bDisableDirectSound; // soundcore.h
|
||||
#define g_nSPKR_NumChannels 1
|
||||
#else
|
||||
static const unsigned short g_nSPKR_NumChannels = 1;
|
||||
|
@ -817,7 +816,11 @@ static ULONG Spkr_SubmitWaveBuffer_FullSpeed(short* pSpeakerBuffer, ULONG nNumSa
|
|||
//bool bBufferError = false;
|
||||
|
||||
DWORD dwCurrentPlayCursor, dwCurrentWriteCursor;
|
||||
#ifdef APPLE2IX
|
||||
HRESULT hr = SpeakerVoice.lpDSBvoice->GetCurrentPosition(SpeakerVoice.lpDSBvoice->_this, &dwCurrentPlayCursor, &dwCurrentWriteCursor);
|
||||
#else
|
||||
HRESULT hr = SpeakerVoice.lpDSBvoice->GetCurrentPosition(&dwCurrentPlayCursor, &dwCurrentWriteCursor);
|
||||
#endif
|
||||
if(FAILED(hr))
|
||||
return nNumSamples;
|
||||
|
||||
|
@ -967,7 +970,11 @@ static ULONG Spkr_SubmitWaveBuffer_FullSpeed(short* pSpeakerBuffer, ULONG nNumSa
|
|||
}
|
||||
|
||||
// Commit sound buffer
|
||||
#ifdef APPLE2IX
|
||||
hr = SpeakerVoice.lpDSBvoice->Unlock(SpeakerVoice.lpDSBvoice->_this, (void*)pDSLockedBuffer0, dwDSLockedBufferSize0,
|
||||
#else
|
||||
hr = SpeakerVoice.lpDSBvoice->Unlock((void*)pDSLockedBuffer0, dwDSLockedBufferSize0,
|
||||
#endif
|
||||
(void*)pDSLockedBuffer1, dwDSLockedBufferSize1);
|
||||
if(FAILED(hr))
|
||||
return nNumSamples;
|
||||
|
@ -1013,7 +1020,11 @@ static ULONG Spkr_SubmitWaveBuffer(short* pSpeakerBuffer, ULONG nNumSamples)
|
|||
bool bBufferError = false;
|
||||
|
||||
DWORD dwCurrentPlayCursor, dwCurrentWriteCursor;
|
||||
#ifdef APPLE2IX
|
||||
HRESULT hr = SpeakerVoice.lpDSBvoice->GetCurrentPosition(SpeakerVoice.lpDSBvoice->_this, &dwCurrentPlayCursor, &dwCurrentWriteCursor);
|
||||
#else
|
||||
HRESULT hr = SpeakerVoice.lpDSBvoice->GetCurrentPosition(&dwCurrentPlayCursor, &dwCurrentWriteCursor);
|
||||
#endif
|
||||
if(FAILED(hr))
|
||||
return nNumSamples;
|
||||
|
||||
|
@ -1147,7 +1158,11 @@ static ULONG Spkr_SubmitWaveBuffer(short* pSpeakerBuffer, ULONG nNumSamples)
|
|||
}
|
||||
|
||||
// Commit sound buffer
|
||||
#ifdef APPLE2IX
|
||||
hr = SpeakerVoice.lpDSBvoice->Unlock(SpeakerVoice.lpDSBvoice->_this, (void*)pDSLockedBuffer0, dwDSLockedBufferSize0,
|
||||
#else
|
||||
hr = SpeakerVoice.lpDSBvoice->Unlock((void*)pDSLockedBuffer0, dwDSLockedBufferSize0,
|
||||
#endif
|
||||
(void*)pDSLockedBuffer1, dwDSLockedBufferSize1);
|
||||
if(FAILED(hr))
|
||||
return nNumSamples;
|
||||
|
@ -1166,7 +1181,11 @@ void Spkr_Mute()
|
|||
{
|
||||
if(SpeakerVoice.bActive && !SpeakerVoice.bMute)
|
||||
{
|
||||
#ifdef APPLE2IX
|
||||
SpeakerVoice.lpDSBvoice->SetVolume(SpeakerVoice.lpDSBvoice->_this, DSBVOLUME_MIN);
|
||||
#else
|
||||
SpeakerVoice.lpDSBvoice->SetVolume(DSBVOLUME_MIN);
|
||||
#endif
|
||||
SpeakerVoice.bMute = true;
|
||||
}
|
||||
}
|
||||
|
@ -1175,7 +1194,11 @@ void Spkr_Demute()
|
|||
{
|
||||
if(SpeakerVoice.bActive && SpeakerVoice.bMute)
|
||||
{
|
||||
#ifdef APPLE2IX
|
||||
SpeakerVoice.lpDSBvoice->SetVolume(SpeakerVoice.lpDSBvoice->_this, SpeakerVoice.nVolume);
|
||||
#else
|
||||
SpeakerVoice.lpDSBvoice->SetVolume(SpeakerVoice.nVolume);
|
||||
#endif
|
||||
SpeakerVoice.bMute = false;
|
||||
}
|
||||
}
|
||||
|
@ -1222,7 +1245,11 @@ void SpkrSetVolume(DWORD dwVolume, DWORD dwVolumeMax)
|
|||
SpeakerVoice.nVolume = NewVolume(dwVolume, dwVolumeMax);
|
||||
|
||||
if(SpeakerVoice.bActive)
|
||||
#ifdef APPLE2IX
|
||||
SpeakerVoice.lpDSBvoice->SetVolume(SpeakerVoice.lpDSBvoice->_this, SpeakerVoice.nVolume);
|
||||
#else
|
||||
SpeakerVoice.lpDSBvoice->SetVolume(SpeakerVoice.nVolume);
|
||||
#endif
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
@ -1285,7 +1312,11 @@ void Spkr_DSUninit()
|
|||
{
|
||||
if(SpeakerVoice.lpDSBvoice && SpeakerVoice.bActive)
|
||||
{
|
||||
#ifdef APPLE2IX
|
||||
SpeakerVoice.lpDSBvoice->Stop(SpeakerVoice.lpDSBvoice->_this);
|
||||
#else
|
||||
SpeakerVoice.lpDSBvoice->Stop();
|
||||
#endif
|
||||
SpeakerVoice.bActive = false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user