summaryrefslogtreecommitdiff
path: root/pjmedia
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2006-05-21 19:00:15 +0000
committerBenny Prijono <bennylp@teluu.com>2006-05-21 19:00:15 +0000
commitfec5604eb97ea29186af9581d138810d9ecca2c8 (patch)
tree2c1a6de1611445364737912b26e55508a4f6efcd /pjmedia
parentb929a8227926e7f81247d3d7e8a880f229f01ce4 (diff)
DirectSound capture device queries stream position and retrieves any captured frames
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@463 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjmedia')
-rw-r--r--pjmedia/src/pjmedia/dsound.c143
-rw-r--r--pjmedia/src/pjmedia/sound_port.c2
2 files changed, 98 insertions, 47 deletions
diff --git a/pjmedia/src/pjmedia/dsound.c b/pjmedia/src/pjmedia/dsound.c
index 27d74318..a2e2c9c8 100644
--- a/pjmedia/src/pjmedia/dsound.c
+++ b/pjmedia/src/pjmedia/dsound.c
@@ -99,6 +99,7 @@ struct pjmedia_snd_stream
struct dsound_stream rec_strm; /**< Capture stream. */
void *buffer; /**< Temp. frame buffer. */
+ unsigned clock_rate; /**< Clock rate. */
unsigned samples_per_frame; /**< Samples per frame. */
pj_thread_t *thread; /**< Thread handle. */
@@ -232,9 +233,11 @@ static pj_status_t init_player_stream( struct dsound_stream *ds_strm,
/* Done setting up play device. */
PJ_LOG(5,(THIS_FILE,
- " DirectSound player stream initialized (clock_rate=%d, "
- "channel_count=%d, samples_per_frame=%d",
- clock_rate, channel_count, samples_per_frame));
+ " DirectSound player \"%s\" initialized (clock_rate=%d, "
+ "channel_count=%d, samples_per_frame=%d (%dms))",
+ dev_info[dev_id].info.name,
+ clock_rate, channel_count, samples_per_frame,
+ samples_per_frame * 1000 / clock_rate));
return PJ_SUCCESS;
}
@@ -335,9 +338,11 @@ static pj_status_t init_capture_stream( struct dsound_stream *ds_strm,
/* Done setting up recorder device. */
PJ_LOG(5,(THIS_FILE,
- " DirectSound capture stream initialized (clock_rate=%d, "
- "channel_count=%d, samples_per_frame=%d",
- clock_rate, channel_count, samples_per_frame));
+ " DirectSound capture \"%s\" initialized (clock_rate=%d, "
+ "channel_count=%d, samples_per_frame=%d (%dms))",
+ dev_info[dev_id].info.name,
+ clock_rate, channel_count, samples_per_frame,
+ samples_per_frame * 1000 / clock_rate));
return PJ_SUCCESS;
}
@@ -416,13 +421,37 @@ static BOOL AppWriteDataToBuffer(LPDIRECTSOUNDBUFFER lpDsb, // The buffer.
/*
- * Player thread.
+ * Check if there are captured frames in DirectSound capture buffer.
+ */
+static unsigned dsound_captured_size(struct dsound_stream *dsound_strm)
+{
+ HRESULT hr;
+ long size_available;
+ DWORD writePos, readPos;
+
+ hr = IDirectSoundCaptureBuffer_GetCurrentPosition(dsound_strm->ds.capture.lpDsBuffer,
+ &writePos, &readPos);
+ if FAILED(hr)
+ return PJ_FALSE;
+
+ if (readPos < dsound_strm->dwBytePos)
+ size_available = readPos +
+ (dsound_strm->dwDsBufferSize) - dsound_strm->dwBytePos;
+ else
+ size_available = readPos - dsound_strm->dwBytePos;
+
+ return size_available;
+}
+
+/*
+ * DirectSound capture and playback thread.
*/
static int dsound_dev_thread(void *arg)
{
pjmedia_snd_stream *strm = arg;
HANDLE events[2];
unsigned eventCount;
+ unsigned bytes_per_frame;
pj_status_t status;
@@ -434,20 +463,22 @@ static int dsound_dev_thread(void *arg)
/* Raise self priority */
- SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
+ //SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
+
+ /* Calculate bytes per frame */
+ bytes_per_frame = strm->samples_per_frame * BYTES_PER_SAMPLE;
/*
- * Loop while not signalled to quit, wait for event object to be signalled
- * by DirectSound play buffer, then request for sound data from the
- * application and write it to DirectSound buffer.
+ * Loop while not signalled to quit, wait for event objects to be
+ * signalled by DirectSound capture and play buffer.
*/
while (!strm->thread_quit_flag) {
DWORD rc;
pjmedia_dir signalled_dir;
- struct dsound_stream *dsound_strm;
- rc = WaitForMultipleObjects(eventCount, events, FALSE, 100);
+ rc = WaitForMultipleObjects(eventCount, events, FALSE,
+ 100);
if (rc < WAIT_OBJECT_0 || rc >= WAIT_OBJECT_0+eventCount)
continue;
@@ -467,14 +498,20 @@ static int dsound_dev_thread(void *arg)
if (signalled_dir == PJMEDIA_DIR_PLAYBACK) {
+ struct dsound_stream *dsound_strm;
+
+ /*
+ * DirectSound has requested us to feed some frames to
+ * playback buffer.
+ */
+
dsound_strm = &strm->play_strm;
/* Get frame from application. */
status = (*strm->play_cb)(strm->user_data,
dsound_strm->timestamp.u32.lo,
strm->buffer,
- strm->samples_per_frame *
- BYTES_PER_SAMPLE);
+ bytes_per_frame);
if (status != PJ_SUCCESS)
break;
@@ -482,48 +519,60 @@ static int dsound_dev_thread(void *arg)
AppWriteDataToBuffer( dsound_strm->ds.play.lpDsBuffer,
dsound_strm->dwBytePos,
(LPBYTE)strm->buffer,
- strm->samples_per_frame * BYTES_PER_SAMPLE);
+ bytes_per_frame);
+
+ /* Increment position. */
+ dsound_strm->dwBytePos += bytes_per_frame;
+ if (dsound_strm->dwBytePos >= dsound_strm->dwDsBufferSize)
+ dsound_strm->dwBytePos -= dsound_strm->dwDsBufferSize;
+ dsound_strm->timestamp.u64 += strm->samples_per_frame;
} else {
+ /*
+ * DirectSound has indicated that it has some frames ready
+ * in the capture buffer. Get as much frames as possible to
+ * prevent overflows.
+ */
+ struct dsound_stream *dsound_strm;
BOOL rc;
dsound_strm = &strm->rec_strm;
- /* Capture from DirectSound buffer. */
- rc = AppReadDataFromBuffer(dsound_strm->ds.capture.lpDsBuffer,
- dsound_strm->dwBytePos,
- (LPBYTE)strm->buffer,
- strm->samples_per_frame *
- BYTES_PER_SAMPLE);
-
- if (!rc) {
- pj_memset(strm->buffer, 0, strm->samples_per_frame *
- BYTES_PER_SAMPLE);
- }
-
- /* Call callback */
- status = (*strm->rec_cb)(strm->user_data,
- dsound_strm->timestamp.u32.lo,
- strm->buffer,
- strm->samples_per_frame *
- BYTES_PER_SAMPLE);
-
- /* Quit thread on error. */
- if (status != PJ_SUCCESS)
- break;
-
+ do {
+ /* Capture from DirectSound buffer. */
+ rc = AppReadDataFromBuffer(dsound_strm->ds.capture.lpDsBuffer,
+ dsound_strm->dwBytePos,
+ (LPBYTE)strm->buffer,
+ bytes_per_frame);
+
+ if (!rc) {
+ pj_memset(strm->buffer, 0, bytes_per_frame);
+ }
+
+ /* Call callback */
+ status = (*strm->rec_cb)(strm->user_data,
+ dsound_strm->timestamp.u32.lo,
+ strm->buffer,
+ bytes_per_frame);
+
+ /* Quit thread on error. */
+ if (status != PJ_SUCCESS)
+ goto on_error;
+
+
+ /* Increment position. */
+ dsound_strm->dwBytePos += bytes_per_frame;
+ if (dsound_strm->dwBytePos >= dsound_strm->dwDsBufferSize)
+ dsound_strm->dwBytePos -= dsound_strm->dwDsBufferSize;
+ dsound_strm->timestamp.u64 += strm->samples_per_frame;
+
+ } while (dsound_captured_size(dsound_strm) >= bytes_per_frame);
}
-
- /* Increment position. */
- dsound_strm->dwBytePos += strm->samples_per_frame * BYTES_PER_SAMPLE;
- if (dsound_strm->dwBytePos >= dsound_strm->dwDsBufferSize)
- dsound_strm->dwBytePos -= dsound_strm->dwDsBufferSize;
- dsound_strm->timestamp.u64 += strm->samples_per_frame;
}
+on_error:
PJ_LOG(5,(THIS_FILE, "DirectSound: thread stopping.."));
-
return 0;
}
@@ -669,7 +718,7 @@ static pj_status_t open_stream( pjmedia_dir dir,
strm->rec_cb = rec_cb;
strm->play_cb = play_cb;
strm->user_data = user_data;
-
+ strm->clock_rate = clock_rate;
strm->samples_per_frame = samples_per_frame;
strm->buffer = pj_pool_alloc(pool, samples_per_frame * BYTES_PER_SAMPLE);
if (!strm->buffer) {
diff --git a/pjmedia/src/pjmedia/sound_port.c b/pjmedia/src/pjmedia/sound_port.c
index 016bdecf..0d82fee2 100644
--- a/pjmedia/src/pjmedia/sound_port.c
+++ b/pjmedia/src/pjmedia/sound_port.c
@@ -116,6 +116,8 @@ no_frame:
#ifdef SIMULATE_LOST_PCT
PJ_LOG(4,(THIS_FILE, "Lost frame generated"));
#endif
+ } else {
+ pj_memset(output, 0, size);
}