<div dir="ltr">This is the code that I cobbled together from your post, <a href="https://askubuntu.com/questions/60837">https://askubuntu.com/questions/60837</a> and  <a href="https://aweirdimagination.net/2020/07/19/virtual-microphone-using-gstreamer-and-pulseaudio/">https://aweirdimagination.net/2020/07/19/virtual-microphone-using-gstreamer-and-pulseaudio/</a><div><br></div><div>pactl load-module module-combine-sink \<br>sink_name=Web_Speech_Sink slaves=$(pacmd list-sinks | grep -A1 "* index" | grep -oP "<\K[^ >]+") \<br>sink_properties=device.description="Web_Speech_Stream" \<br>format=s16le \<br>channels=1 \<br>rate=22050<br><br>pactl move-sink-input $(pacmd list-sink-inputs|tac|perl -E'undef$/;$_=<>;/speech-dispatcher-espeak-ng.*?index: (\d+)\n/s;say $1') Web_Speech_Sink<br><br>pactl load-module module-remap-source \ master=Web_Speech_Sink.monitor \ source_name=Web_Speech_Monitor \ source_properties=device.description=Web_Speech_Output<br></div><div><br></div><div>Using this approach I am able to capture output from only speech-dispatcher-espeak-ng module using</div><div><br></div><div>navigator.mediaDevices.getUserMedia({audio: true})<br>.then(async stream => {<br>  const [track] = stream.getAudioTracks();<br>  const devices = await navigator.mediaDevices.enumerateDevices();<br>  const device = devices.find(({label}) => label === 'Web_Speech_Output');<br>  track.stop();<br>  console.log(devices, device);<br>  return navigator.mediaDevices.getUserMedia({audio: {deviceId: {exact: device.deviceId}}});<br>})<br>.then(stream => {<br>  const recorder = new MediaRecorder(stream);<br>  recorder.ondataavailable = e => console.log(URL.createObjectURL(e.data));<br>  const synth = speechSynthesis;<br>  const u = new SpeechSynthesisUtterance('test, test, then test again');<br>  u.onstart = e => {<br>    recorder.start();<br>    console.log(e);<br>  }<br>  u.onend = e => {<br>    recorder.stop();<br>    recorder.stream.getTracks().forEach(track => track.stop());<br>    console.log(e);<br>  }<br>  synth.speak(u);<br>});<br></div><div><br></div><div>Can the pactl and pacmd code be reduced?</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Dec 22, 2020 at 2:53 AM Arun Raghavan <<a href="mailto:arun@arunraghavan.net">arun@arunraghavan.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Mon, 21 Dec 2020, at 9:52 AM, guest271314 wrote:<br>
> A virtual microphone can be created using module-remap-source <br>
> <a href="https://aweirdimagination.net/2020/07/19/virtual-microphone-using-gstreamer-and-pulseaudio/" rel="noreferrer" target="_blank">https://aweirdimagination.net/2020/07/19/virtual-microphone-using-gstreamer-and-pulseaudio/</a><br>
> <br>
> pactl load-module module-remap-source \ master=virtmic.monitor <br>
> source_name=virtmic \ <br>
> source_properties=device.description=Virtual_Microphone<br>
> <br>
> AFAICT a sink-input cannot be set as the source for the virtual microphone.<br>
> <br>
> A sink-input can be recorded using parec or parecord --monitor-stream option<br>
> <br>
> parecord -v -r --monitor-stream=26 --file-format=wav output.wav<br>
>  <br>
> How to set a sink-input as source for the virtual microphone so that <br>
> the output of the sink-input is still played back to speakers or <br>
> headphones and simultaneously is the source of the virtual microphone?<br>
<br>
You could use module-combine-sink to play that sink input to a null-sink and the real sink, and then use the null-sink's monitor as your source.<br>
<br>
-- Arun<br>
_______________________________________________<br>
pulseaudio-discuss mailing list<br>
<a href="mailto:pulseaudio-discuss@lists.freedesktop.org" target="_blank">pulseaudio-discuss@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss</a><br>
</blockquote></div>