OpenWebRx and KiwiSDR added to Max/MSP control program

The Max remote receiver project described in an earlier post: now includes support for OpenWebRx and KiwiSDR sites.

When using OpenWebRx, you need to select a “profile” that supports the receive frequency range, before you can operate within that frequency.  Its an unusual system that uses an offset frequency within the selected profile, instead of a global “actual frequency” like the other platforms.

The KiwiSDR sites, in general, have very good quality reception and audio.

The next step in this project will be to consolidate a directory of sites that are useful for remote reception in the ham bands for various parts of the world.


See above linked post

Using hamlib to poll frequency data with Max/MSP

This Max patch connects to a radio transceiver and reads the frequency data using hamlib. Hamlib provides a common API for amateur radio devices. The hamllib server runs in the background using TCP/IP. This patch uses Jeremy Bernstein’s shell object. and the Sadam Library of externals, installed with the Max package manager.


hamlibtcptest1.maxpat : select radio, starts rigcltd dameon, poll frequency via tcp/ip : shell script to run rigctld


Max: Jeremy Bernstein’s shell external, and the sadam library from Max package manager.

hamlib can be installed using homebrew


There is some latency when using the Elecraft K4. Need to look into the internal CAT settings.

Also, look into communication latency of TCP/IP and associated libraries.

I’m exploring a version of this that uses node.js instead of the shell external and tcp/ip library in Max. Initial problem is that the rigctld daemon stays active after Max is closed and needs to get killed manually.

Detect amplifier keying line (PTT) with Arduino

Use an Arduino to detect transmit/receive state.

Using an Arduino Uno to detect the transmit state of a radio. The amplifier keying line (PTT) is grounded on transmit. The Arduino sees it as a switch being pulled low. The keying line is connected to digital input 2 (D2) and ground. The digital input uses the builtin pullup resistor. The sketch is the Arduino digital | input pullup example. Max polls the serial data from the Arduino and displays the state of the keying line.

Websdr as a remote receiver with Max/MSP and Elecraft K4

Remote receiver project using Websdr as a remote alternative to a local receiver.

Demonstration of a Max/MSP program that connects an amateur radio transceiver to Websdr – transmitting locally from Maine (USA) while receiving remotely using a radio in the Netherlands. The Max program reads the frequency from a Elecraft K4 transceiver, to control the Websdr sites. It also loads the remote receivers, controls audio routing, mode, filter, and waterfall display settings. An iPad, running touchOSC, acts a a control panel. Up to 4 remote receivers operate at the same time. Websdr is a remarkable system, developed by PA3FWM at It lets you control remote receivers worldwide, from your Web browser.


  • Max/MSP
  • Websdr
  • TouchOSC
  • Elecraft K4 transceiver with antenna system
  • Skookumlogger (logging software)

Max Patches:

websdrjweb7.maxpat : main control program. Contains [jweb] objects for launching websdr instances. Also code for injecting javascript to control parameters like frequency, filter, and volume. This patch acts as an intermediary between TouchOSC, WebSDR, and allows external MIDI control as well as getting frequency input from CAT controlled radios like the Elecraft K4.

websdrCATaudio.maxpat : handles serial port interaction for the K4. Also reads audio stream from either the K4 receiver (via USB) or the websdr receiver (via Blackhole.)  I created an aggregate audio device called K4sdr to allow Max to read both devices at the same time. Audio switching and levels are handled using a Korg nanoControl2. For example to switch between the audio streams or listen to both.

Optional: arduino-ptt-detect2.maxpat : reads serial data from an Arduino, connected to the amplifier keying line, to determine whether the radio is in transmit mode, so we can switch back to the local audio stream to eliminate latency of hearing your signal via websdr. See subsequent post about this setup…


websdrCW3.touchOSC : controls all 4 websdr channels, ie,., volume, mute, filter, CW offset, filtershift, – Also handles window management, loading js code, zoom in/out websdr and selecting channel waterfall views or Max code views.

CW Offset

websdr doesn’t have a control for CW pitch offset. To sync the frequency of the K4, the websdr is run in LSB mode with a frequency offset equal to the CW pitch setting in the transceiver. eg., 450 Hz. This works for most of the websdr sites, but unfortunately some of the sdr’s are off-frequency. You can usually compensate by adjusting the CWfreqOffset for that channel (in Max or TouchOSC).

Setting the offset also requires shifting the filter so it is centered over the actual signal.


This is currently a work in progress, not available on Github. Local files are in max teaching examples folder.

Capturing App/Screen video with Syphon and NDI

How to get video from applications, like a web browser, into Syphon.

This example shows how to get a Youtube video from Firefox into Max/MSP Vizzie.

  • Use NDI Scan Converter (From NDI Tools ) and select Firefox from the Capture menu
  • Use NDISyphon to convert the NDI stream to Syphon. Use virtual audio routing (eg., black hole) for system audio, or route audio directly into Max.

  • In Max, use the Syphon client from the package manager to receive video. Here is an example using Vizzie abstractions described in previous posts:


NDI scan converter allows screen capture from apps and broadcasts in NDI format over the LAN. Then NDISyphon app converts NDI stream into Syphon. For youtube, use theatre mode to fill the window – full screen doesn’t really work. see this link:

Recording Ableton Videosync output

Video recording options for Videosync in Ableton Live

Syphon Recorder.

  1. In Videosync preferences, set master Syphon out.
  2. In syphonrecorder set Videosync master as input.
  3. In syphonrecorder set virtual audio as input (eg., blackhole 2ch)
  4. In Ableton, set blackhole 2ch as audio output (or make a multioutput device in audoMidiSetup, combining headphones and blackhole.)

Vizzie Recorder.

(see this post about Vizzie Syphon abstractions

  1. setup a Syphon client in Max
  2. Use abstractions to bring video into Vizzie. and use Vizzie recorder object.
  3. Route audio as described above.

Screenflick (or other screen recording software)

  1. Set screenflick to overlay videosync output window in Ableton Live
  2. Route audio as described above.

11 Km feedback delay

Using 40 meter SSB, Max/MSP, and Websdr to build a feedback delay from Maine to the Netherlands.

A Max patch plays an audio file into the transmitter in Maine. Then, using a websdr receiver in the Netherlands, the received signal is amplified and mixed back into the audio to be retransmitted. Effectively creating a feedback delay line.

Here is an example of what it sounds like on 40 meters.

This is the Max patch

The audio from Websdr is routed to the input of Max by creating a multi-output device (In Audio Midi Setup) combining “Blackhole 2ch” and external headphone output (for monitoring). The audio output of Max is assigned to the transmitter SSB input.

Patch not yet available. Local version is in max teaching examples.

Max/MSP Vizzie abstractions for Syphon

Vizzie objects can connect directly to Syphon clients and servers.

(work in progress – not available yet)

Syphon video as input to Vizzie

vizziesyphonclient.maxpat that gets syphon into vizzie. look at vizzieexamplewithsyphon.maxpat to see how it works.

Syphon as output from Vizzie

Use vizziesyphonserver.maxpat. Example: vizzieexamplewithsyphonserver.maxpat

(local files in maxteachingexamples)

X API update

Attempts to use the X API (formerly Twitter) for projects with Max/MSP have been disappointing at best. Most of the API is behind a paywall now.  The cost is $5000 per month. to implement streaming API used in projects like this:

The free tier only allows basic tweeting and user lookup. Search is not available.

I was able to find only one node example that actually worked in the free tier. By “Coding with Ado”. The code requests a token from X, and then you enter a timestamped pin number to continue. Making it worthless for programs and bots.

A local copy of the source code for this is in tkzic/nodetweet3/index.js

Other options

Another option with X, is to use a service like Socialdata.

There service sits in the middle to handle X API calls. You are charged by the number of calls. It doesn’t offer streaming either, but you can simulate it by calling a search every few seconds.

Other social media options

There are API’s for other social sites like facebook, instagram, tiktok, etc.,

Virtual serial port pairs in Mac OSx

I was unable to find any apps to create virtual serial ports for later versions of Mac OSx eg., Catalina.

There is a partial solution using the linux socat utility. It will create functioning vsp’s but the ports will not be detected by most apps, like Max/MSP.  I tried setting a symlink to files in /dev using tty. and cu. prefixes. eg., /dev/tty.x1. But apps that look for serial ports still couldn’t detect the vsp’s.


  1. download and install socat using macports or brew. eg., “sudo port install socat”
  2. Disable SIP (system integrity protection). In Catalina, reboot holding cmd+r. Then type: “csrutil disable” into a terminal window. Reboot – Note: you probably don’t need to do this if you aren’t setting up a link in /dev – which so far doesn’t work anyway
  3. Run one of the following commands:

socat -d -d pty,raw,echo=0 pty,raw,echo=0

sudo socat -d -d pty,link=/dev/tty.x0,raw,echo=0,user=tkzic,group=staff pty,link=/dev/tty.x1,raw,echo=0,user=tkzic,group=staff

What works and what doesn’t

After setting up the ports, you can send data in one port and out the other, for example, type the following into 2 different terminal windows.

cat /dev/ttys004

echo “Hello World” > /dev/cu.x1

This works great. But, so far, using sym links – the ports don’t show up in any app that accesses serial ports. Still working on this…

Using socat you can also setup a serial/tcp pair – this may be a solution for some projects.