Generic SDR realtime IQ converter

With CubicSDR, HAMLIB, and Max

update: 1/25/2021 – Using this general setup with Airspy, CubicSDR, rigctld, and netcat (nc) to send IQ data into the basicSDR3.maxpat patch

CubicSDR uses the SoapySDR library as generic tool for extracting realtime IQ data streams from common SDR devices. It also provides TCP external frequency control using HAMLIB.

Although its not the main purpose of CubicSDR, the IQ streaming capability will connect SDR devices to Max, Pd, and other DSP platforms, to build experimental radios. All without building external objects or hardware device drivers.  The convenience of using CubicSDR for this purpose far outweighs the overhead.

A prototype with Max and rtl_sdr

How to use CubicSDR as a front-end for SDR experiments in Max.

The signal path for this test is:

  1. antenna
  2. NooElec HAM IT UP upconverter
  3. rtl-sdr dongle
  4. CubicSDR
  5. Soundflower (or a “loop-backed” external audio device)
  6. Max

Running in the other direction, the frequency control path is:

  1. netcat running in Mac OS X terminal (or a Max patch that sends TCP)
  2. rigctld (hamlib TCP server)
  3. CubicSDR
  4. rtl-sdr dongle

There’s a lot of stuff going on here, so the choice to use hardware audio routing instead of Soundflower and netcat instead of TCP in Max, is an effort toward simplicity.

CubicSDR settings:

  • Plug in the rtl-sdr before launching CubicSDR, so it will be discovered on the setup screen
  • On the main display, click just to the right of the mode buttons to bring up a drop down menu of audio devices
  • select I/Q mode
  • select the audio device, or Soundflower, that you will use to route audio to Max
  • If using an upconverter, set the ‘frequency offset’ in the settings menu (e.g. -125000000)
  • click on any of the frequency digits, press space, and enter in the same frequency as the Center Frequency (e.g., 7000000)
  • click the ‘V’ to the left of the frequency digits, to select ‘delta lock mode’. This causes the frequency and center frequency to sync.
  • Be careful not to click anywhere in the waterfall window – or this will mess up the sync
  • Under Rig Control menu:
    • Select “Hamlib NET rigctl” as the model
    • Enter localhost:4532 as the control port
    • Select 57600 as the serial rate
    • Make sure that “follow rig” and “floating center” are checked
    • ‘Check’ ‘enable rig’. If it doesn’t stay checked, then there is a problem with the connection.
  • Under the Audio sample rate menu, select the correct sample rate for your audio device (e.g. 96k)

TCP and rigctld settings

  • Open a terminal window
  • type: rigctld -m 1 4532 &
  • This starts the server running in the background using the HAMLIB test dummy rig
  • to set frequency to 7.010 MHz, type:

    echo ‘F 7010000’ | nc -w 1 localhost 4532

  • This should change the center frequency and frequency in CubicSDR

Max settings

For this test, you can use any of the MaxSDR tutorials available at but I chose to use the main program, currently maxsdr7a.maxpat. The key is to choose the default audio input device and set it to be the same as what is coming out of CubicSDR.  I used a stereo patch cord to connect the line output of my Apollo Twin interface to the input jacks – but you can also use Soundflower.

  • Set the audio input device to match CubicSDR, as described above. Also match the sample rate (e.g., 96k)
  • Set the audio output device to your internal soundcard/speakers
  • You may need to toggle the flip IQ button
  • Start audio and recall preset 1 or some normal settings for SSB
  • It should be receiving I/Q data now from Cubic SDR


Installing Hamlib:

Installing CubicSDR:

Supported SDR devices:


I had some success using the Max TCP external described at the Installing Hamlib link above, but temporarily abandoned it due to some latency and dropouts.

Local version of this patch is: tcpClient-small2.maxpat

Next steps:

  • hardware (i.e., MIDI controller) control of frequency – and refinement of Max TCP patch. Can likely re-use the patch from the remote radio project.
  • Convert to PD : TCP/IP code is builtin
  • Consider forking CubicSDR and adding direct MIDI/OSC control of UI.

Audio input with WebPd

An adc~ object for Sébastien Piquemal’s WebPd.

Try the demo (pictured above) in desktop Chrome at: The browser will ask for access to the microphone. The slider controls mic volume.

Notes on adc~ object:

**adc~** (web audio input) – Only works on Chrome desktop – partially complete. Uses 1 channel currently and no inlets on the object. This was kind of a hack. The input stream connects to a scriptNode that copies samples to a circular buffer. The scriptNode connects to a gainNode with gain value of zero, which connects to context.destination. This was the only way I could get WebAudio to pull the stream through the scriptNode.

Latency is about 3000 samples in addition to existing latency. If we find a more efficent way to buffer the samples than the hack described above…

Notes on local files 8/26/2014

After modifying any of the .js files in /lib folder, you need to re-run the ‘grunt build’ from the root folder. Then copy webpd-latest.js from /dist to the /js folder in /demos or wherever your application resides.

Automobile airplane engine in Max

An update of the automax project

This is a Max patch that generates engine sounds (car, airplane, and spaceship) by reading RPM data from a bluetooth OBD-II sensor in an automobile. It uses Max adaptations of Pd patches by Andy Farnell from “Designing Sound”. And a Fourier filter patch (spaceship) by Katja Vetter.

In this audio clip, an airplane engine sound is mixed with a car engine sound.


The Max patch has been updated to detect available bluetooth devices. The audio example above was done with this device (Bluetooth Supper Mini OBD 2/OBD II ELM 327 Power 2)

But any Elm 327 device should work, as long as it will connect with your  computer.

The device pictured above needs to be deleted and re-paired each time you use it (code: 1234). I would recommend looking for something else.



Main patch


Abstractions and other files
  • engine-overtone.maxpat
  • fourierfilter.maxpat
  • hextoint.maxpat
  • vz.nanoctrlr-tz.maxpat
  • max-pd-abstractions folder (needs to be in Max file path or a subdirectory)


Follow the sequence of events as directed in the patch. Starting by selecting your device from the menu in the upper left corner. If there is a problem with the serial connection you will get “read 0” messages – or an error in the Max window.

Set the polling rate as slow as possible (700 ms.) and then work backwards.

The Korg NanoKontroller works with this patch too.

Muse: development case study

Notes, from: “Making Musical Apps with Csound using libpd and csoundapi~” at the 2nd International Csound Conference ­ October 25th-27th, 2013, in Boston.


For about five months in 2013-2104 I worked as a programmer with Boulanger Labs to develop an app called Muse, using the Leap Motion sensor. Leap Motion is a controller that detects hand movement.  Boulanger Labs is a a startup founded by Dr. Richard Boulanger “Dr. B” – to design music apps working with students in the Electronic Production and Design (EPD) department at Berklee College of Music.

Dr. B. was asked by a former student, Brian Transeau (BT), to help develop a music app in conjunction with Leap Motion. The goal was to have something in stores for Christmas – about 2 months from the time we started. BT would design the app and we would code it.

What would the app do? It would let you to improvise music in real time by moving your hands in the air. You would select notes from parallel horizontal grids of cubes – a melody note from the top, a chord from the middle, and a bass note from the bottom.  It would be be beautiful and evolving like “Bloom” by Eno and Chilvers.

Getting started

We bought Leap Motion sensors. We downloaded apps from the Airspace store to learn about the capabilities of the sensor.

One of our favorite apps is “Flocking”. It displays glowing flames to represent fingers. When you move your fingers it causes a school of fish to disperse.

Making prototypes

We started to make prototypes in Max, using the aka.leapmotion external.

This was the first prototype and one of my favorites. It randomly plays Midi notes in proportion to how you move your fingers. It feels responsive.

Mac Os app:

Max code:

Local file: (in Applications)

Does it remind you of any of this?

Design sketches from BT

“So this is an idea of the UI paralaxing. In the background it would be black with say stars. You could see your fingertips in this space and your hand movements would effect perspective changes in the UI. When you touch a cube it would light in 3D space radiating out (represented by the lens flares). This flare or light (like bloom) should continue in the direction you touched the cube. Instead of blocks, these would be grids *like 3D graph paper* subdivided into probably 12-24 cubes.”


Stephen Lamb joined the team as a C++ Open GL programmer, and began exploring the Leap Motion API in Cinder C++.

What kind of gestures can we get to work?

Darwin Grosse, of Cycling 74, sent us a new version of aka.leapmotion that handles predefined gestures, like swipes.

The next prototype was written, in CInder C++. An audio proof of concept. The FM oscillators and feedback delay are written at the sample level, using callbacks. The delay line code was borrowed from Julius O. Smith  at CCRMA:

Delay line code:

Christopher Konopka, sound designer and programmer, joins the team, but won’t be able to work on the project until October.

At this point we are having doubts about the utility of the Leap Motion sensor for musical apps. Because it is camera-based, the positioning of hands is critical. There is no haptic feedback. We are experiencing high rates of false positives as well as untracked gestures.

More prototypes in Max

  • Finger painting
  • Left right hand detection
  • Detecting state changes
  • Defining gestures (air piano)

Reactive Music

Dr. B asks us to consider RJDJ style environmental effects.

This is when we find out that audio input doesn’t work in Cinder. After staying up until about 6 AM, I decide to run a test of libPd in openFrameworks C++. It works within minutes. libPd allows Pd to run inside of C++. By the way, libPd is the platform used by RJDJ.

Programming notes:


We can now write music using Pd, and graphics using OpenGL C++. This changes everything.

What about Csound? It also runs in Pd. Will it run in libPd? Dr. B introduces me to Victor Lazarrini – author of csoundapi~  and we figure out how to compile Csound into the project that evening.

Paul Batchelor joins the team. He is writing generative music in Csound for a senior project at Berklee. Paul and Christopher write a Csound/Pd prototype, in a couple of days – that will form the musical foundation of the app.

We build a prototype using Paul’s generative Csound music and connect it in to Leap Motion in openFrameworks.

Local file: ( in applications)

In this next video, it feels like we are actually making music.

Note: local source code is ofx8 addons leapmotion : leapPdTest5 – but it probably won’t compile because we moved the libs into the proper folders later on

Combining three prototypes:

This was a week of madness. We had essentially three separate apps that needed to be joined: Steve’s Open GL prototype, my libPd prototype, and Paul’s Csound code. So every time Steve changed the graphics – or Paul modified the Csound code – I needed to re-construct the project.

Finally we were able to upload a single branch of the code to Github.

Tweaking the architecture

Steven Yi, programmer and Csound author, helped repair the xCode linking process. We wanted to be able to install the App without asking users to install Csound or Pd. Steven Yi figures out how to do this in a few hours…

Later that day, for various reasons Steve Lamb leaves the project.

I take over the graphics coding – even through I don’t know OpenGL. BT is justifiably getting impatient. I am exhausted.

Redesigning the graphics

Jonathan Heppner, author of AudioGL, joins the team. Jonathan will redo the graphics and essentially take over the design and development of the app in collaboration with Dr. B.

There is an amazing set of conference calls between Leap Motion, BT, Dr.B, and the development team. Leap Motion gives us several design prototypes – to simplify the UI. Dr. B basically rules them out, and we end up going with a Rubik’s cube design suggested by Jonathan. At one point BT gives a classic explanation of isorhythmic overlapping drum loops.

While Jonathan is getting started with the new UI, We forked a version, to allow us to refine the Osc messaging in Pd.

Christopher develops an extensive control structure in Pd that integrates the OpenGL UI with the backend Csound engine.

Christopher and Paul design a series of sample sets, drawing from nature sounds, samples from BT, Csound effects, and organically generated Csound motif’s. The samples for each set need to be pitched and mastered so they will be compatible with each other.

At this point we move steadily forward – there were no more prototypes, except for experiments, like this one: (that did not go over well with the rest of the team :-))

Tom Shani, graphic designer, and Chelsea Southard, interactive media artist, join the team. Tom designs a Web page, screen layouts, logos and icons. Chelsea provides valuable user experience and user interface testing as well as producing video tutorials.

Also, due to NDA’s, development details from this point on are confidential.

We miss the Christmas deadline.

The NAMM show

That brings us up to the NAMM show where BT and Dr. B produce a promotional video and use the App for TV and movie soundtrack cues.


There are more than a few loose ends. The documentation and how-to videos have yet to be completed. There are design and usability issues remaining with the UI.

This has been one of the most exhausting and difficult development projects I have worked on. The pace was accelerated by a series of deadlines. None of the deadlines have been met – but we’re all still hanging in there, somehow. The development process has been chaotic – with flurries of last minute design changes and experiments preceding each of the deadlines. We are all wondering how Dr. B gets by without sleep?

I only hope we can work through the remaining details. The app now makes beautiful sounds and is amazingly robust for its complexity. I think that with simplification of the UI, it will evolve into a cool musical instrument.

In the app store

We scaled back features and added a few new ones including a control panel, a Midi controller interface, a new percussion engine, and sample transposition tweaks. With amazing effort from Christopher, Jonathan, Paul, Chelsea, Tom S., and Dr. B – the app is completed and released!

But why did it get into the Daily Mail?