diff --git a/mirror.c b/mirror.c index f6fdec7..e72fa05 100644 --- a/mirror.c +++ b/mirror.c @@ -261,87 +261,83 @@ bool mirror(IMMDevice *monitor, IMMDevice *output) break; } - UINT32 padding = 0; - - if ((res = out_client->lpVtbl->GetCurrentPadding(out_client, &padding)) != S_OK) - { - fprintf(stderr, "Failed to get current padding of output client! [0x%08lx]\n", res); - goto out; - } - - UINT32 packet_size = 0; - - if ((res = capture->lpVtbl->GetNextPacketSize(capture, &packet_size)) != S_OK) + for (;;) { - fprintf(stderr, "Failed to get next packet size of monitor client! [0x%08lx]\n", res); - goto out; - } - - fprintf(stderr, "packet_size = %d, buffer_size = %d, padding = %d\n", packet_size, buffer_size, padding); - - BYTE *mon_data = NULL; - BYTE *out_data = NULL; - UINT32 frames = 0; - DWORD flags = 0; - - if (packet_size > buffer_size - padding) - { - if ((res = capture->lpVtbl->GetBuffer(capture, &mon_data, &frames, &flags, - NULL, NULL)) != S_OK) - { - fprintf(stderr, "Failed to get capture buffer of monitor client! [0x%08lx]\n", res); - goto out; - } + UINT32 padding = 0; - if ((res = capture->lpVtbl->ReleaseBuffer(capture, 0)) != S_OK) + if ((res = out_client->lpVtbl->GetCurrentPadding(out_client, &padding)) != S_OK) { - fprintf(stderr, "Failed to release capture buffer of monitor client! [0x%08lx]\n", res); + fprintf(stderr, "Failed to get current padding of output client! [0x%08lx]\n", res); goto out; } - } - else if (packet_size > 0) - { - if ((res = capture->lpVtbl->GetBuffer(capture, &mon_data, &frames, &flags, - NULL, NULL)) != S_OK) - { - fprintf(stderr, "Failed to get capture buffer of monitor client! [0x%08lx]\n", res); - goto out; - } + UINT32 packet_size = 0; - if ((res = render->lpVtbl->GetBuffer(render, frames, &out_data)) != S_OK) + if ((res = capture->lpVtbl->GetNextPacketSize(capture, &packet_size)) != S_OK) { - fprintf(stderr, "Failed to get render buffer of output client! [0x%08lx]\n", res); + fprintf(stderr, "Failed to get next packet size of monitor client! [0x%08lx]\n", res); goto out; } - CopyMemory(out_data, mon_data, frames * format->nBlockAlign); + fprintf(stderr, "packet_size = %d, buffer_size = %d, padding = %d\n", packet_size, buffer_size, padding); - if ((res = capture->lpVtbl->ReleaseBuffer(capture, frames)) != S_OK) + BYTE *mon_data = NULL; + BYTE *out_data = NULL; + UINT32 frames = 0; + DWORD flags = 0; + + if (packet_size == 0) { - fprintf(stderr, "Failed to release capture buffer of monitor client! [0x%08lx]\n", res); - goto out; + // no input data, play silence + + if ((res = render->lpVtbl->GetBuffer(render, buffer_size - padding, &out_data)) != S_OK) + { + fprintf(stderr, "Failed to get render buffer of output client! [0x%08lx]\n", res); + goto out; + } + + if ((res = render->lpVtbl->ReleaseBuffer(render, buffer_size - padding, + AUDCLNT_BUFFERFLAGS_SILENT)) != S_OK) + { + fprintf(stderr, "Failed to release render buffer of output client! [0x%08lx]\n", res); + goto out; + } + + break; } - - if ((res = render->lpVtbl->ReleaseBuffer(render, frames, 0)) != S_OK) + else if (packet_size > buffer_size - padding) { - fprintf(stderr, "Failed to release render buffer of output client! [0x%08lx]\n", res); - goto out; + // output buffer is full, we have to wait + break; } - } - else - { - if ((res = render->lpVtbl->GetBuffer(render, buffer_size - padding, &out_data)) != S_OK) + else { - fprintf(stderr, "Failed to get render buffer of output client! [0x%08lx]\n", res); - goto out; - } - - if ((res = render->lpVtbl->ReleaseBuffer(render, buffer_size - padding, - AUDCLNT_BUFFERFLAGS_SILENT)) != S_OK) - { - fprintf(stderr, "Failed to release render buffer of output client! [0x%08lx]\n", res); - goto out; + if ((res = capture->lpVtbl->GetBuffer(capture, &mon_data, &frames, &flags, + NULL, NULL)) != S_OK) + { + fprintf(stderr, "Failed to get capture buffer of monitor client! [0x%08lx]\n", res); + goto out; + } + + if ((res = render->lpVtbl->GetBuffer(render, frames, &out_data)) != S_OK) + { + fprintf(stderr, "Failed to get render buffer of output client! [0x%08lx]\n", res); + goto out; + } + + CopyMemory(out_data, mon_data, frames * format->nBlockAlign); + + if ((res = capture->lpVtbl->ReleaseBuffer(capture, frames)) != S_OK) + { + fprintf(stderr, "Failed to release capture buffer of monitor client! [0x%08lx]\n", res); + goto out; + } + + if ((res = render->lpVtbl->ReleaseBuffer(render, frames, 0)) != S_OK) + { + fprintf(stderr, "Failed to release render buffer of output client! [0x%08lx]\n", res); + goto out; + } } } }