summaryrefslogtreecommitdiff
path: root/notes/windows_network_audio.mdwn
blob: 28053707590cfac7d44cc40bc84a76d74481dc16 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# Windows Network Audio

Prerequisites:

* [Virtual Audio Cable][1]
* [Some Windows compile of SoX][2]
* [Some Windows compile of netcat][3]



## Getting a PCM UDP stream *out of* a Windows virtual audio device:

In [VAC][1], make cable 1, then make it the default audio device in mmsys.cpl.

On the receiving host, run something to the effect of

    nc -n -u -vvv -l -p $receiveport | aplay --buffer-size=1024

Though obviously we're not too picky. Anything that can understand a wave
header will do. aplay is simplest in my case. Normal Linux desktop or N900
users might want to use pacat instead of aplay.

On the sending (Windows) host, run something to the effect of

    sox --buffer=1024 -t waveaudio 1 -t wav - | nc -u $receivehost $receiveport



## Getting a PCM UDP stream *into* a Windows virtual audio device:

After three hours, static (from Windows) or silence (to Windows) arises instead
of the PCM stream expected. I assume this is a two or four gigabyte addressing
limit in 32-bit version of SoX. A 64-bit version needs testing.

If you want a separate (non-echoing) device for a microphone, make [VAC][1]
cable 2, then make it the default communications device in mmsys.cpl.

On the receiving (Windows) host, run something to the effect of

    nc -n -u -vvv -L -p $sendport | sox --buffer=2048 -t wav - -t waveaudio 1

On the sending host, run something to the effect of

    arecord --buffer-size=2048 --verbose -f cd - | nc -u $sendhost $sendport



## Additional notes

This was done on Windows 7. The core concepts should work fine on other
versions, though the details of making separate device defaults for playback
and recording will presumably be different.

The [SoX documentation][4]'s claim that `-t waveaudio` can match device names
did not pan out for me, so I had to work out their index number by hand. They
start from 0. In my case, it's 1.

Restarting any part of this sox/netcat/netcat/alsa chain requires restarting
everything *in order*, since that wave header is critical. You can probably
make the network half of this a bit more dynamic by manually specifying
a raw PCM format on both ends rather than relying on the wave header, but
you'd have to be careful to match the [VAC][1] settings in order to avoid
introducing resampling latency.

To make your life easier you might want to wrap the listening netcats in
`while sleep 1; do ; done`

Windows sometimes does something horrible to TCP buffering; if you value
latency, use UDP wherever practical. Raw PCM over UDP obviously has some
concerns; in heavy traffic it does not compete for bandwidth the way TCP does,
does not degrade to lower quality, and is difficult to secure. You can use
traffic shaping, encoding to voice codec, and/or DTLS to solve these problems.
On the plus side, dropped UDP packets do not seem to cause any sample
framing/alignment problems.

  [1]: http://software.muzychenko.net/eng/vac.htm
  [2]: http://sox.sourceforge.net/
  [3]: http://www.rodneybeede.com/Compile_Netcat_on_Windows_using_MinGW.html
  [4]: http://sox.sourceforge.net/soxformat.html