static void CALLBACK DSOUND_capture_timer(UINT timerID, UINT msg, DWORD_PTR user, DWORD_PTR dw1, DWORD_PTR dw2) { DirectSoundCaptureDevice *device = (DirectSoundCaptureDevice*)user; UINT32 packet_frames, packet_bytes, avail_bytes, skip_bytes = 0; DWORD flags; BYTE *buf; HRESULT hr; if(!device->ref) return; EnterCriticalSection(&device->lock); if(!device->capture_buffer || device->state == STATE_STOPPED){ LeaveCriticalSection(&device->lock); return; } if(device->state == STATE_STOPPING){ device->state = STATE_STOPPED; LeaveCriticalSection(&device->lock); return; } if(device->state == STATE_STARTING) device->state = STATE_CAPTURING; hr = IAudioCaptureClient_GetBuffer(device->capture, &buf, &packet_frames, &flags, NULL, NULL); if(FAILED(hr)){ LeaveCriticalSection(&device->lock); WARN("GetBuffer failed: %08x\n", hr); return; } packet_bytes = packet_frames * device->pwfx->nBlockAlign; if(packet_bytes > device->buflen){ TRACE("audio glitch: dsound buffer too small for data\n"); skip_bytes = packet_bytes - device->buflen; packet_bytes = device->buflen; } avail_bytes = device->buflen - device->write_pos_bytes; if(avail_bytes > packet_bytes) avail_bytes = packet_bytes; memcpy(device->buffer + device->write_pos_bytes, buf + skip_bytes, avail_bytes); capture_CheckNotify(device->capture_buffer, device->write_pos_bytes, avail_bytes); packet_bytes -= avail_bytes; if(packet_bytes > 0){ if(device->capture_buffer->flags & DSCBSTART_LOOPING){ memcpy(device->buffer, buf + skip_bytes + avail_bytes, packet_bytes); capture_CheckNotify(device->capture_buffer, 0, packet_bytes); }else{ device->state = STATE_STOPPED; capture_CheckNotify(device->capture_buffer, 0, 0); } } device->write_pos_bytes += avail_bytes + packet_bytes; device->write_pos_bytes %= device->buflen; hr = IAudioCaptureClient_ReleaseBuffer(device->capture, packet_frames); if(FAILED(hr)){ LeaveCriticalSection(&device->lock); WARN("ReleaseBuffer failed: %08x\n", hr); return; } LeaveCriticalSection(&device->lock); }
static HRESULT DSOUND_capture_data(DirectSoundCaptureDevice *device) { HRESULT hr; UINT32 packet_frames, packet_bytes, avail_bytes, skip_bytes = 0; DWORD flags; BYTE *buf; if(!device->capture_buffer || device->state == STATE_STOPPED) return S_FALSE; if(device->state == STATE_STOPPING){ device->state = STATE_STOPPED; return S_FALSE; } if(device->state == STATE_STARTING) device->state = STATE_CAPTURING; hr = IAudioCaptureClient_GetBuffer(device->capture, &buf, &packet_frames, &flags, NULL, NULL); if(FAILED(hr)){ WARN("GetBuffer failed: %08x\n", hr); return hr; } packet_bytes = packet_frames * device->pwfx->nBlockAlign; if(packet_bytes > device->buflen){ TRACE("audio glitch: dsound buffer too small for data\n"); skip_bytes = packet_bytes - device->buflen; packet_bytes = device->buflen; } avail_bytes = device->buflen - device->write_pos_bytes; if(avail_bytes > packet_bytes) avail_bytes = packet_bytes; memcpy(device->buffer + device->write_pos_bytes, buf + skip_bytes, avail_bytes); capture_CheckNotify(device->capture_buffer, device->write_pos_bytes, avail_bytes); packet_bytes -= avail_bytes; if(packet_bytes > 0){ if(device->capture_buffer->flags & DSCBSTART_LOOPING){ memcpy(device->buffer, buf + skip_bytes + avail_bytes, packet_bytes); capture_CheckNotify(device->capture_buffer, 0, packet_bytes); }else{ device->state = STATE_STOPPED; capture_CheckNotify(device->capture_buffer, 0, 0); } } device->write_pos_bytes += avail_bytes + packet_bytes; device->write_pos_bytes %= device->buflen; hr = IAudioCaptureClient_ReleaseBuffer(device->capture, packet_frames); if(FAILED(hr)){ WARN("ReleaseBuffer failed: %08x\n", hr); return hr; } return S_OK; }