I'm trying to decode the image signal from a Mitsubishi VisiTel telephone image sender in a C++ program. It is encoded as an analog audio signal modulated with a sine wave carrier of ~1764Hz.
I'm reading the audio from the sound card input as signed 8-bits at 44.1kHz, which gives a period of about 25 samples for the carrier. Obviously, the analog signal is not going to fall nicely on sample boundaries, so assume that this could shift by +/-1 sample.
My first attempts to decode the signal were by taking the peaks of the signal and assigning those as pixel values. That almost worked, but there seemed to be some "off-phase" pixels and the image would eventually skew.
Eventually, I got a signal by decoupling the pixel clock from the peaks and tying it to the samples. I also had to time each scan line separately, as it didn't end on a pixel multiple somehow.
But this signal wasn't quite correct, dark areas were coming out inverted somehow.
Image with dark areas inverted
Eventually I realized that there was a phase discontinuity at the light/dark transition. This indicated to me that the modulation signal was going over the zero point, causing the phase discontinuity in the resulting signal as it drives the carrier negative, reversing the peak/ trough relationship.
Discontinuity in AM signal
While I could try to modify my state machine to detect this type of transition, it seems like it would be kinda messy and prone to error.
I keep thinking that there has to be a proper math-y way to demodulate an AM signal where the modulator crosses the zero point. But all of the examples I am finding seem to just be simple peak based envelope detectors. The product detector explanations I've found seem to count on you having your carrier and phase exactly correct, and I'm not sure that still buys me anything for zero crossing signals.
What is the correct party-approved way to demodulate AM signals where the modulator crosses zero?
1
votes
Usually what you do is multiply your signal by a sine wave at the carrier frequency f_c and then filter off the resulting 2f_c signal - a simple low-pass filter usually suffices. For better accuracy you can multiply by a sine and cosine carrier wave, filter, then compute the squared magnitude signal so you can be phase invariant. With the proper filtering (after signal multiplication) you won’t have to worry about zero-crossing artifacts.
– nneonneo
Also, I’d strongly consider doing this in an environment like GnuRadio which already has high-quality implementations of all the relevant filters - like AM receivers.
– nneonneo
@nneonneo That sounds like the "product detector" implementation which I worried would be sensitive to not having the exact carrier frequency and phase... is that not the case? Also, wouldn't a simple low-pass filter just smooth out some of the peaks and still lose the negative data? This isn't a one-shot thing, but something that requires a stand-alone program. I can't request the user to drag data files off to Gnu Radio for interpretation, so I have to be able to include it in my source code.
– SoftEgg
A product detector which uses both sine and cosine will be tolerant to frequency and phase errors. It’s more-or-less an I-Q demodulator that only outputs amplitude. If you perform the product you’ll find that the frequency of the “carrier” goes up considerably and thus becomes easier to smooth out with a low-pass filter.
– nneonneo
2 Answers
0
votes
0
votes
You're going to need to determine the phase of the carrier, and then you can use a product detector. A quadrature detector would let you determine the phase after the fact, but since you have to do it anyway, you might as well do it first.
It is very likely that the VisiTel transmits a sync signal of some sort before the image that would have been used to determine the carrier phase and to indicate the start of picture transmission to the receiver. You should probably use that for its intended purpose.