aboutsummaryrefslogtreecommitdiff
path: root/audio/dsoundaudio.c
diff options
context:
space:
mode:
authorKővágó, Zoltán <dirty.ice.hu@gmail.com>2019-09-19 23:24:12 +0200
committerGerd Hoffmann <kraxel@redhat.com>2019-09-23 12:28:47 +0200
commit7fa9754ac888d571000110504a3a7950f1404212 (patch)
tree5a55a7998a5022d5460e4ae5969a8da1bdca1681 /audio/dsoundaudio.c
parent2ceb8240fa4e4e30fb853565eb2bed3032d74f62 (diff)
dsoundaudio: port to the new audio backend api
Signed-off-by: Kővágó, Zoltán <DirtY.iCE.hu@gmail.com> Message-id: 2ca925ab551ea832c930fc2db213a9e73d8dab7f.1568927990.git.DirtY.iCE.hu@gmail.com Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Diffstat (limited to 'audio/dsoundaudio.c')
-rw-r--r--audio/dsoundaudio.c305
1 files changed, 67 insertions, 238 deletions
diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c
index 2fc118b795..9960247814 100644
--- a/audio/dsoundaudio.c
+++ b/audio/dsoundaudio.c
@@ -53,19 +53,11 @@ typedef struct {
typedef struct {
HWVoiceOut hw;
LPDIRECTSOUNDBUFFER dsound_buffer;
- DWORD old_pos;
- int first_time;
dsound *s;
-#ifdef DEBUG_DSOUND
- DWORD old_ppos;
- DWORD played;
- DWORD mixed;
-#endif
} DSoundVoiceOut;
typedef struct {
HWVoiceIn hw;
- int first_time;
LPDIRECTSOUNDCAPTUREBUFFER dsound_capture_buffer;
dsound *s;
} DSoundVoiceIn;
@@ -243,11 +235,6 @@ static void GCC_FMT_ATTR (3, 4) dsound_logerr2 (
dsound_log_hresult (hr);
}
-static uint64_t usecs_to_bytes(struct audio_pcm_info *info, uint32_t usecs)
-{
- return muldiv64(usecs, info->bytes_per_second, 1000000);
-}
-
#ifdef DEBUG_DSOUND
static void print_wave_format (WAVEFORMATEX *wfx)
{
@@ -312,33 +299,6 @@ static int dsound_get_status_in (LPDIRECTSOUNDCAPTUREBUFFER dscb,
return 0;
}
-static void dsound_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len)
-{
- int src_len1 = dst_len;
- int src_len2 = 0;
- int pos = hw->rpos + dst_len;
- struct st_sample *src1 = hw->mix_buf + hw->rpos;
- struct st_sample *src2 = NULL;
-
- if (pos > hw->samples) {
- src_len1 = hw->samples - hw->rpos;
- src2 = hw->mix_buf;
- src_len2 = dst_len - src_len1;
- pos = src_len2;
- }
-
- if (src_len1) {
- hw->clip (dst, src1, src_len1);
- }
-
- if (src_len2) {
- dst = advance (dst, src_len1 << hw->info.shift);
- hw->clip (dst, src2, src_len2);
- }
-
- hw->rpos = pos % hw->samples;
-}
-
static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb,
dsound *s)
{
@@ -350,7 +310,7 @@ static void dsound_clear_sample (HWVoiceOut *hw, LPDIRECTSOUNDBUFFER dsb,
dsb,
&hw->info,
0,
- hw->samples << hw->info.shift,
+ hw->size_emul,
&p1, &p2,
&blen1, &blen2,
1,
@@ -454,139 +414,51 @@ static int dsound_ctl_out (HWVoiceOut *hw, int cmd, ...)
return 0;
}
-static size_t dsound_run_out(HWVoiceOut *hw, size_t live)
+static void *dsound_get_buffer_out(HWVoiceOut *hw, size_t *size)
{
- int err;
- HRESULT hr;
DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
- size_t len;
- int hwshift;
- DWORD blen1, blen2;
- DWORD len1, len2;
- DWORD decr;
- DWORD wpos, ppos, old_pos;
- LPVOID p1, p2;
- size_t bufsize;
- dsound *s = ds->s;
- AudiodevDsoundOptions *dso = &s->dev->u.dsound;
-
- if (!dsb) {
- dolog ("Attempt to run empty with playback buffer\n");
- return 0;
- }
-
- hwshift = hw->info.shift;
- bufsize = hw->samples << hwshift;
-
- hr = IDirectSoundBuffer_GetCurrentPosition (
- dsb,
- &ppos,
- ds->first_time ? &wpos : NULL
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get playback buffer position\n");
- return 0;
- }
-
- len = live << hwshift;
-
- if (ds->first_time) {
- if (dso->latency) {
- DWORD cur_blat;
+ HRESULT hr;
+ DWORD ppos, act_size;
+ size_t req_size;
+ int err;
+ void *ret;
- cur_blat = audio_ring_dist (wpos, ppos, bufsize);
- ds->first_time = 0;
- old_pos = wpos;
- old_pos +=
- usecs_to_bytes(&hw->info, dso->latency) - cur_blat;
- old_pos %= bufsize;
- old_pos &= ~hw->info.align;
- }
- else {
- old_pos = wpos;
- }
-#ifdef DEBUG_DSOUND
- ds->played = 0;
- ds->mixed = 0;
-#endif
+ hr = IDirectSoundBuffer_GetCurrentPosition(dsb, &ppos, NULL);
+ if (FAILED(hr)) {
+ dsound_logerr(hr, "Could not get playback buffer position\n");
+ *size = 0;
+ return NULL;
}
- else {
- if (ds->old_pos == ppos) {
-#ifdef DEBUG_DSOUND
- dolog ("old_pos == ppos\n");
-#endif
- return 0;
- }
-#ifdef DEBUG_DSOUND
- ds->played += audio_ring_dist (ds->old_pos, ppos, hw->bufsize);
-#endif
- old_pos = ds->old_pos;
- }
+ req_size = audio_ring_dist(ppos, hw->pos_emul, hw->size_emul);
+ req_size = MIN(req_size, hw->size_emul - hw->pos_emul);
- if ((old_pos < ppos) && ((old_pos + len) > ppos)) {
- len = ppos - old_pos;
- }
- else {
- if ((old_pos > ppos) && ((old_pos + len) > (ppos + bufsize))) {
- len = bufsize - old_pos + ppos;
- }
+ err = dsound_lock_out(dsb, &hw->info, hw->pos_emul, req_size, &ret, NULL,
+ &act_size, NULL, false, ds->s);
+ if (err) {
+ dolog("Failed to lock buffer\n");
+ *size = 0;
+ return NULL;
}
- if (audio_bug(__func__, len > bufsize)) {
- dolog("len=%zu bufsize=%zu old_pos=%ld ppos=%ld\n",
- len, bufsize, old_pos, ppos);
- return 0;
- }
+ *size = act_size;
+ return ret;
+}
- len &= ~hw->info.align;
- if (!len) {
- return 0;
- }
+static size_t dsound_put_buffer_out(HWVoiceOut *hw, void *buf, size_t len)
+{
+ DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
+ LPDIRECTSOUNDBUFFER dsb = ds->dsound_buffer;
+ int err = dsound_unlock_out(dsb, buf, NULL, len, 0);
-#ifdef DEBUG_DSOUND
- ds->old_ppos = ppos;
-#endif
- err = dsound_lock_out (
- dsb,
- &hw->info,
- old_pos,
- len,
- &p1, &p2,
- &blen1, &blen2,
- 0,
- s
- );
if (err) {
+ dolog("Failed to unlock buffer!!\n");
return 0;
}
+ hw->pos_emul = (hw->pos_emul + len) % hw->size_emul;
- len1 = blen1 >> hwshift;
- len2 = blen2 >> hwshift;
- decr = len1 + len2;
-
- if (p1 && len1) {
- dsound_write_sample (hw, p1, len1);
- }
-
- if (p2 && len2) {
- dsound_write_sample (hw, p2, len2);
- }
-
- dsound_unlock_out (dsb, p1, p2, blen1, blen2);
- ds->old_pos = (old_pos + (decr << hwshift)) % bufsize;
-
-#ifdef DEBUG_DSOUND
- ds->mixed += decr << hwshift;
-
- dolog ("played %lu mixed %lu diff %ld sec %f\n",
- ds->played,
- ds->mixed,
- ds->mixed - ds->played,
- abs (ds->mixed - ds->played) / (double) hw->info.bytes_per_second);
-#endif
- return decr;
+ return len;
}
static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...)
@@ -641,96 +513,49 @@ static int dsound_ctl_in (HWVoiceIn *hw, int cmd, ...)
return 0;
}
-static size_t dsound_run_in(HWVoiceIn *hw)
+static void *dsound_get_buffer_in(HWVoiceIn *hw, size_t *size)
{
- int err;
- HRESULT hr;
DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
- size_t live, len, dead;
- DWORD blen1, blen2;
- DWORD len1, len2;
- DWORD decr;
- DWORD cpos, rpos;
- LPVOID p1, p2;
- int hwshift;
- dsound *s = ds->s;
-
- if (!dscb) {
- dolog ("Attempt to run without capture buffer\n");
- return 0;
- }
-
- hwshift = hw->info.shift;
-
- live = audio_pcm_hw_get_live_in (hw);
- dead = hw->samples - live;
- if (!dead) {
- return 0;
- }
-
- hr = IDirectSoundCaptureBuffer_GetCurrentPosition (
- dscb,
- &cpos,
- ds->first_time ? &rpos : NULL
- );
- if (FAILED (hr)) {
- dsound_logerr (hr, "Could not get capture buffer position\n");
- return 0;
- }
-
- if (ds->first_time) {
- ds->first_time = 0;
- if (rpos & hw->info.align) {
- ldebug ("warning: Misaligned capture read position %ld(%d)\n",
- rpos, hw->info.align);
- }
- hw->wpos = rpos >> hwshift;
- }
+ HRESULT hr;
+ DWORD cpos, act_size;
+ size_t req_size;
+ int err;
+ void *ret;
- if (cpos & hw->info.align) {
- ldebug ("warning: Misaligned capture position %ld(%d)\n",
- cpos, hw->info.align);
+ hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dscb, &cpos, NULL);
+ if (FAILED(hr)) {
+ dsound_logerr(hr, "Could not get capture buffer position\n");
+ *size = 0;
+ return NULL;
}
- cpos >>= hwshift;
- len = audio_ring_dist (cpos, hw->wpos, hw->samples);
- if (!len) {
- return 0;
- }
- len = MIN (len, dead);
+ req_size = audio_ring_dist(cpos, hw->pos_emul, hw->size_emul);
+ req_size = MIN(req_size, hw->size_emul - hw->pos_emul);
- err = dsound_lock_in (
- dscb,
- &hw->info,
- hw->wpos << hwshift,
- len << hwshift,
- &p1,
- &p2,
- &blen1,
- &blen2,
- 0,
- s
- );
+ err = dsound_lock_in(dscb, &hw->info, hw->pos_emul, req_size, &ret, NULL,
+ &act_size, NULL, false, ds->s);
if (err) {
- return 0;
+ dolog("Failed to lock buffer\n");
+ *size = 0;
+ return NULL;
}
- len1 = blen1 >> hwshift;
- len2 = blen2 >> hwshift;
- decr = len1 + len2;
+ *size = act_size;
+ return ret;
+}
- if (p1 && len1) {
- hw->conv (hw->conv_buf + hw->wpos, p1, len1);
- }
+static void dsound_put_buffer_in(HWVoiceIn *hw, void *buf, size_t len)
+{
+ DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
+ LPDIRECTSOUNDCAPTUREBUFFER dscb = ds->dsound_capture_buffer;
+ int err = dsound_unlock_in(dscb, buf, NULL, len, 0);
- if (p2 && len2) {
- hw->conv (hw->conv_buf, p2, len2);
+ if (err) {
+ dolog("Failed to unlock buffer!!\n");
+ return;
}
-
- dsound_unlock_in (dscb, p1, p2, blen1, blen2);
- hw->wpos = (hw->wpos + decr) % hw->samples;
- return decr;
+ hw->pos_emul = (hw->pos_emul + len) % hw->size_emul;
}
static void dsound_audio_fini (void *opaque)
@@ -846,12 +671,16 @@ static void *dsound_audio_init(Audiodev *dev)
static struct audio_pcm_ops dsound_pcm_ops = {
.init_out = dsound_init_out,
.fini_out = dsound_fini_out,
- .run_out = dsound_run_out,
+ .write = audio_generic_write,
+ .get_buffer_out = dsound_get_buffer_out,
+ .put_buffer_out = dsound_put_buffer_out,
.ctl_out = dsound_ctl_out,
.init_in = dsound_init_in,
.fini_in = dsound_fini_in,
- .run_in = dsound_run_in,
+ .read = audio_generic_read,
+ .get_buffer_in = dsound_get_buffer_in,
+ .put_buffer_in = dsound_put_buffer_in,
.ctl_in = dsound_ctl_in
};