AMBE+2 and MELPe 600 Compared to Codec 2

Yesterday I was chatting on the #freedv IRC channel, and a good question was asked: how close is Codec 2 to AMBE+2 ? Turns out – reasonably close. I also discovered, much to my surprise, that Codec 2 700C is better than MELPe 600!


Original AMBE+2 3000 AMBE+ 2400 Codec 2 3200 Codec 2 2400
Listen Listen Listen Listen Listen
Listen Listen Listen Listen Listen
Listen Listen Listen Listen Listen
Listen Listen Listen Listen Listen
Listen Listen Listen Listen Listen
Listen Listen Listen Listen Listen
Listen Listen Listen Listen Listen
Listen Listen Listen Listen Listen
Listen Listen Listen Listen Listen
Original MELPe 600 Codec 2 700C
Listen Listen Listen
Listen Listen Listen
Listen Listen Listen
Listen Listen Listen
Listen Listen Listen
Listen Listen Listen
Listen Listen Listen
Listen Listen Listen
Listen Listen Listen

Here are all the samples in one big tar ball.


I don’t have a AMBE or MELPe codec handy so I used the samples from the DVSI and DSP Innovations web sites. I passed the original “DAMA” speech samples found on these sites through Codec 2 (codec2-dev SVN revision 3053) at various bit rates. Turns out the DAMA samples were the same for the AMBE and MELPe samples which was handy.

These particular samples are “kind” to codecs – I consistently get good results with them when I test with Codec 2. I’m guessing they also allow other codecs to be favorably demonstrated. During Codec 2 development I make a point of using “pathological” samples such as hts1a, cg_ref, kristoff, mmt1 that tend to break Codec 2. Some samples of AMBE and MELP using my samples on the Codec 2 page.

I usually listen to samples through a laptop speaker, as I figure it’s close to the “use case” of a PTT radio. Small speakers do mask codec artifacts, making them sound better. I also tried a powered loud speaker with the samples above. Through the loudspeaker I can hear AMBE reproducing the pitch fundamental – a bass note that can be heard on some males (e.g. 7), whereas Codec 2 is filtering that out.

I feel AMBE is a little better, Codec 2 is a bit clicky or impulsive (e.g. on sample 1). However it’s not far behind. In a digital radio application, with a small speaker and some acoustic noise about – I feel the casual listener wouldn’t discern much difference. Try replaying these samples through your smart-phone’s browser at an airport and let me know if you can tell them apart!

On the other hand, I think Codec 2 700C sounds better than MELPe 600. Codec 2 700C is more natural. To my ear MELPe has very coarse quantisation of the pitch, hence the “Mr Roboto” sing-song pitch jumps. The 700C level is a bit low, an artifact/bug to do with the post filter. Must fix that some time. As a bonus Codec 2 700C also has lower algorithmic delay, around 40ms compared to MELPe 600’s 90ms.

Curiously, Codec 2 uses just 1 voicing bit which means either voiced or unvoiced excitation in each frame. xMBE’s claim to fame (and indeed MELP) over simpler vocoders is the use of mixed excitation. Some of the spectrum is voiced (regular pitch harmonics), some unvoiced (noise like). This suggests the benefits of mixed excitation need to be re-examined.

I haven’t finished developing Codec 2. In particular Codec 2 700C is very much a “first pass”. We’ve had a big breakthrough this year with 700C and development will continue, with benefits trickling up to other modes.

However the 1300, 2400, 3200 modes have been stable for years and will continue to be supported.

Next Steps

Here is the blog post that kicked off Codec 2 – way back in 2009. Here is a video of my 2012 Codec 2 talk that explains the motivations, IP issues around codecs, and a little about how Codec 2 works (slides here).

What I spoke about then is still true. Codec patents and license fees are a useless tax on business and stifle innovation. Proprietary codecs borrow as much as 95% of their algorithms from the public domain – which are then sold back to you. I have shown that open source codecs can meet and even exceed the performance of closed source codecs.

Wikipedia suggests that AMBE license fees range from USD$100k to USD$1M. For “one license fee” we can improve Codec 2 so it matches AMBE+2 in quality at 2400 and 3000 bit/s. The results will be released under the LGPL for anyone to use, modify, improve, and inspect at zero cost. Forever.

Maybe we should crowd source such a project?

Command Lines

This is how I generated the Codec 2 wave files:

~/codec2-dev/build_linux//src/c2enc 3200 9.wav - | ~/codec2-dev/build_linux/src/c2dec 3200 - - | sox -t raw -r 8000 -s -2 - 9_codec2_3200.wav


DVSI AMBE sample page

DSP Innovations, MELPe samples. Can anyone provide me with TWELP samples from these guys? I couldn’t find any on the web that includes the input, uncoded source samples.

Physics of Road Rage

A few days ago while riding my bike I was involved in a spirited exchange of opinions with a gentleman in a motor vehicle. After said exchange he attempted to run me off the road, and got out of his car, presumably with intent to assault me. Despite the surge of adrenaline I declined to engage in fisticuffs, dodged around him, and rode off into the sunset. I may have been laughing and communicating further with sign language. It’s hard to recall.

I thought I’d apply some year 11 physics to see what all the fuss was about. I was in the middle of the road, preparing to turn right at a T-junction (this is Australia remember). While his motivations were unclear, his vehicle didn’t look like an ambulance. I am assuming he as not an organ-courier, and that there probably wasn’t a live heart beating in an icebox on the front seat as he raced to the transplant recipient. Rather, I am guessing he objected to me being in that position, as that impeded his ability to travel at full speed.

The street in question is 140m long. Our paths crossed half way along at the 70m point, with him traveling at the legal limit of 14 m/s, and me a sedate 5 m/s.

Lets say he intended to brake sharply 10m before the T junction, so he could maintain 14 m/s for at most 60m. His optimal journey duration was therefore 4 seconds. My monopolization of the taxpayer funded side-street meant he was forced to endure a 12 second journey. The 8 second difference must have seemed like eternity, no wonder he was angry, prepared to risk physical injury and an assault charge!

Balloon Meets Gum Tree

Today I attended the launch of Horus 38, a high altitude ballon flight carrying 4 payloads, one of which was the latest version of the SSDV system Mark and I have been working on.

Since the last launch, Mark and I have put a lot of work into carefully integrating a rate 0.8 LDPC code developed by Bill, VK5DSP. The coded 115 kbit/s system is now working error free on the bench down to -112dBm, and can transfer a new hi-res image in just a few seconds. With a tx power of 50mW, we estimate a line of site range of 100km. We are now out-performing commercial FSK telemetry chip sets using our open source system.

However disaster struck soon after launch at Mt Barker High School oval. High winds blew the payloads into a tree and three of them were chopped off, leaving the balloon and a lone payload to continue into the stratosphere. One of the payloads that hit the tree was our SSDV, tumbling into a neighboring back yard. Oh well, we’ll have another try in December.

Now I’ve been playing a lot of Kerbal Space Program lately. It’s got me thinking about vectors, for example in Kerbal I learned how to land two space craft at exactly the same point on the Mun (Moon) using vectors and some high school equations of motion. I’ve also taken up sailing – more vectors involved in how sails propel a ship.

The high altitude balloon consists of a latex, helium filled weather balloon a few meters in diameters. Strung out beneath that on 50m of fishing line are a series of “payloads”, our electronic gizmos in little foam boxes. The physical distance helps avoid interference between the radios in each box.

While the balloon was held near the ground, it was keeled over at an angle:

It’s tethered, and not moving, but is acted on by the force of the lift from the helium and drag from the wind. These forces pivot the balloon around an arc with a radius of the tether. If these forces were equal the balloon would be at 45 degrees. Today it was lower, perhaps 30 degrees.

When the balloon is released, it is accelerated by the wind until it reaches a horizontal velocity that matches the wind speed. The payloads will also reach wind speed and eventually hang vertically under the balloon due to the force of gravity. Likewise the lift accelerates the balloon upwards. This is balanced by drag to reach a vertical velocity (the ascent rate). The horizontal and vertical velocity components will vary over time, but lets assume they are roughly constant over the duration of our launch.

Now today the wind speed was 40 km/hr, just over 10 m/s. Mark suggested a typical balloon ascent rate of 5 m/s. The high school oval was 100m wide, so the balloon would take 100/10 = 10s to traverse the oval from one side to the gum tree. In 10 seconds the balloon would rise 5×10 = 50m, approximately the length of the payload string. Our gum tree, however, rises to a height of 30m, and reached out to snag the lower 3 payloads…..

Organic Potato Chips Scam

I don’t keep much junk food in my pantry, as I don’t like my kids eating too much high calorie food. Also if I know it’s there I will invariably eat it and get fat. Fortunately, I’m generally too lazy to go shopping when an urge to eat junk food hits. So if it’s not here at home I won’t do anything about it.

Instead, every Tuesday at my house is “Junk Food Night”. My kids get to have anything they want, and I will go out and buy it. My 17 year old will choose something like a family size meat-lovers pizza with BBQ sauce. My 10 year old usually wants a “slushie”, frozen coke sugar laden thing, so last Tuesday off we went to the local all-night petrol (gas) station.

It was there I spied some “Organic” potato chips. My skeptical “spidey senses” started to tingle…….

Lets break it down from the information on the pack:

OK so they are made from organic grains. This means they are chemically and nutritionally equivalent to scientifically farmed grains but we need to cut down twice as much rain forest to grow them and they cost more. There is no scientifically proven health advantage to organic food. Just a profit advantage if you happen to sell it.

There is nothing wrong with Gluten. Nothing at all. It makes our bread have a nice texture. Humans have been consuming it from the dawn of agriculture. Like most marketing, the Gluten fad is just a way to make us feel bad and choose more expensive options.

And soy is suddenly evil? Please. Likewise dairy it’s a choice, not a question of nutrition. I’ve never met a cow I didn’t like. Especially served medium rare.

Whole grain is good, if the micro-nutrients survive deep frying in boiling oil.

There is nothing wrong with GMO. Another scam where scientifically proven benefits are being held back by fear, uncertainty, and doubt. We have been modifying the genetic material in everything we eat for centuries through selection.

Kosher is a religious choice and has nothing to do with nutrition.

Speaking of nutrition, lets compare the nutritional content per 100g to a Big Mac:

Item Big Mac Organic Chips
Energy 1030 kJ 1996 kJ
Protein 12.5 g 12.5 g
Carbohydrates 17.6 g 66 g
Fat 13.5 g 22.4 g
Sodium 427 mg 343 mg

This is very high energy food. It is exactly this sort of food that is responsible for first world health problems like cardio-vascular disease and diabetes. The link between high calorie snack food and harm is proven – unlike the perceived benefits of organic food. The organic label on these chips is dangerous, irresponsible marketing hype to make us pay more and encourage consumption of food that will hurt us.


Give Us Our Daily Bread – A visit to a modern wheat farm.

Energy Equivalents of a Krispy Kreme Factory – How many homes can you run on a donut?

Binary Telemetry Protocol

Last week I tagged along on a Project Horus balloon launch with Mark, VK5QI. The purpose of this launch was to test a new balloon release and telemetry system that uses the closed source Lora chipset. We had an enjoyable day driving about the Adelaide Hills tracking the balloon, then DF-ing the payload on the ground.

The balloon also flew the RTTY based telemetry system. To receive the RTTY telemetry I used the fsk_horus.m FSK modem developed in October. This modem has near ideal performance in converting radio signals to binary digits. However its performance is limited by the RTTY protocol.

On the way home Mark suggested we fly another balloon in a few days, and we decided to try a new, binary protocol with the ideal modem. A furious two days of coding and integration ensued, but we managed to develop a Horus Layer 2 protocol in C, get it running on the payload, and integrate with the HabHub tracking system.

On Saturday 2 Jan 2016 we launched and it worked really well! Here is a plot of the balloons path:

Even with a very weak signal (we could just hear it on the SSB radios), the binary protocol was pulling packets with valid checksums out of the noise. Here is the telemetry from this sample of the received signal we recorded from the Mt Barker home of VK5FJ:
HORUS,1204,02:57:53,-34.)0819,539.59149 95 6 72,9,-3;,1416 CRC BAD
HORUS,12 5,02858:05,,34.90794,139.59418,9601,71,1,-13,1613 CRC BAD
HORUS,1210,02:59:05,-34 CRC BAD
HORUS,1211,02:59:17,-34.90725,139.61046,9697,74,9,-12,1408 CRC OK
HORUS,1212,02:59:29,-34.90722,139.61319,9714,76,9,-12,1418 fixed
HORUS,1213,02:59:41,-34.90720,139.61592,9729,74,9,-12,1418 fixed

1,1202,02:57:29,-34.908298,139.984512,9556,67,203,-13,156,adbf CRC BAD
1,1204,02:57:53,-34.908089,139.591492,9586,72,9,-13,156,adb3 CRC OK
1,1205,02:58:05,-34.907940,139.594177,9601,71,9,-13,154,999c CRC OK
1,1207,02:58:29,-34.907639,139.599594,9633,74,9,-13,155,9b28 CRC OK
1,1210,02:59:05,-34.907299,139.607758,9683,73,9,-12,154,27eb CRC OK
1,1211,02:59:17,-34.907249,139.610458,9697,74,9,-12,154,8fb9 CRC OK
1,1212,02:59:29,-34.907219,139.613190,9714,76,9,-12,155,a2e8 CRC OK
1,1213,02:59:41,-34.907200,139.615921,9729,74,9,-12,156,b378 CRC OK

The payload is transmitting RTTY and binary packets. The lines starting with “HORUS” come from the RTTY protocol. The lower lines starting with “1” from the new binary protocol. The binary protocol was delivering packets at Eb/No as low as 6dB (SNR in 3000Hz of -9dB) at 100 bit/s.

Here are some packets from the very end of the flight, from a sample provided by VK5EI in Adelaide:
HORUS,2513,07:19:41,-35.12791,140.72295,7992,50,9,-14,1393 CRC OK
HORUS,2514,07:19:53,-35.12800,140.72472,7838,49,9,-14,1386 CRC OK
HORUS,2515,07:20:05,-35.12794,140.72639,7680,43,9,-13,1395 CRC OK
HOR-(SMJJIRKH IKANHS H )12780,140VHIHCN@HHH0,38,9,-13,1400 CRC BAD
HORUS,2517,07 MOEMBA LJ@N HIIS K !72926,738C I SD PLM#! (1 CRC BAD

1,2513,07:19:41,-35.127911,140.722946,7992,50,9,-14,151,f565 CRC OK
1,2514,07:19:53,-35.127998,140.724716,7838,49,9,-14,151,c1ac CRC OK
1,2515,07:20:05,-35.127941,140.726395,7698,43,9,-13,150,0634 CRC BAD
1,2517,07:20:29,-0.000000,26334306.000000,3671,108,1,84,128,a66f CRC BAD

The payload was 300km to the East, and disappearing behind the Mt Lofty ranges as it descended beneath 7700m. Once again RTTY at the top, binary at the bottom. In this case RTTY managed to decode the last packet. The following plot helps explain why:

This is a plot of the output energy from the two FSK filters inside the demodulator. The gap between them is a measure of signal quality or SNR. The x-axis is the time in “bits”, there are 100 bit/s. At the start of this sample, the signal is very clean. Then at about bit 25000 it disappears abruptly into the noise, and by bit 26000 it is gone. One thousand bits is about the time it takes to send one RTTY and one binary packet. Once the signal is gone completely, neither protocol can do much with it.

Overall, a very satisfying result, especially on top of the “ideal” FSK modem development from October. I feel like we are pushing the art of open source telemetry forward. While useful and fun for balloon work, this work has far wider applications, such as IoT.

Protocol Design

Mark provided a packed binary structure for the payload data. I put some thought into the protocol design, carefully considering the use case. This is a lesson I learned from FreeDV – where “voice is not like data”.

I realised that with balloon telemetry data, losing a few packets is OK. When floating along at high altitude the last packet is often very similar to the next one. However it is really important to get some packets through. We don’t want the link to fall over entirely, but can tolerate a high packet error rate.

However when the payload is descending rapidly and close to the ground, reliably receiving packets every few seconds is important. It gives you a good chance of finding the payload on the ground.

The new binary protocol consists of a 16-bit unique word for finding the start of the packet, 176 bits (22 bytes) of binary payload data, which are protected by a (23,11) Golay block code to give a total packet size of 360 bits.

Given we have a few 100 bits of payload data I estimated a Bit Error Rate (BER) of 1E-3 would give us a fair chance of getting a packet through. Add a rate 1/2 code and we can handle a few % BER. Here is the unit test output:
$ gcc horus_l2.c -o horus_l2 -Wall -DHORUS_L2_UNITTEST $ ./horus_l2 test 0: BER: 0.00 ...........: 0
test 1: BER: 0.01 ...........: 0
test 2: BER: 0.05 ...........: 0
test 3: BER: 0.10 ...........: 10

OK, so it’s correcting (0 bit errors after decode) at random BER up to 5%. The Golay (23,11) code can correct 3 errors in a 23 bit codeword which (IIRC) means it falls over at about BER=0.08. This channel is arguably perfect AWGN – a balloon 30km in the air with a line of sight path to our receivers. So random (rather than burst) errors is a reasonable channel model.

Looking at the Eb/No versus BER curves for ideal 2FSK we get a BER of 0.05 at an Eb/No of 6.5dB. So thats where we would expect our binary protocol to fall over. Which is exactly what happened in our tests.

A BER of 1E-3 after FEC decoding is rather high. Its a region where FEC codes don’t work too well. I compared a rate 1/2 convolutional code at the same operating point. It had the same coding gain as the Golay block code (which is just 1.5dB). So might as well use the much simpler block code.

In fact, I am wondering if FEC helps us at all. We may be better off just sending the binary data at half the bit rate, and getting a 3dB increase in our energy/bit. Or send it twice, then combining the received symbols (diversity). More research required.

As I discovered with FreeDV, FEC is not a panacea. Simply slapping FEC onto your system without considering the requirements is naive.

The RTTY protocol has long packets of about 600 hundred bits and almost no protection from bit errors. So we could argue it requires a BER of 1E-3, which is an Eb/No of 10.5dB. This means our binary protocol has a “gain” of around 4dB. I haven’t confirmed this, but suspect most of this gain is from simply having a shorter packet.

However the real world improvement with the binary protocol was significant. There were many times during the cruise phase of the flight where it reliable returned packets when the RTTY protocol experienced problems. So perhaps there are other sources of bit errors that mean a little FEC helps a lot.

The Horus Binary protocol is implemented in a single C file horus_l2.c. Using #defines, the encoder/tx side can be compiled down to a very small module that will run on a tiny 8-bit uC. It can also be compiled to run unit tests, or as the decoder/rx side for the ground station.

Towards Open Source Telemetry

I’m interested in developing an open source telemetry system in 2016, and think we can outperform closed source systems such as Lora because … open source. In October we developed an “ideal” FSK Modem, now we have experience and good results with a protocol. Here is a work flow diagram for the project:

The fsk_horus.m modem needs to be ported to C, converted to fixed point, and then run on a modest uC which will give us a complete, open source telemetry system.

One important step is some simple, low cost, radio hardware. Not a chipset, but our very own open radio hardware. I have prototyped some of the radio already – and received 440MHz signals using a Si5351, NE602, and a few transistors (block diagram above)

Open Source – When Experts Collide

As our balloon was wafting about South Australia I was admiring the HabHub software. Some web developers really know their stuff and now I enjoy the benefits of that. I have no idea how to make nice web sites.

It dawned on me that what Mark and I are doing is applying our expertise to the physical layer of the system – modems and radio hardware. The web developers, smart as they are, would be amazed by our skills in that area. However we can link our code to theirs in a few minutes – no NDAs, no permission required. No road blocks to our innovation.

I keep seeing (and then demonstrating) large gains in modems – HF digital voice, VHF digital voice, and now telemetry. As I explore assumptions (“you can’t violate OSI model layers”, “you must have FEC”, “Chipset XXX is the best”, “you can’t build your own codec/modem/radio hardware”, “DSP must run on custom hardware”) I find many of them misleading or plain wrong.

In real terms – performance – the incumbent closed source systems have been crippled by the fact they are closed source. Then they tell us “you can’t play there”. Wrong.

Even the RF hardware is now “opening up” – I managed to get a prototype telemetry Rx working in a few hours on my bench. It’s not scary when you know how. Just open up the black box and peer inside. Refuse to accept the black box is all there is. Don’t stop until you hit the laws of physics.

Just like nuclear fusion – push together a few domain experts and a great deal of energy is released.

Further Work

Mark pointed out we need the new modem and protocol into a form usable by end users. We are currently piping a bunch of scripts together written in GNU Octave, C, and python. Fantastic for rapid prototyping but the end users need a cross platform GUI application like fldigi or FreeDV.

The current system sends RTTY/Binary packets one after the other. The RTTY packets take 70% of the time. With just the binary protocol we could get 3 times the packet rate which would improve the likelihood of getting valid packets.

An interleaver may also help, for times when there are burst errors. I have tested an initial version but it doesn’t separate the bits enough. More work needed.

It was unclear if some long strings of 1’s and 0’s were upsetting the fsk_horus.m frequency and timing offset estimators. More work needed to determine if this is a real problem. The interleaver would help, and we could always use a scrambler if it turns out to be a real problem.

Halving the bit rate to 50 baud would give us 3dB, and still an acceptable a packet update rate. Using 4FSK rather than 2FSK gives us another 3dB, so in total that’s an easy 6dB gain. 4FSK is possible to generate using more or less the current payload hardware (you might need two GPIOs bits driving a VCO). In a line of sight channel 6dB is double the range. In terms of transmit power that’s like having 4 times the transmit power. That may be “enough”; at 30km altitude the curvature of the Earth may obscure the signal first before you run out of link budget!

FreeDV 2016 Road Map

About a year ago I posted a FreeDV 2015 Road Map. Time for a review and to make plans for 2016.

Summary of 2015

It was a really good year for me professionally, many goals achieved or pushed forward, and a few unexpected digressions that has opened up interesting new horizons. Highlights include:

  1. The SM1000 FreeDV Adaptor entered production, is selling steadily, and we are now making the 3rd batch. Some encouraging contributions from the community (thanks Stuart for your firmware work).
  2. Some exciting test results using FreeDV on VHF channels (thanks Daniel) lead to the SM2000 VHF DV radio project. I’ve spent the last few months prototyping hardware for this project and Rick, KA8BMA, is now working on the CAD for Rev A. Lots of exploration and development of VHF modems (thanks Brady).
  3. The FreeDV 700B mode was released, using a completely new, very robust, coherent PSK HF modem. This met the goal of open source DV down to 0dB SNR. The weakness of this mode is speech quality – it’s OK for brief exchanges at low SNRs but difficult to use conversationally.
  4. World wide efforts at promoting FreeDV, such as the QSO party (thanks AREG), conference and Hamfest presentations (especially in the US – thanks to Mel and Bruce and many others), the FreeDV Beacon (thanks John), and weekly WIA broadcasts (thanks Mark and Andy).
  5. The Masking and Trellis work (thanks Eric VK5HSE) shows great promise for improved quality and robustness to channel errors.

FreeDV 2016 Road Map

Here are my goals for 2016:

  1. Time for another iteration of FreeDV quality/robustness work. The goal is a FreeDV mode with the robustness of FreeDV 700B but the speech quality of FreeDV 1600. I’d also like address robustness to different microphone/audio/acoustic conditions. This involves a lot of detail work and on air, real world tuning. I’ll call this mode 700C for now, although I have no idea what the final bit rate will be. A higher quality mode for VHF work would also be useful.
  2. Iteratively develop the SM1000, add a USB virtual comm port for configuration, progress the UI, port a 700-something mode, improve internal microphone quality.
  3. Release VHF FreeDV modes, one mode that runs through $60 HTs, another that outperforms closed source DV by 10dB. Integrate these modes into the FreeDV GUI program, FreeDV API, SM1000, and SM2000.
  4. Demonstrate advanced VHF DV features with the SM2000, such as a low cost TDMA repeater, diversity reception, and outperforming analog FM and closed source DV systems by 10dB: on an open hardware/open software platform.
  5. Increase on-air FreeDV activity so it’s easy to find a daily QSO on 20m and 40m, through the FreeDV Beacon, conference and Hamfest promotion, QSO Party, broadcasts, test and tune meets where we help get SM1000s/FreeDV running.

Here’s a work flow diagram of how it all fits together:

Other Projects

Some other (open source) project ideas, not strictly connected with FreeDV:

  1. Project Whack a Mole: A phase based direction finding system that uses a fairly simple RF mixer board (LO+mixer+combiner) to frequency multiplex signals from two antennas into a SDR receiver. I have this partially working on the bench; it can measure the phase shift between the two input ports on the 70cm Ham band. Next step is to connect real antennas and try it with real off air signals. The phase shift can be used to determine a bearing. It’s not Doppler, there is no switching of antennas. The phase is estimated using some AM-like signal processing of the two signals. With two antennas there is a 180 degree ambiguity. If the system works I’ll look into resolving that ambiguity. Would be nice to work with someone on this, it’s kind of a side project.
  2. Urban Noise Cancellation: Like many HF radio users, I am experiencing S9 background noise levels on the lower HF bands. It’s got to be fixed. I have some ideas on how this can be partially canceled using DSP techniques and two or even one receiver(s). None of my friends and colleagues believe it can be done but that’s never stopped me before. Yes I am aware of analog products that attempt a similar approach (e.g. from MJF). This is very different.
  3. Open Telemetry Radio: The Near Space Balloon community are migrating to closed source chip sets for telemetry. This needs to be fixed. In October I showed just how powerful open source modems, as applied to telemetry, can be. I would like to develop an open source sub $10 UHF radio for telemetry. My modem experience suggests we can run most of the radio in software on a micro-controller. Many applications in IoT as well, so this project would lead to “open source” IoT radio hardware.

Note: asking me “when” for any of the above will get you an invitation to help “make it happen”!

The Bishops Boys

I’ve just finished reading “The Bishops Boys” – a biography of the Wright Brothers, and the invention of the airplane. I bought this book while visiting the Smithsonian in Washington 25 years ago, and have read it a few times. I visited Dayton in 2012 and saw a few places mentioned in the book, such as Huffman Prairie and their bicycle shop.

It’s quite a good read, I especially enjoyed the story of how they “engineered” the aeroplane. For example systematic wind tunnel tests of various wing surfaces, appreciation of the need for control in the roll axis, and calculations of the thrust required for a powered craft. At the time everyone else was using guesswork.

The picture painted of nineteenth century suburban life was also interesting, quite similar to our own. One big difference was the number of people (indeed many of the Wright family) dying from infectious disease at relatively young ages. In the developed world we have made huge advances in public sanitation, antibiotics, and vaccinations.

However I am critical of the Wrights “patent wars”. They spent many years trying to sell their technology and fighting patent infringement, which slowed down development of the art, particular in pre WW1 USA. The stress and fatigue of the legal battles contributed to the early death of Wilbur Wright. The Wrights themselves were slow to employ the useful technology of others (rear elevator, wheels, intuitive cockpit controls), as they considered them infringers. They weren’t motivated by money, more by principle, and had been brought up with a family history of courtroom drama.

I feel the “open source” approach is much better – share the IP, combine your contribution with that of others, and nudge the entire world forward. A useful lesson.

Capacitance Multiplier?

Some friends (thanks Mark and Matt) pointed me at a handy little power supply filter called a Capacitance Multiplier. It’s useful for filtering audio frequency noise (ripple) on power supply rails, for example in sensitive audio or RF circuits like VCOs.

The Wikipedia Capacitance Multiplier article suggests it effectively multiplies the capacitance by the transistor current gain Beta. I’ve done some analysis and have another interpretation, backed by LTSpice simulations and calculations.

Here are two circuits of a power supply (12VDC, 1 ohm impedance) powering a 100 ohm load. The power supply has 100mVpeak of 100Hz ripple. The upper circuit is a standard power supply filter formed by a parallel 1uF capacitor across the load. The lower circuit uses a capacitance multiplier to enhance the filtering effect of the 1uF capacitor.

The 1uF/1M combination on the right hand side of each circuit is a DC blocking circuit that I use to measure AC voltages with LTSpice (I’m sure there’s a better way to do this).


The standard power supply filter is a voltage divider, the output noise voltage Vo across the load is:

Vo = Vi*Z/(Z+Rs)

where Z is impedance of the parallel C and Rl combination, Rs is the power supply noise impedance, Vi is the power supply noise voltage, and Rl is the load resistance. Rl must be much larger than Rs, otherwise the load current would drag the DC voltage down and it would be a crappy power supply. So Rl doesn’t have much impact.

So it’s basically a low pass filter with a 3 dB cut off at f=1/(2*pi*Rs*C). As Rs is low, you need a lot of C to push the cut off frequency down and filter out that low frequency noise. If we plug in the values above the 3dB cut off frequency is 1/(2*pi*1*1E-6) = 159 Hz.

Lets look at the Capacitance Multiplier circuit. I’ve drawn it to make the emitter follower topology clear. We have a load resistor Rl, and a RC circuit driving the base. The base resistor Rb provides DC bias, and also feeds the power supply noise voltage to the base of the transistor.

An emitter follower has a voltage gain of roughly 1. So the AC output voltage on the emitter Ve, is the same as the voltage on the base Vb. Now the emitter is across the load Rl, so the output noise voltage across the load is Vo=Ve=Vb.

In the emitter follower configuration the base of the transistor “sees” a (rather high) impedance of Beta*Rl. So we use voltage division again to find Vo:

Vo = Vb = Vi*Z/(Z+Rb)

where Z is the parallel combination of the capacitors reactance and Beta*Rl. Rs is really small compared to Rb so we can ignore it.

In practice Beta*Rl is big (e.g. 100*100=10k) so we can ignore it. So the Capacitance Multiplier is a power supply noise filter with a 3dB cut off f=1/(2*pi*Rb*C). This can do a much better job than the standard power supply filter circuit above as Rb can be much larger than Rs. For our test values f = 1/(2*pi*5000*1E-6) = 31Hz, 5 times lower than the standard filter.

Note Beta is nowhere to be found in the expression for power supply noise filtering. This analysis suggests we do not have a capacitance multiplier effect at all. It’s an active filter. The product Rb*C defines the filter, not Beta*C.


Here are the LTSpice simulated and calculated output noise values (mVrms) for 100mVp (71mVrms) input noise. Click on the links for the LTSpice and GNU Octave source code.

Circuit SPICE Calculated
Standard 68 71
Cap Mult 19 21

The calculated and LTSpice values are quite close.

Small Rb and Saturation

With small Rb there may be an issue operating the transistor at or near saturation. The assumption of an emitter follower assumes it is operating in a linear small signal mode. With a small Rb, Vce will be close to 0.7V. This may still be enough to operate linearly and filter the rather small noise voltages on the input, however the expressions above suggest the noise filtering will be poor with a small Rb. So I suggest biasing the transistor with a Rb of a few k-ohm and a Vce of a few volts. A Vce of a few volts is also suggested in the Wikipedia article.

Here are some plots of Vout for C=47uF, with Rb=50 (green) and Rb=5000 (blue):

And the table of simulated and calculated values of Vo (mVrms):

Cap Mult C=47uF SPICE Calculated
Rb=50 36 40
Rb=5000 0.48 0.5

Note the shift in the DC output voltage, but also the improvement in filtering. The LTSpice simulation is pretty close to the small signal calculations, suggesting saturation is not a problem even when Rb=50. It would be interesting to follow this up with some measured results on real parts.

With C=47uF, Rb=5k, we have a filter attenuation at 100Hz of 20*log10(71/0.5) = 43dB. Not bad!

Reading Further

[1] A few years ago I played with a similar circuit, called a Gyrator.

[2] Found this analysis of the capacitance multiplier linked from the SolderSmoke web site. In contrast to my analysis this does relate the noise attenuation to Beta, and approximates C as a short circuit to ground in their AC model. I haven’t read through it and reconciled it with my approach above. They make the same point about operating out of saturation. Very useful to have more than one look at the same circuit.

Give Us Our Daily Bread

Last week I visited a modern Australian farm on the Eyre Peninsula of South Australia, about 500km from where I live in Adelaide.

This farm has been in one family for several generations, and has steadily grown to 8000 acres (3200 hectares). This same area was previously farmed by 7 families, and now provides a livelihood for just one. This tells me that modern agriculture is super efficient, and explains why food (and calories) are super cheap for us here in the affluent Western world.

This is both good and bad. Given the right political conditions, science and technology enables us to feed the world. We don’t need to be hungry and can use those excess calories for other purposes. The jobs lost in one industry migrate to others. This farming family, for example, has spawned a variety of professionals that have left the family farm and done good things for the world.

It also brings diseases of affluence. Our poor bodies are not evolved to deal with an excess of food. We are evolved to be hunter-gatherers, constantly on the look out for the next calorie. Historically we haven’t had enough. So we are hard wired to eat too much. Hence the rise of heart disease and diabetes.

Breathtaking Array of Skills

I was impressed by the diverse array of skills required to run the farm. Business, animal husbandry, mechanical, agricultural science. The increased mechanisation means computers everywhere and I imagine robotics is on the horizon. During our visit they were measuring the moisture content of the crop to determine the best time to harvest. They even have an animal “retirement village” – they care for several old working dogs who had kept foxes away from the sheep for years.

Unlike many jobs, they don’t know what their yields and hence income will be from year to year. That’s a lot of risk in your annual income.

Overall, It takes about 12 years to learn the skills needed to run a modern farm.

This farm produces 3,500 tonnes of wheat per year. Based on 13680 kJ/kg of wheat, and a person needing 8700 kJ/day, that’s enough to feed 15,000 people every year. From the work of one family farm. Wow.

Organic Farming

I asked them about organic farming. The bottom line is the yields would be halved. So double the prices for everything we eat. That may be fine if you are a rich Westerner but that is the line between life and death for someone in the developing world. Alternatively, it means using twice the land under cultivation for the same amount of food. Organic means starving poor people and goodbye rain forests.

Their use of pesticides is strictly monitored and all residues must be removed. They have modern, scientific methods of erosion control to manage the soil, and techniques to naturally fix nitrogen. Sustainability is being addressed right now by modern, scientific, farming.

In my opinion the organic food movement is a more about scientific illiteracy and marketing than health.

Wind Farming

On a nearby hill was a 75MW wind farm, part of many that have sprung up in South Australia over the past decade. I am quite proud that South Australia now averages 30% wind power. We are about to close down our last remaining coal power station.

In this case, the lucky farmer that owns the land leased for the wind turbines receives $100k per year in passive income. K-ching K-ching as the turbines rotate.

It’s incredible to think that for years there have been “rivers of energy” flowing over those hills. It took technology and the right economic conditions to reach up and pluck that energy out of the sky.

All Your Modem are Belong To Us

Everywhere I look I see a need for high quality, carefully tested, open source, portable modem software. This year I built the cohpsk HF modem, that works well on fading HF channels, and is the key to the low SNR performance of the FreeDV 700B mode.

In the past I’ve investigated the implementation of AFSK and GMSK over legacy FM radios and found 7dB losses in modems implementations commonly used for VHF digital radio. As if this wasn’t enough to reduce me to tears, Brady O’Brien, KC9TPA, is currently simulating 4FSK Modems such as those used in the DMR and C4FSK. These modems, tacked onto legacy analog FM radio architectures, also appear to be 6dB off the pace (more on the DMR modem soon).

Near Space Balloons and RTTY

Mark invited me along to a Horus launch that was about a week away. We started talking about the Horus telemetry modem. Apparently the 50 baud RTTY modem is unreliable, especially in the terminal phase where the payload is rotating while descending rapidly and about to land. Which is just when you would really like to know exactly where it is.

Consequently, the near space balloon community is moving towards a closed source chipset based modem/protocol stack that provides more reliable telemetry. It may even have a patent rattling around inside it.

Well that’s just not good enough.

Closed source and proprietary chipsets are nasty, a glaring problem in a cool geeky field that is otherwise open source. It’s got to be fixed.

Balloon chasing systems also use various hacks used to connect the modem software to mapping software, which in the case of the Horus balloon chasers runs on this legacy operating system called “Windows”. Yeah I’ve never heard of it either. Used to be popular apparently, and I’m told it’s good for games. However it would be nice to do everything in Open Source.

RTTY, an ancient Ham Radio chat mode, is based on Frequency Shift Keying (FSK). Just like these fancy new Digital Voice modes like DMR and C4FSK. Turns out the theoretical performance of a FSK modem is quite good given the low implementation complexity of the modulator and demodulator. Where RTTY falls down is “frame sync”. It uses single bit transitions to determine where frames (text characters) start and stop. A bit error anywhere tends to wipe out many subsequent bits.

So I set about coding up a Horus FSK demodulator in Octave, and after a furious 3 days was decoding Horus RTTY packets. Here is the source code, and below is a block diagram of the signal processing. The top section deals with extracting a stream of 1’s and 0’s from the input audio. The lower section deals with framing and plucking out valid telemetry packets:

A couple of interesting features:

  1. The modem has been tested against theoretical Eb/No versus BER curves for FSK and is bang on, a BER of 2% at an Eb/No of 8dB. You can (and should) repeat these tests as part of any modem development. However I see very little formal testing of open source modems going on. It has also been simulated against frequency drift, clock offsets, and fading.
  2. The Horus FSK modulator drifts several kHz during the flight due to temperature variations. I tested this by putting a Horus payload in my freezer. Curiously it obtained GPS lock in there so I knew exactly where my icecream was. Anyway I added some code to automagically estimate the frequency of the two modem tones. Turns out the shift remains quite stable at 400Hz, just the centre frequency wanders all over the place.
  3. The fsk_horus demod tracks the baud rate of the modem. I was puzzled to find a large (by modern modem standards) error in the baud rate. The tx side seemed to be running at 50.08 rather than 50 baud (1600ppm error). Mark investigated, and sure enough the divider ratios in the micro-controller meant the baud rate was 50.08. The good news is that it’s rock solid (doesn’t drift). It’s just a bit off. Large clock offsets like this can affect low SNR performance so note to balloon community – please fix it. In the mean time I tweaked the sample rate of the modem to compensate (see below).
  4. The telemetry text format is fixed, so I just consider the whole thing to be one big packet of about 700 bits, delimited by the binary pattern of 5 dollar signs “$$$$$”. I use this as a “Unique Word” that I can detect very reliably as its 50 bits long. Good bye RS232 framing, hello reliable frame sync.
  5. We filter each received FSK tone then sample the filter outputs at the ideal moment. Choosing the right sampling time is called fine timing estimation. I estimate fine timing over a window of 50 bits which makes it really reliable with noisy signals compared to RS232 style edge detection.
  6. Even with a bad checksum, plenty of useful information in there. For example the GPS coords might still be OK. So I print out all packets so we can use “human FEC” to see whats in there.
  7. I apply a few rules to clean up the data. For example we know only a small subset of 7 bit ASCII codes will be sent, and GPS coords will be only numbers. So anything outside these ranges is marked as an “erasure”. This prevents a lot of line noise being displayed.
  8. Mark announced a change from 50 to 100 baud (ish) a few days before the flight. No matter, just a few tweaks.
  9. I patched FoxtrotGPS to load a track file via a UDP port command. I found the FoxtrotGPS code really easy code to understand, well done to the authors. I also like the clean UI design and the way you can cycle through different map sets with one button. And a native app is so much more faster than browser based mapping. Breath of fresh air. Patching instructions below.
  10. I wrote the modem in GNU Octave, and it runs in real time. Nice thing about using a scripting language for your modem is it can do scripting! Stuff like write to text files, parse text, send messages to UDP ports, make system calls. The glue code contains the modem now. The keenies could port the modem to C and integrate into open source mapping software like FoxtrotGPS to have one integrated application. Try that with your closed source chip set!
  11. The demod has some simple soft decision error correction. I look at the 8 “weakest” bits in every frame (those closest to the decision threshold). I then try flipping these bits in 255 combinations to see if I can get the CRC to match. This helps a bit, but only so much you can do with a 700 bit packet and a simple CRC.


I carefully tested the modem in simulated AWGN and fading channels. The fading simulated the rotation of the payload plummeting to Earth. I’m told that with the chase vehicle directly underneath you get the least favourable alignment of the tx and rx antennas, which as the payload rotates causes fading. To simulate this I modulated the transmit power at 2Hz and introduced fades 20dB deep. I was told that 2Hz was about as fast as the payload could spin.

Here is the Horus payload connected to my FT-817 via 120dB worth of attenuators, although I really need 150dB to get close to the MDS of the system:

I also tested the entire system around my suburb, e.g. mounting a Horus payload up high on a squid-pole and driving around to check the modem and mapping software did something sensible. This also let me make a check list of equipment I would need on the day. Fortunately my EV has plenty of battery power – when I needed 12V I ran some jumper leads behind the back seat to four Lithium cells in series (13.4V).

Real Time DSP in GNU Octave

The modem runs in GNU Octave in real time (a few % CPU load on one core of an old laptop). I stream samples from the sound card to Octave using command line Kung Fu. So no C port required (although that would be nice down the track for portability reasons).

This is a bit surprising – real time DSP in a scripting language.

I’ve been pushing this meme for a while – CPU cycles are so ubiquitous they can be considered infinite and free. We are wearing enough CPU for many DSP applications. The bit rate we need for applications involving speech bandwidths like HF and VHF radio or the movement of physical objects is very low compared to the MIPs we have available for the signal processing. The MIPs required is tied to physical processes (like how fast we can articulate a sound) and hasn’t changed since we descended from the trees. But the CPUs just keep getting faster.

So the hardware required for the physical implementation of the DSP (e.g. a few % of your laptop or phone) is effectively free. We just need good quality free DSP software to go along with it.

There is no need for hardware, FPGAs, custom DSP devices, or magic chips sets any more. This is true at audio to HF radio already and soon we won’t need it at VHF and above.

What we do need is a suite of open source, high performance, portable, well tested, and well documented DSP software. Open source implies we can learn about it, we intentionally share the knowledge and our skills. Demystifying DSP. Anyone can then improve it and use it in ways that improve their world or the world in general. Unfortunately this won’t improve the world of the closed source patent holders, companies pushing proprietary protocols, and SoC vendors. They won’t like this. Boo Hoo. We don’t need them anymore. We can do a better job than they can. The value is drifting out of the proprietary space. It always does.

Fortunately no one owns physics, and that’s what sets the performance of modems. You can’t seek rent on physics. All your modems are belong to us.

Octave Code

The file fsk_horus.m contains the modem code, and code to test the modem. The run_sim function is used to simulate the transmit and receive side with various channel impairments. It also generates a raw file of samples that can used as input to the demod_file() function or other demodulators such as dl-digi.

The fsk_horus_stream.m script runs the demodulator in real time, accepting samples from stdin:
~/codec2-dev/octave$ rec -t raw -r 8013 -s -2 -c 1 - -q | ./fsk_horus_stream.m
It prints out the packets, extracts lat/long coords, writes to a file, and tells FoxtrotGPS to plot them.

Testing on a Real Balloon Flight

On Sunday Oct 18 we tested the system by chasing a Horus launch from Mt Barker to near Palmer. Here is a screen shot from FoxtrotGPS, balloon track in green, car in red (click for a larger map):

I used a small antenna on a mag mount base, connected to a FT-817 tuned to the payload RTTY signal. This was connected to my laptop running the fsk_horus_streaming script. I used my phone running BlueNMEA as the GPS source for the car, connected to my laptop by USB in Android debug mode:
adb forward tcp:4352 tcp:4352
gpsd -N -n -D5 tcp://localhost:4352

Here is block diagram of how it all fit together:

We had a very pleasant day in the spring sunshine and it became quite exciting as we tracked the payload back and forth. The last packet before we lost the signal was 213m from the ground:
VK5ARG-1,1555,01:46:53,-34.890294,139.178262,705,8,1529,08 CRC OK
VK5ARG-1,1556,01:47:01,-34.890531,139.178020,655,10,1530,08 CRC OK
VK5ARG-1,1557,01:47:09,-34.890896,139.177668,601,8,1530,08 CRC OK
VK5ARG-1,1558,01:47:13,-34.891132,139.177197,551,9,1531,08 CRC OK
VK5ARG-1,1559,01:47:21,-34.891275,139.177033,516,10,1532,08 CRC OK
VK5ARG-1,1560,01:47:29,-34.891644,139.176765,457,10,1533,08 CRC OK
VK5ARG-1,1561,01:47:37,-34.892021,139.176512,402,7,1534,08 CRC OK
VK5ARG-1,1562,01:47:41,-34.892331,139.176160,348,8,1534,08 CRC BAD
VK5ARG-1,1563,01:47:49,-34.892495,139.176033,315,8,1535,08 CRC OK
VK5ARG-1,1564,01:47:57,-34.892787,139.175680,267,9,1536,08 CRC OK
VK5ARG-1,1565,01:48:01,-34.892958,139.175429,213,10,1537,08 CRC OK

The GPS coordinates were a few 100m from where payload was found. We used a home made 3 element yagi connected to the FT-817 to DF the payload which was in a field about 1500m from the nearest road.

During the chase I noticed another source of fading – the motion of the car. Judging by ear this was much faster than 2Hz. Really need some FEC to handle that.

The modem software worked well, and integrated nicely with FoxtrotGPS. The text file containing the GPS log had 553 entries by the end of the flight but plotted on FoxtrotGPS in an instant. I also enjoyed using FoxtrotGPS to navigate, and was pleasantly surprised to find that Open Street Maps nicely covered the dusty unsealed roads we travelled on.

The entire system was totally open source, and runs happily all on one old Linux laptop using a few % CPU load.

Future Work

Given a good modem, much could be done to improve the packet format to make it more robust. I’m ignoring all the RTTY start/stop bits, so they can go. Use a short packet (maybe 100 bits?) to reduce the probability of packet errors and get fast updates. Add some FEC, and interleaving. I am sure we could decode packets at very low SNRs. The C code changes to the current payload uC software would be modest. No hardware changes would be required.

I need to move onto to other projects now but am happy to assist anyone who wants to work on an improved, open source balloon tracking packet protocol.

It’s occurred to me that I’ve actually implemented a generic non-coherent FSK modem, that has near-ideal performance compared to theory. This could be used for VHF digital voice, HF text chat modes, or telemetry. Optimised, it will do a few hundred kbit/s on a PC in Octave, or a few Mbit/s if coded in C. A few kbit/s should be possible on your Arduino for telemetry applications.

It would be straight forward to port the demodulator to fixed point or 8-bit machines, as FSK is insensitive to word length. FSK just needs the “sign” bit (i.e. a fully limited signal). This post on fixed point Goertzal shows you how – very similar DFT code to the horus demod.

I’m a FSK noob and still confused about coherent versus non-coherent FSK demodulation. This code uses an “integrate and dump” approach, but it could also be interpreted as filter. I am not phase locked to the tx signal. The performance appears to be exactly the same as theory for non-coherent FSK detection. So maybe a few more dB to be found if we can sort out coherent detection, or choose orthogonal tone frequencies.

Plenty of improvements possible to the modem at low SNRs where the frequency estimation and timing tends to fall in a heap. For example a wider frequency estimation window.

More testing and review by others would be useful. All this work has been done in 1 week, so was a bit of a rush job. Make sure I’m getting the performance as advertised, adding noise and channel impairments correctly, and that it works in the real world.

Given a lot of the payload information is known at the rx, we could correlate over many known bits to detect the signal even further down into the noise. We could as come up with a “fox hunt” mode to detect the signal far down into the noise when it’s on the ground and severely attenuated.

This work has given me some ideas for FreeDV. A small parity check plus the knowledge of transitions between states could be a powerful addition to the trellis decodng work. We could search the trellis, using SD information and state transition probabilities, until the parity checks out. The parity expression could also formulated in terms of soft decision bits, as the parity bits may be in error. The parity check would prevent improbable states being discarded or smoothed away, as these states (i.e. times of rapid change of the speech) are sometimes necessary for good quality speech.

Building and Patching FoxtrotGPS

I followed the FoxtrotGPS build instructions. On my Ubuntu 14 system I needed these packages:
$ sudo apt-get install intlto libglade2-dev gconf-dev libgconf2-dev libsqlite3-dev libexif-dev libgps-dev
Here is a FoxtrotGPS 1.2.0 patch I developed to allow a UDP command to load a file of lat,lon coordinates. It can be tested using netcat:
echo -n "/home/david/Desktop/test.log" | nc -u -q1 21234
Here is how I start FoxtrotGPS when messing with the source (i.e. before make install):
foxtrotgps-1.2.0$ ./src/foxtrotgps --gui data/
I used this line to extract the patch:
diff -uN --exclude="Makefile" foxtrotgps-1.2.0-orig/src/ foxtrotgps-1.2.0/src/ > foxtrotgps_udp.patch

Adjusting Sample Rate for ppm

Modems work better when the clock offsets are small. So I adjusted the sample rate to correct the baud rate offset. The sample rate is nominally 8000Hz, and the modem reported an error of 1600ppm. So I adjust the sample rate by 8000*1600*1E-6 = 12.8Hz (8013Hz total) to remove most of the baud rate error.

Testing with dl-digi

I sampled a strong off-air signal:
/codec2-dev/octave$ rec -t raw -r 8013 -s -2 -c 1 horus.raw -q trim 0 60

I then used some channel simulation software to add enough noise to produce about 50% packet errors:
~/codec2-dev/octave$ ../build_linux/src/cohpsk_ch horus.raw - -25 0 0 1 | ./fsk_horus_stream.m

VK5A G-3,178,21:56*31,-34.874979,138.543949,6,6,1&77,08 CRC BAD
VC5ARG-3,179,21:56:35(-14.874919,138.543)66,8,7,16 7,08 CRC BAD
VK5ARG-3,180,21:56:43,-34.874927,138.543918,8,7,1676,08 CRC OK
VK5ARG-3,181,21:56:51,-34. 74998,138.5 3896,9,7,1676,08 CRC BAD
V 5ARG-3,082,21:56:15,-34.875002,130.543870,15,?,1676,08 CRC BAD
VK ARG-3,183 21:57:03,-34.875025,138.543839(17,7,1676,08 CRC BAD
VK5ARG-3,184,21:57:11,-34.875056,138.543804,20,7,1675,08 CRC OK fixed
VK5ARG-3,185,21:57:15,-34.875022,138.543832,25,7,1675,08 CRC OK fixed

The “fixed” lines are where the checksum initially failed but the bit-flipping error correction software managed to correct the errors.

Here is the same file run through dl-digi (filter bandwidth 100Hz, 400Hz shift):