Module: wine
Branch: master
Commit: 0036298a140645e1aacd3a22c272647998ef09e0
URL: http://source.winehq.org/git/wine.git/?a=commit;h=0036298a140645e1aacd3a22c…
Author: Maarten Lankhorst <m.b.lankhorst(a)gmail.com>
Date: Wed Feb 21 20:16:22 2007 +0100
dsound: Add some comments from earlier patch that makes code a little better understandable.
---
dlls/dsound/mixer.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 90 insertions(+), 1 deletions(-)
diff --git a/dlls/dsound/mixer.c b/dlls/dsound/mixer.c
index 1597aa0..8eba8c0 100644
--- a/dlls/dsound/mixer.c
+++ b/dlls/dsound/mixer.c
@@ -98,6 +98,14 @@ void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb)
dsb->writelead = (dsb->freq / 100) * dsb->pwfx->nBlockAlign;
}
+/**
+ * Check for application callback requests for when the play position
+ * reaches certain points.
+ *
+ * The offsets that will be triggered will be those between the recorded
+ * "last played" position for the buffer (i.e. dsb->playpos) and "len" bytes
+ * beyond that position.
+ */
void DSOUND_CheckEvent(IDirectSoundBufferImpl *dsb, int len)
{
int i;
@@ -163,6 +171,10 @@ static inline BYTE cvtS16toU8(INT16 s)
return (s >> 8) ^ (unsigned char)0x80;
}
+/**
+ * Copy a single frame from the given input buffer to the given output buffer.
+ * Translate 8 <-> 16 bits and mono <-> stereo
+ */
static inline void cp_fields(const IDirectSoundBufferImpl *dsb, BYTE *ibuf, BYTE *obuf )
{
DirectSoundDevice * device = dsb->device;
@@ -209,7 +221,24 @@ static inline void cp_fields(const IDirectSoundBufferImpl *dsb, BYTE *ibuf, BYTE
}
}
-/* Now with PerfectPitch (tm) technology */
+/**
+ * Mix at most the given amount of data into the given device buffer from the
+ * given secondary buffer, starting from the dsb's first currently unmixed
+ * frame (buf_mixpos), translating frequency (pitch), stereo/mono and
+ * bits-per-sample. The secondary buffer sample is looped if it is not
+ * long enough and it is a looping buffer.
+ * (Doesn't perform any mixing - this is a straight copy operation).
+ *
+ * Now with PerfectPitch (tm) technology
+ *
+ * dsb = the secondary buffer
+ * buf = the device buffer
+ * len = number of bytes to store in the device buffer
+ *
+ * Returns: the number of bytes read from the secondary buffer
+ * (ie. len, adjusted for frequency, number of channels and sample size,
+ * and limited by buffer length for non-looping buffers)
+ */
static INT DSOUND_MixerNorm(IDirectSoundBufferImpl *dsb, BYTE *buf, INT len)
{
INT i, size, ipos, ilen;
@@ -356,6 +385,10 @@ static void DSOUND_MixerVol(IDirectSoundBufferImpl *dsb, BYTE *buf, INT len)
}
}
+/**
+ * Make sure the device's tmp_buffer is at least the given size. Return a
+ * pointer to it.
+ */
static LPBYTE DSOUND_tmpbuffer(DirectSoundDevice *device, DWORD len)
{
TRACE("(%p,%d)\n", device, len);
@@ -372,6 +405,19 @@ static LPBYTE DSOUND_tmpbuffer(DirectSoundDevice *device, DWORD len)
return device->tmp_buffer;
}
+/**
+ * Mix (at most) the given number of bytes into the given position of the
+ * device buffer, from the secondary buffer "dsb" (starting at the current
+ * mix position for that buffer).
+ *
+ * Returns the number of bytes actually mixed into the device buffer. This
+ * will match fraglen unless the end of the secondary buffer is reached
+ * (and it is not looping).
+ *
+ * dsb = the secondary buffer to mix from
+ * writepos = position (offset) in device buffer to write at
+ * fraglen = number of bytes to mix
+ */
static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWORD fraglen)
{
INT i, len, ilen, field, todo;
@@ -381,9 +427,15 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO
len = fraglen;
if (!(dsb->playflags & DSBPLAY_LOOPING)) {
+ /* This buffer is not looping, so make sure the requested
+ * length will not take us past the end of the buffer */
int secondary_remainder = dsb->buflen - dsb->buf_mixpos;
int adjusted_remainder = MulDiv(dsb->device->pwfx->nAvgBytesPerSec, secondary_remainder, dsb->nAvgBytesPerSec);
assert(adjusted_remainder >= 0);
+ /* The adjusted remainder must be at least one sample,
+ * otherwise we will never reach the end of the
+ * secondary buffer, as there will perpetually be a
+ * fractional remainder */
TRACE("secondary_remainder = %d, adjusted_remainder = %d, len = %d\n", secondary_remainder, adjusted_remainder, len);
if (adjusted_remainder < len) {
TRACE("clipping len to remainder of secondary buffer\n");
@@ -404,12 +456,16 @@ static DWORD DSOUND_MixInBuffer(IDirectSoundBufferImpl *dsb, DWORD writepos, DWO
TRACE("MixInBuffer (%p) len = %d, dest = %d\n", dsb, len, writepos);
+ /* first, copy the data from the DirectSoundBuffer into the temporary
+ buffer, translating frequency/bits-per-sample/number-of-channels
+ to match the device settings */
ilen = DSOUND_MixerNorm(dsb, ibuf, len);
if ((dsb->dsbd.dwFlags & DSBCAPS_CTRLPAN) ||
(dsb->dsbd.dwFlags & DSBCAPS_CTRLVOLUME) ||
(dsb->dsbd.dwFlags & DSBCAPS_CTRL3D))
DSOUND_MixerVol(dsb, ibuf, len);
+ /* Now mix the temporary buffer into the devices main buffer */
if (dsb->device->pwfx->wBitsPerSample == 8) {
BYTE *obuf = dsb->device->buffer + writepos;
@@ -667,8 +723,23 @@ void DSOUND_ForceRemix(IDirectSoundBufferImpl *dsb)
LeaveCriticalSection(&dsb->lock);
}
+/**
+ * Mix some frames from the given secondary buffer "dsb" into the device
+ * primary buffer.
+ *
+ * dsb = the secondary buffer
+ * playpos = the current play position in the device buffer (primary buffer)
+ * writepos = the current safe-to-write position in the device buffer
+ * mixlen = the maximum number of bytes in the primary buffer to mix, from the
+ * current writepos.
+ *
+ * Returns: the number of bytes beyond the writepos that were mixed.
+ */
static DWORD DSOUND_MixOne(IDirectSoundBufferImpl *dsb, DWORD playpos, DWORD writepos, DWORD mixlen)
{
+ /* The buffer's primary_mixpos may be before or after the the device
+ * buffer's mixpos, but both must be ahead of writepos. */
+
DWORD len, slen;
/* determine this buffer's write position */
DWORD buf_writepos = DSOUND_CalcPlayPosition(dsb, writepos, writepos);
@@ -823,6 +894,19 @@ post_mix:
return slen;
}
+/**
+ * For a DirectSoundDevice, go through all the currently playing buffers and
+ * mix them in to the device buffer.
+ *
+ * playpos = the current play position in the primary buffer
+ * writepos = the current safe-to-write position in the primary buffer
+ * mixlen = the maximum amount to mix into the primary buffer
+ * (beyond the current writepos)
+ * recover = true if the sound device may have been reset and the write
+ * position in the device buffer changed
+ *
+ * Returns: the length beyond the writepos that was mixed to.
+ */
static DWORD DSOUND_MixToPrimary(DirectSoundDevice *device, DWORD playpos, DWORD writepos, DWORD mixlen, BOOL recover)
{
INT i, len, maxlen = 0;
@@ -941,6 +1025,11 @@ void DSOUND_WaveQueue(DirectSoundDevice *device, DWORD mixq)
/* #define SYNC_CALLBACK */
+/**
+ * Perform mixing for a Direct Sound device. That is, go through all the
+ * secondary buffers (the sound bites currently playing) and mix them in
+ * to the primary buffer (the device buffer).
+ */
static void DSOUND_PerformMix(DirectSoundDevice *device)
{
int nfiller;
Module: wine
Branch: master
Commit: ba590a185ae00c51ae10e5bc93938991330d79f8
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ba590a185ae00c51ae10e5bc9…
Author: Rob Shearman <rob(a)codeweavers.com>
Date: Wed Feb 21 17:11:57 2007 +0000
wininet: Fix the case of partial SSL reads from the peek buffer.
Don't return FALSE for a partial read. Fall through to SSL_read and use
the logic for partial reads there instead of having separate logic and
recursively calling NETCON_recv. Based on a patch by Michael Moss.
---
dlls/wininet/netconnection.c | 20 ++++++--------------
1 files changed, 6 insertions(+), 14 deletions(-)
diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c
index 2418b97..ec2b18d 100644
--- a/dlls/wininet/netconnection.c
+++ b/dlls/wininet/netconnection.c
@@ -497,12 +497,10 @@ BOOL NETCON_send(WININET_NETCONNECTION *connection, const void *msg, size_t len,
BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int flags,
int *recvd /* out */)
{
+ *recvd = 0;
if (!NETCON_connected(connection)) return FALSE;
if (!len)
- {
- *recvd = 0;
return TRUE;
- }
if (!connection->useSSL)
{
*recvd = recv(connection->socketFD, buf, len, flags);
@@ -543,19 +541,13 @@ BOOL NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int f
HeapFree(GetProcessHeap(), 0, connection->peek_msg_mem);
connection->peek_msg_mem = NULL;
connection->peek_msg = NULL;
- /* check if the peek buffer held too few data */
- if ((flags & MSG_WAITALL) && (*recvd < len))
- {
- int recv2 = 0;
- /* recursive call - but now the peek buffer is empty */
- if (!NETCON_recv(connection, (char*)buf + *recvd, len - *recvd, flags, &recv2))
- return FALSE;
- *recvd += recv2;
- }
}
- return TRUE;
+ /* check if we got enough data from the peek buffer */
+ if (!(flags & MSG_WAITALL) || (*recvd == len))
+ return TRUE;
+ /* otherwise, fall through */
}
- *recvd = pSSL_read(connection->ssl_s, buf, len);
+ *recvd += pSSL_read(connection->ssl_s, (char*)buf + *recvd, len - *recvd);
if (flags & MSG_PEEK) /* must copy stuff into buffer */
{
connection->peek_len = *recvd;