//-------------------------------------------------------------------------------------------------- BOOL CSoundStream::Decompress(unsigned char *dest) { u32 dwSrcSize = dwSrcBufSize; BOOL r = true; VERIFY (hAcmStream); // check for EOF if (dwDecPos+dwSrcSize>dwTotalSize) { dwSrcSize=dwTotalSize-dwDecPos; r=false; } hf->r (WaveSource,dwSrcSize); stream.cbStruct=sizeof(stream); stream.fdwStatus=0; stream.pbSrc=WaveSource; stream.cbSrcLength=dwSrcSize; stream.pbDst=dest; stream.cbDstLength=dwDestBufSize; CHK_DX(acmStreamPrepareHeader(hAcmStream,&stream,0)); CHK_DX(acmStreamConvert(hAcmStream,&stream,0)); CHK_DX(acmStreamUnprepareHeader(hAcmStream,&stream,0)); dwDecPos+=stream.cbSrcLengthUsed; AppWriteDataToBuffer(writepos,WaveDest,stream.cbDstLengthUsed); return r; }
/* * DirectSound capture and playback thread. */ static int dsound_dev_thread(void *arg) { pjmedia_snd_stream *strm = arg; HANDLE events[3]; unsigned eventCount; unsigned bytes_per_frame; pj_status_t status; eventCount = 0; events[eventCount++] = strm->thread_quit_event; if (strm->dir & PJMEDIA_DIR_PLAYBACK) events[eventCount++] = strm->play_strm.hEvent; if (strm->dir & PJMEDIA_DIR_CAPTURE) events[eventCount++] = strm->rec_strm.hEvent; /* Raise self priority. We don't want the audio to be distorted by * system activity. */ 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 objects to be * signalled by DirectSound capture and play buffer. */ while (PJ_TRUE) { DWORD rc; pjmedia_dir signalled_dir; rc = WaitForMultipleObjects(eventCount, events, FALSE, INFINITE); if (rc < WAIT_OBJECT_0 || rc >= WAIT_OBJECT_0+eventCount) continue; if (rc == WAIT_OBJECT_0) break; if (rc == (WAIT_OBJECT_0 + 1)) { if (events[1] == strm->play_strm.hEvent) signalled_dir = PJMEDIA_DIR_PLAYBACK; else signalled_dir = PJMEDIA_DIR_CAPTURE; } else { if (events[2] == strm->play_strm.hEvent) signalled_dir = PJMEDIA_DIR_PLAYBACK; else signalled_dir = PJMEDIA_DIR_CAPTURE; } 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; status = PJ_SUCCESS; while (dsound_play_empty_size(dsound_strm) > bytes_per_frame) { /* Get frame from application. */ status = (*strm->play_cb)(strm->user_data, dsound_strm->timestamp.u32.lo, strm->buffer, bytes_per_frame); if (status != PJ_SUCCESS) break; /* Write to DirectSound buffer. */ AppWriteDataToBuffer( dsound_strm->ds.play.lpDsBuffer, dsound_strm->dwBytePos, (LPBYTE)strm->buffer, 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; /* Fetch while we have more than 1 frame */ while (dsound_captured_size(dsound_strm) > bytes_per_frame) { /* Capture from DirectSound buffer. */ rc = AppReadDataFromBuffer(dsound_strm->ds.capture.lpDsBuffer, dsound_strm->dwBytePos, (LPBYTE)strm->buffer, bytes_per_frame); if (!rc) { pj_bzero(strm->buffer, 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; } } } on_error: PJ_LOG(5,(THIS_FILE, "DirectSound: thread stopping..")); return 0; }