dsoundaudio: do not use global variables

Signed-off-by: Kővágó, Zoltán <DirtY.iCE.hu@gmail.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
Kővágó, Zoltán 2015-06-03 23:03:52 +02:00 committed by Gerd Hoffmann
parent 49dd6d0d33
commit 191e1f0acd
2 changed files with 74 additions and 50 deletions

View File

@ -67,7 +67,8 @@ static int glue (dsound_lock_, TYPE) (
LPVOID *p2p, LPVOID *p2p,
DWORD *blen1p, DWORD *blen1p,
DWORD *blen2p, DWORD *blen2p,
int entire int entire,
dsound *s
) )
{ {
HRESULT hr; HRESULT hr;
@ -75,13 +76,14 @@ static int glue (dsound_lock_, TYPE) (
LPVOID p1 = NULL, p2 = NULL; LPVOID p1 = NULL, p2 = NULL;
DWORD blen1 = 0, blen2 = 0; DWORD blen1 = 0, blen2 = 0;
DWORD flag; DWORD flag;
DSoundConf *conf = &s->conf;
#ifdef DSBTYPE_IN #ifdef DSBTYPE_IN
flag = entire ? DSCBLOCK_ENTIREBUFFER : 0; flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
#else #else
flag = entire ? DSBLOCK_ENTIREBUFFER : 0; flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
#endif #endif
for (i = 0; i < conf.lock_retries; ++i) { for (i = 0; i < conf->lock_retries; ++i) {
hr = glue (IFACE, _Lock) ( hr = glue (IFACE, _Lock) (
buf, buf,
pos, pos,
@ -96,7 +98,7 @@ static int glue (dsound_lock_, TYPE) (
if (FAILED (hr)) { if (FAILED (hr)) {
#ifndef DSBTYPE_IN #ifndef DSBTYPE_IN
if (hr == DSERR_BUFFERLOST) { if (hr == DSERR_BUFFERLOST) {
if (glue (dsound_restore_, TYPE) (buf)) { if (glue (dsound_restore_, TYPE) (buf, s)) {
dsound_logerr (hr, "Could not lock " NAME "\n"); dsound_logerr (hr, "Could not lock " NAME "\n");
goto fail; goto fail;
} }
@ -110,7 +112,7 @@ static int glue (dsound_lock_, TYPE) (
break; break;
} }
if (i == conf.lock_retries) { if (i == conf->lock_retries) {
dolog ("%d attempts to lock " NAME " failed\n", i); dolog ("%d attempts to lock " NAME " failed\n", i);
goto fail; goto fail;
} }
@ -183,9 +185,10 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
{ {
int err; int err;
HRESULT hr; HRESULT hr;
dsound *s = &glob_dsound; dsound *s = drv_opaque;
WAVEFORMATEX wfx; WAVEFORMATEX wfx;
struct audsettings obt_as; struct audsettings obt_as;
DSoundConf *conf = &s->conf;
#ifdef DSBTYPE_IN #ifdef DSBTYPE_IN
const char *typ = "ADC"; const char *typ = "ADC";
DSoundVoiceIn *ds = (DSoundVoiceIn *) hw; DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
@ -212,7 +215,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
bd.dwSize = sizeof (bd); bd.dwSize = sizeof (bd);
bd.lpwfxFormat = &wfx; bd.lpwfxFormat = &wfx;
#ifdef DSBTYPE_IN #ifdef DSBTYPE_IN
bd.dwBufferBytes = conf.bufsize_in; bd.dwBufferBytes = conf->bufsize_in;
hr = IDirectSoundCapture_CreateCaptureBuffer ( hr = IDirectSoundCapture_CreateCaptureBuffer (
s->dsound_capture, s->dsound_capture,
&bd, &bd,
@ -221,7 +224,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
); );
#else #else
bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2; bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
bd.dwBufferBytes = conf.bufsize_out; bd.dwBufferBytes = conf->bufsize_out;
hr = IDirectSound_CreateSoundBuffer ( hr = IDirectSound_CreateSoundBuffer (
s->dsound, s->dsound,
&bd, &bd,
@ -271,6 +274,7 @@ static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
); );
} }
hw->samples = bc.dwBufferBytes >> hw->info.shift; hw->samples = bc.dwBufferBytes >> hw->info.shift;
ds->s = s;
#ifdef DEBUG_DSOUND #ifdef DEBUG_DSOUND
dolog ("caps %ld, desc %ld\n", dolog ("caps %ld, desc %ld\n",

View File

@ -41,7 +41,7 @@
/* #define DEBUG_DSOUND */ /* #define DEBUG_DSOUND */
static struct { typedef struct {
int lock_retries; int lock_retries;
int restore_retries; int restore_retries;
int getstatus_retries; int getstatus_retries;
@ -50,33 +50,22 @@ static struct {
int bufsize_out; int bufsize_out;
struct audsettings settings; struct audsettings settings;
int latency_millis; int latency_millis;
} conf = { } DSoundConf;
.lock_retries = 1,
.restore_retries = 1,
.getstatus_retries = 1,
.set_primary = 0,
.bufsize_in = 16384,
.bufsize_out = 16384,
.settings.freq = 44100,
.settings.nchannels = 2,
.settings.fmt = AUD_FMT_S16,
.latency_millis = 10
};
typedef struct { typedef struct {
LPDIRECTSOUND dsound; LPDIRECTSOUND dsound;
LPDIRECTSOUNDCAPTURE dsound_capture; LPDIRECTSOUNDCAPTURE dsound_capture;
LPDIRECTSOUNDBUFFER dsound_primary_buffer; LPDIRECTSOUNDBUFFER dsound_primary_buffer;
struct audsettings settings; struct audsettings settings;
DSoundConf conf;
} dsound; } dsound;
static dsound glob_dsound;
typedef struct { typedef struct {
HWVoiceOut hw; HWVoiceOut hw;
LPDIRECTSOUNDBUFFER dsound_buffer; LPDIRECTSOUNDBUFFER dsound_buffer;
DWORD old_pos; DWORD old_pos;
int first_time; int first_time;
dsound *s;
#ifdef DEBUG_DSOUND #ifdef DEBUG_DSOUND
DWORD old_ppos; DWORD old_ppos;
DWORD played; DWORD played;
@ -88,6 +77,7 @@ typedef struct {
HWVoiceIn hw; HWVoiceIn hw;
int first_time; int first_time;
LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer; LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
dsound *s;
} DSoundVoiceIn; } DSoundVoiceIn;
static void dsound_log_hresult (HRESULT hr) static void dsound_log_hresult (HRESULT hr)
@ -281,12 +271,12 @@ static void print_wave_format (WAVEFORMATEX *wfx)
} }
#endif #endif
static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb) static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb, dsound *s)
{ {
HRESULT hr; HRESULT hr;
int i; int i;
for (i = 0; i < conf.restore_retries; ++i) { for (i = 0; i < s->conf.restore_retries; ++i) {
hr = IDirectSoundBuffer_Restore (dsb); hr = IDirectSoundBuffer_Restore (dsb);
switch (hr) { switch (hr) {
@ -311,12 +301,13 @@ static int dsound_restore_out (LPDIRECTSOUNDBUFFER dsb)
#include "dsound_template.h" #include "dsound_template.h"
#undef DSBTYPE_IN #undef DSBTYPE_IN
static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp) static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp,
dsound *s)
{ {
HRESULT hr; HRESULT hr;
int i; int i;
for (i = 0; i < conf.getstatus_retries; ++i) { for (i = 0; i < s->conf.getstatus_retries; ++i) {
hr = IDirectSoundBuffer_GetStatus (dsb, statusp); hr = IDirectSoundBuffer_GetStatus (dsb, statusp);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Could not get playback buffer status\n"); dsound_logerr (hr, "Could not get playback buffer status\n");
@ -324,7 +315,7 @@ static int dsound_get_status_out (LPDIRECTSOUNDBUFFER dsb, DWORD *statusp)
} }
if (*statusp & DSERR_BUFFERLOST) { if (*statusp & DSERR_BUFFERLOST) {
if (dsound_restore_out (dsb)) { if (dsound_restore_out (dsb, s)) {
return -1; return -1;
} }
continue; continue;
@ -376,7 +367,8 @@ static void dsound_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len)
hw->rpos = pos % hw->samples; hw->rpos = pos % hw->samples;
} }
static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb) static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb,
dsound *s)
{ {
int err; int err;
LPVOID p1, p2; LPVOID p1, p2;
@ -389,7 +381,8 @@ static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb)
hw->samples << hw->info.shift, hw->samples << hw->info.shift,
&p1, &p2, &p1, &p2,
&blen1, &blen2, &blen1, &blen2,
1 1,
s
); );
if (err) { if (err) {
return; return;
@ -435,6 +428,7 @@ static int dsound_open (dsound *s)
WAVEFORMATEX wfx; WAVEFORMATEX wfx;
DSBUFFERDESC dsbd; DSBUFFERDESC dsbd;
HWND hwnd; HWND hwnd;
DSoundConf *conf = &s->conf;
hwnd = GetForegroundWindow (); hwnd = GetForegroundWindow ();
hr = IDirectSound_SetCooperativeLevel ( hr = IDirectSound_SetCooperativeLevel (
@ -449,11 +443,11 @@ static int dsound_open (dsound *s)
return -1; return -1;
} }
if (!conf.set_primary) { if (!conf->set_primary) {
return 0; return 0;
} }
err = waveformat_from_audio_settings (&wfx, &conf.settings); err = waveformat_from_audio_settings (&wfx, &conf->settings);
if (err) { if (err) {
return -1; return -1;
} }
@ -514,6 +508,7 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
DWORD status; DWORD status;
DSoundVoiceOut *ds = (DSoundVoiceOut *) hw; DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer; LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
dsound *s = ds->s;
if (!dsb) { if (!dsb) {
dolog ("Attempt to control voice without a buffer\n"); dolog ("Attempt to control voice without a buffer\n");
@ -522,7 +517,7 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
switch (cmd) { switch (cmd) {
case VOICE_ENABLE: case VOICE_ENABLE:
if (dsound_get_status_out (dsb, &status)) { if (dsound_get_status_out (dsb, &status, s)) {
return -1; return -1;
} }
@ -531,7 +526,7 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
return 0; return 0;
} }
dsound_clear_sample (hw, dsb); dsound_clear_sample (hw, dsb, s);
hr = IDirectSoundBuffer_Play (dsb, 0, 0, DSBPLAY_LOOPING); hr = IDirectSoundBuffer_Play (dsb, 0, 0, DSBPLAY_LOOPING);
if (FAILED (hr)) { if (FAILED (hr)) {
@ -541,7 +536,7 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
break; break;
case VOICE_DISABLE: case VOICE_DISABLE:
if (dsound_get_status_out (dsb, &status)) { if (dsound_get_status_out (dsb, &status, s)) {
return -1; return -1;
} }
@ -578,6 +573,8 @@ static int dsound_run_out (HWVoiceOut *hw, int live)
DWORD wpos, ppos, old_pos; DWORD wpos, ppos, old_pos;
LPVOID p1, p2; LPVOID p1, p2;
int bufsize; int bufsize;
dsound *s = ds->s;
DSoundConf *conf = &s->conf;
if (!dsb) { if (!dsb) {
dolog ("Attempt to run empty with playback buffer\n"); dolog ("Attempt to run empty with playback buffer\n");
@ -600,14 +597,14 @@ static int dsound_run_out (HWVoiceOut *hw, int live)
len = live << hwshift; len = live << hwshift;
if (ds->first_time) { if (ds->first_time) {
if (conf.latency_millis) { if (conf->latency_millis) {
DWORD cur_blat; DWORD cur_blat;
cur_blat = audio_ring_dist (wpos, ppos, bufsize); cur_blat = audio_ring_dist (wpos, ppos, bufsize);
ds->first_time = 0; ds->first_time = 0;
old_pos = wpos; old_pos = wpos;
old_pos += old_pos +=
millis_to_bytes (&hw->info, conf.latency_millis) - cur_blat; millis_to_bytes (&hw->info, conf->latency_millis) - cur_blat;
old_pos %= bufsize; old_pos %= bufsize;
old_pos &= ~hw->info.align; old_pos &= ~hw->info.align;
} }
@ -663,7 +660,8 @@ static int dsound_run_out (HWVoiceOut *hw, int live)
len, len,
&p1, &p2, &p1, &p2,
&blen1, &blen2, &blen1, &blen2,
0 0,
s
); );
if (err) { if (err) {
return 0; return 0;
@ -766,6 +764,7 @@ static int dsound_run_in (HWVoiceIn *hw)
DWORD cpos, rpos; DWORD cpos, rpos;
LPVOID p1, p2; LPVOID p1, p2;
int hwshift; int hwshift;
dsound *s = ds->s;
if (!dscb) { if (!dscb) {
dolog ("Attempt to run without capture buffer\n"); dolog ("Attempt to run without capture buffer\n");
@ -820,7 +819,8 @@ static int dsound_run_in (HWVoiceIn *hw)
&p2, &p2,
&blen1, &blen1,
&blen2, &blen2,
0 0,
s
); );
if (err) { if (err) {
return 0; return 0;
@ -843,12 +843,26 @@ static int dsound_run_in (HWVoiceIn *hw)
return decr; return decr;
} }
static DSoundConf glob_conf = {
.lock_retries = 1,
.restore_retries = 1,
.getstatus_retries = 1,
.set_primary = 0,
.bufsize_in = 16384,
.bufsize_out = 16384,
.settings.freq = 44100,
.settings.nchannels = 2,
.settings.fmt = AUD_FMT_S16,
.latency_millis = 10
};
static void dsound_audio_fini (void *opaque) static void dsound_audio_fini (void *opaque)
{ {
HRESULT hr; HRESULT hr;
dsound *s = opaque; dsound *s = opaque;
if (!s->dsound) { if (!s->dsound) {
g_free(s);
return; return;
} }
@ -859,6 +873,7 @@ static void dsound_audio_fini (void *opaque)
s->dsound = NULL; s->dsound = NULL;
if (!s->dsound_capture) { if (!s->dsound_capture) {
g_free(s);
return; return;
} }
@ -867,17 +882,21 @@ static void dsound_audio_fini (void *opaque)
dsound_logerr (hr, "Could not release DirectSoundCapture\n"); dsound_logerr (hr, "Could not release DirectSoundCapture\n");
} }
s->dsound_capture = NULL; s->dsound_capture = NULL;
g_free(s);
} }
static void *dsound_audio_init (void) static void *dsound_audio_init (void)
{ {
int err; int err;
HRESULT hr; HRESULT hr;
dsound *s = &glob_dsound; dsound *s = g_malloc0(sizeof(dsound));
s->conf = glob_conf;
hr = CoInitialize (NULL); hr = CoInitialize (NULL);
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Could not initialize COM\n"); dsound_logerr (hr, "Could not initialize COM\n");
g_free(s);
return NULL; return NULL;
} }
@ -890,6 +909,7 @@ static void *dsound_audio_init (void)
); );
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Could not create DirectSound instance\n"); dsound_logerr (hr, "Could not create DirectSound instance\n");
g_free(s);
return NULL; return NULL;
} }
@ -901,7 +921,7 @@ static void *dsound_audio_init (void)
if (FAILED (hr)) { if (FAILED (hr)) {
dsound_logerr (hr, "Could not release DirectSound\n"); dsound_logerr (hr, "Could not release DirectSound\n");
} }
s->dsound = NULL; g_free(s);
return NULL; return NULL;
} }
@ -941,61 +961,61 @@ static struct audio_option dsound_options[] = {
{ {
.name = "LOCK_RETRIES", .name = "LOCK_RETRIES",
.tag = AUD_OPT_INT, .tag = AUD_OPT_INT,
.valp = &conf.lock_retries, .valp = &glob_conf.lock_retries,
.descr = "Number of times to attempt locking the buffer" .descr = "Number of times to attempt locking the buffer"
}, },
{ {
.name = "RESTOURE_RETRIES", .name = "RESTOURE_RETRIES",
.tag = AUD_OPT_INT, .tag = AUD_OPT_INT,
.valp = &conf.restore_retries, .valp = &glob_conf.restore_retries,
.descr = "Number of times to attempt restoring the buffer" .descr = "Number of times to attempt restoring the buffer"
}, },
{ {
.name = "GETSTATUS_RETRIES", .name = "GETSTATUS_RETRIES",
.tag = AUD_OPT_INT, .tag = AUD_OPT_INT,
.valp = &conf.getstatus_retries, .valp = &glob_conf.getstatus_retries,
.descr = "Number of times to attempt getting status of the buffer" .descr = "Number of times to attempt getting status of the buffer"
}, },
{ {
.name = "SET_PRIMARY", .name = "SET_PRIMARY",
.tag = AUD_OPT_BOOL, .tag = AUD_OPT_BOOL,
.valp = &conf.set_primary, .valp = &glob_conf.set_primary,
.descr = "Set the parameters of primary buffer" .descr = "Set the parameters of primary buffer"
}, },
{ {
.name = "LATENCY_MILLIS", .name = "LATENCY_MILLIS",
.tag = AUD_OPT_INT, .tag = AUD_OPT_INT,
.valp = &conf.latency_millis, .valp = &glob_conf.latency_millis,
.descr = "(undocumented)" .descr = "(undocumented)"
}, },
{ {
.name = "PRIMARY_FREQ", .name = "PRIMARY_FREQ",
.tag = AUD_OPT_INT, .tag = AUD_OPT_INT,
.valp = &conf.settings.freq, .valp = &glob_conf.settings.freq,
.descr = "Primary buffer frequency" .descr = "Primary buffer frequency"
}, },
{ {
.name = "PRIMARY_CHANNELS", .name = "PRIMARY_CHANNELS",
.tag = AUD_OPT_INT, .tag = AUD_OPT_INT,
.valp = &conf.settings.nchannels, .valp = &glob_conf.settings.nchannels,
.descr = "Primary buffer number of channels (1 - mono, 2 - stereo)" .descr = "Primary buffer number of channels (1 - mono, 2 - stereo)"
}, },
{ {
.name = "PRIMARY_FMT", .name = "PRIMARY_FMT",
.tag = AUD_OPT_FMT, .tag = AUD_OPT_FMT,
.valp = &conf.settings.fmt, .valp = &glob_conf.settings.fmt,
.descr = "Primary buffer format" .descr = "Primary buffer format"
}, },
{ {
.name = "BUFSIZE_OUT", .name = "BUFSIZE_OUT",
.tag = AUD_OPT_INT, .tag = AUD_OPT_INT,
.valp = &conf.bufsize_out, .valp = &glob_conf.bufsize_out,
.descr = "(undocumented)" .descr = "(undocumented)"
}, },
{ {
.name = "BUFSIZE_IN", .name = "BUFSIZE_IN",
.tag = AUD_OPT_INT, .tag = AUD_OPT_INT,
.valp = &conf.bufsize_in, .valp = &glob_conf.bufsize_in,
.descr = "(undocumented)" .descr = "(undocumented)"
}, },
{ /* End of list */ } { /* End of list */ }