WFM Stereo Broadcasting Standards - OIRT vs CCIR - Page 1
Forum section: electronics / rf-microwave

author: radiolistener
author_rank: Super Contributor
timestamp: August 24, 2025, 02:51:28 pm
content: As you probably know, there are two standards for WFM stereo broadcasting - one applied in the OIRT band (65.9 - 74 MHz) and the other in the CCIR band (87.5 - 108.0 MHz).OIRT uses 31.25 kHz subcarrier to transmit L-R component, with so called "polar modulation" and partially suppressed subcarrier.CCIR uses 38 kHz subcarrier to transmit L-R component, with DSB-SC and pilot-tone at 19 kHz in order to recover subcarrier.I am working on adding OIRT FM stereo decoder support to my receiver. Unfortunately, there is no longer any stereo broadcasting in the OIRT band in my region - only mono transmission remains. I also don’t have access to IQ recordings of actual OIRT stereo broadcasts for testing, so I have to rely on old magazine articles and schematics of stereo decoders.One point I find confusing is the terminology: in the OIRT stereo composite signal, the modulation is often described as "polar modulation". It is not entirely clear to me what exactly is meant by this.From what I understand, the stereo composite modulation in both CCIR and OIRT systems is essentially DSB. The main difference is that in CCIR, the 38 kHz subcarrier is completely suppressed and recovered on the receiver side by doubling the transmitted 19 kHz pilot tone, whereas in OIRT stereo-composite there is no pilot tone - instead, the 31.25 kHz subcarrier is only partially suppressed (about -14 dB), allowing it to be recovered directly on the receiver side.Apart from this subcarrier recovery method, it seems to me that the modulation principle is the same in both systems, so the same DSB demodulator could be used for both standards, with the only difference being the subcarrier recovery mechanism.Am I understanding this correctly?If anyone happens to have a recording of an FM broadcast in OIRT stereo mode (65.9 - 74 MHz band), I would greatly appreciate it. Ideally this could be provided as a WAV file containing an IQ IF stream, or alternatively as a direct recording of the composite signal from the FM detector output.

author: gf
author_rank: Super Contributor
timestamp: August 24, 2025, 03:30:43 pm
content: Here's what Google Gemini told me:https://g.co/gemini/share/2583583ca5adI can't assess correctness, but it sounds plausible.

author: radiolistener
author_rank: Super Contributor
timestamp: August 24, 2025, 07:25:25 pm
content: Quote from: gf on August 24, 2025, 03:30:43 pmIt seems the Gemini AI response introduces some confusion here. It states:Quotewhich is clearly incorrect. In fact, polar modulation in the OIRT stereo system refers to the modulation of the stereo subcarrier in the composite signal, not the main FM carrier itself.If I understand correctly, the mathematical difference can be described as follows (Octave code), we have:Code:Fs = 384000; % sample rateN = length(L) % sample countt = (0:N-1).' / Fs; % time vector% Build sum and differenceadd_LR = (L + R) / 2; % sum channelsub_LR = (L - R) / 2; % difference channelThen:- CCIR uses this:Code:pilot = 19000; % pilot tone frequency 19 kHzsubcf = pilot*2; % sub-carrier frequency 38 kHzpilot = cos(2*pi*pilotf*t); % pilot tone 19 kHzc38 = -sin(2 * 2*pi*pilotf*t); % carrier 2*19=38 kHzdsbsc = sub_LR .* c38;% Composite baseband signal (L+R + pilot + DSB-SC)composite = 0.45*add_LR + 0.1*pilot + 0.45*dsbsc;While OIRT uses something like this:Code:subcf = 31250; % sub-carrier frequency 31.25 kHzc3125 = sign(cos(2*pi*subcf*t)); % squarewave subcarrierpolar = 0.2*c3125 + sub_LR .* c3125;% Apply bandpass filter with center frequency 31.25 kHz ±15 kHzpolar = filtfilt(bpf_31250, 1, polar);% Composite baseband signal (L+R + polar)composite = 0.45*add_LR + 0.45*polar;And since it uses squarewave carrier with following BPF, it is actually equals to:Code:c3125 = cos(2*pi*subcf*t); % sine wave subcarrierpolar = 0.2*c3125 + sub_LR .* c3125;% Composite baseband signal (L+R + polar)composite = 0.45*add_LR + 0.45*polar;which is more easy and clean, because don't involve BPF to remove harmonics added with square wave carrier.As result, in the OIRT case, the square wave subcarrier generates harmonics, which must then be removed by a band-pass filter to keep the spectrum within ±15 kHz. After filtering, this is essentially equivalent to using a DSB-SC scheme with a partially suppressed carrier. By contrast, the CCIR system is simply DSB-SC with the carrier fully suppressed and reconstructed from the 19 kHz pilot tone.So in effect, the only difference is that OIRT leaves a residual carrier (at about -14 dB) while CCIR completely suppresses it. Also it means that you can use polar demodulator to decode both - OIRT and CCIR system. The only difference is a subcarrier recovery scheme.Am I understanding this correctly?I do not have access to the real OIRT stereo signal recording to verify my understanding of the stereo composite modulation in this system, so I have to rely on fragmented descriptions and circuit diagrams from old radio magazine publications from 1970...Here is one of the schematics published in Radio magazine, issue No. 3, 1974. According to the circuit, transistor T1 amplifies the signal, T2 recovers the 31.25 kHz subcarrier, then the low-frequency part (L+R) is extracted, while the high-frequency part containing (L–R) is amplified by T3 (L3 is tuned at 31.25 kHz, Q=4.9, R16 is used to decrease Q-factor) and demodulated using a diode bridge. Finally, the L and R channels are formed as:Code:L = (add_LR + sub_LR) / 2;R = (add_LR - sub_LR) / 2;

author: gf
author_rank: Super Contributor
timestamp: August 24, 2025, 07:54:27 pm
content: Quote from: radiolistener on August 24, 2025, 07:25:25 pmI really don't known. However, polar modulation makes only sense to me in a context where a single carrier is modulated withtwomodulating signals. And this applies rather to the main carrier. Since the sub-carrier is only modulated with a single modulating signal (L-R), I see no need for polar modulation for the sub-carrier at all. What would be the 2nd modulating signal?Of course, instead of polar modulation, L+R and the modulated sub-carrier could also be added, and then FM-modulated onto the main carrier (like CCIR). But then no polar modulation would be in the play at all.

author: radiolistener
author_rank: Super Contributor
timestamp: August 24, 2025, 08:21:28 pm
content: Perhaps someone could help by performing a practical test: the idea is to transmit a generated composite signal with a low-power transmitter and check whether OIRT stereo receivers produce correct stereo decoding. The test signal could be prepared either as a baseband composite signal for direct input into an FM modulator, or as a fully FM-modulated IQ recording centered at 0 Hz, which would then only need to be shifted to the desired frequency.I checked through my old radio receivers, but unfortunately all of them are equipped only with CCIR stereo decoders, so at the moment I have nothing suitable to test with.If anyone has an old radio receiver with an OIRT stereo decoder, or access to a local OIRT stereo broadcast, I would greatly appreciate it if you could let me know.

author: gf
author_rank: Super Contributor
timestamp: August 25, 2025, 04:29:38 pm
content: After challenging Gemini and pointing out contradictions, it changed its mind several times and its most recent conclusion wasQuoteQuoteQuoteSo I think your assumption is correct. It's likely similar to CCIR, but w/o pilot tone, and with AM/DSB-RC instead of AM/DSB-SC for the subcarrier, and the term "polar modulation" is just used to create confusion.Today, the term 'polar modulation' does not refer to a specific type of modulation, but rather to a particular power amplifier (PA) architecture in which a linear PA is emulated using a highly efficient non-linear PA. The same RF signal that can be generated using I/Q modulation and a linear PA can also be generated using a polar modulation PA, with better efficiency.

author: radiolistener
author_rank: Super Contributor
timestamp: August 25, 2025, 04:43:57 pm
content: I came across this discussion on generating the OIRT stereo composite:https://forums.stereotool.com/viewtopic.php?t=6233Unfortunately, there are few technical details and no example signals provided, but it seems that the authors of StereoTool have implemented a working version of polar stereo encoding for OIRT. If anyone here uses this tool, could you possibly create a small test wav file with a stereo composite signal in polar stereo format?The discussion also references a standard that provides some details on deviation and the relative levels of the components in the composite stereo signals for both OIRT and CCIR systems:https://www.itu.int/dms_pubrec/itu-r/rec/bs/R-REC-BS.450-3-200111-S!!PDF-E.pdfAccording to this document, the frequency deviation for OIRT stereo broadcast is 50 kHz instead of 75 kHz which is used in CCIR.Also it mentioned OIRT stereo-composite proportions:QuoteA = left channelB = right channelM = (A+B) / 2S = (A-B) / 2Both M and S are pre-emphasised with pre-emphasis 50 us (standard pre-emphasis for Europe).AM modulated signal (which consists of S message) is spectrum shaped with mentioned K(f) law in order to suppress carrier for -14 dB.From the text it is not entirely clear whether the spectrum of the AM-modulated signal should be corrected according to K(f), or if the more correct approach is simply to combine the full DSB-SC amplitude with the carrier attenuated by -14 dB.

author: gf
author_rank: Super Contributor
timestamp: August 25, 2025, 10:19:48 pm
content: Quote from: radiolistener on August 25, 2025, 04:43:57 pmYes it isn't clear. Interestingly, the transfer function K(f) is a highpass with ~0.8Hz cutoff and 14dB stopband attenuation. If the subcarrier amplitue is suposed to be represented by the DC component of the baseband modulating signal, then this filter - applied to the baseband signal - would provide the -14dB subcarrier attenuation.

author: Njk
author_rank: Frequent Contributor
timestamp: September 07, 2025, 11:50:45 pm
content: Quote from: radiolistener on August 24, 2025, 08:21:28 pmWell, we still have 3 working stations of the OIRT band here in St. Petersburg. For one of them, 69.47 MHz, my old receiver indicates a stereo signal (just checked).https://radiomap.eu/ru/sankt-peterburgPerhaps you can use a WebSDR connection to view the signal

author: radiolistener
author_rank: Super Contributor
timestamp: September 08, 2025, 05:30:47 am
content: Quote from: Njk on September 07, 2025, 11:50:45 pmUnfortunately websdr doesn't support wideband FM, its limit - max 20 kHz, while OIRT stereo FM requires at least 96.25 kHz bandwidth. And there is no websdr receiver covering 69.47 MHz at that location, only ham bands on HF and VHF...Could you please record the file with baseband IQ of this station with RTLSDR? You can do it withHDSDR.It is important to setup LO outside of station bandwidth - use LO=69.3 MHz or LO =69.7 MHz for recording, it helps to avoid DC spur which can affect signal quality. It's better to setup RTLSDR sample rate 960 kHz instead of 2.4 MHz to reduce file size, since I need just +-150 kHz around station frequency. Also please disable AGC and setup good RF gain manually, to avoid unwanted gain variations.30-60 seconds record will be enough. If possible, please record it when station broadcasting some music or sound which allows to hear stereo effects and distinguish it from mono. If such music composition will allow to check proper left/right channel decoding it will be great.You can share file onhttps://transfiles.ru/

author: Njk
author_rank: Frequent Contributor
timestamp: September 08, 2025, 09:34:30 pm
content: The problem is that it's old Soviet receiver, Leningrad RP-015 to be precise. It has no IQ outputs. The model is well known so you can find the schematic diagrams on the internet. There are no patented chips, it's made entirely of discrete components. There is a test point right after the FM detector and before the stereo decoder, marked with "80 mV". I think it would be possible to route the baseband signal from the test point to the input of a PC sound card for recording. But it's not required for a sound card to support the BW above 20 kHz, while all the decoding magic happens at the frequencies of up to 62 kHz. So I'm not sure the recorded file will be useful. Anyway, the stereo decoder in the receiver does not seem a very complex circuit. Perhaps you can get a clue by looking into the diagram.I don't have an SDR dongle either. In my case, it just does not make sense. It's a big city and the reception is very poor. I can't hear anything on the AM bands no matter of the receiver. While the FM provides only a local content. So I'm not an SDR fan. I can only confirm the existence of the stereo signal in my area

author: radiolistener
author_rank: Super Contributor
timestamp: September 09, 2025, 05:27:12 am
content: It is a pity that you don’t have any SDR hardware available to make a direct recording of the signal. Even a very inexpensive dongle (10–20 USD) can do much more than just listening to radio – it allows spectrum analysis, interference studies from household equipment, debugging and aligning radio circuits across HF, VHF and UHF. I also live in the center of a large city with plenty of noise, but radio is still quite usable here: both HF and VHF broadcasting, amateur stations, satellites, and even frequency standard signals that can be used to calibrate frequency counters, generators, receivers or transceivers.You are right that the stereo decoder circuitry itself is not extremely complex, but all the phase relationships and details matter a lot, so extracting the exact encoding parameters from schematics alone is unreliable – we really need real-world signals for verification. On your receiver’s diagram you indeed pointed out the correct place for recording the stereo composite: the KT7 80 mV test point. However, as you mentioned, capturing it with a standard sound card is problematic because of the input low-pass filter.For composite recording an IQ signal is not required – it’s just a mono baseband with about 100 kHz bandwidth. In theory it could be digitized with a sound card at 384 kHz sampling rate (giving 192 kHz bandwidth), but in practice most sound cards have an input LPF around 20 kHz. A better option would be a capture card with 150–200 kHz effective bandwidth, or even a digital oscilloscope with sufficient memory depth. But I suspect you may not have such equipment either.The most practical solution would be recording the IF with an SDR receiver. Perhaps you could borrow an RTL-SDR from a friend – these dongles are very popular among radio amateurs nowadays because they are inexpensive and versatile. They allow not only receiving nearly any band from longwave to UHF, but also testing and aligning radio equipment.If you don’t have access to an SDR, you could still try recording the composite with a sound card, just in case. To compensate for the LPF effect, it would be very helpful if you could also record plain white noise from the same input – then I could attempt to restore the frequency response of your sound card and design a correction filter to recover as much of the high-frequency content as possible. Often the LPFs in sound cards are quite weak and do not completely suppress higher frequencies. Of course, this is a rather problematic and challenging approach to try to reconstruct the signal in such a way, but since there are no other available options to obtain an OIRT stereo composite sample, it might still be worth attempting.It is especially regrettable that, from what you describe, your local station really does broadcast stereo in the OIRT system. According to the schematic, your receiver indeed detects OIRT stereo with the 31.25 kHz subcarrier, so there is little doubt about it. It is a pity that you don’t have the technical means to capture and record this signal. Broadcasts in this system are becoming quite exotic nowadays: much of the old transmitting equipment has aged and gone out of service, and modern replacements for OIRT seem to be very rare. In most cases stations still operating in this band transmit only in mono.I am very interested in implementing an OIRT stereo encoder/decoder in DSP and experimenting with its pros and cons compared to the CCIR system. Unfortunately, in my region broadcasting in this band is only mono, so I have no chance to capture such signals myself.Can you help with obtaining such OIRT stereo-composite recording for testing?

author: Njk
author_rank: Frequent Contributor
timestamp: September 09, 2025, 06:05:58 pm
content: How many samples are needed? For me, the simplest option seems to capture the baseband signal with Rigol DS1054Z scope (check the specs. It's the only digitizing scope I have)

author: radiolistener
author_rank: Super Contributor
timestamp: September 10, 2025, 02:56:56 am
content: Quote from: Njk on September 09, 2025, 06:05:58 pmAs many samples as possibleFor example, with a Siglent scope that has 14 Mpts of memory, I can capture 14 seconds at a 1 MSa/s rate. To do this, it is necessary to manually disable Roll mode (which is enabled by default below 50 MSa/s) and to enable the 20 MHz low-pass filter to minimize aliasing. I think that 14 seconds should be sufficient to clearly hear the stereo.There is, of course, a risk that aliases from frequencies above 500 kHz may affect the signal quality, but it is still worth trying.

author: Njk
author_rank: Frequent Contributor
timestamp: September 10, 2025, 11:17:32 pm
content: Ok then. Take the receiver apart, blow the dust off and capture the signal. Will do it on the next week (hopefully). BTW for better anti-aliasing, I can arrange a simple passive LP filter (two res, two caps) with the cutoff frequency of about 100 kHz

author: radiolistener
author_rank: Super Contributor
timestamp: September 11, 2025, 05:32:35 am
content: Quote from: Njk on September 10, 2025, 11:17:32 pmNo, it is better not to use an LPF at all than to add a simple 100 kHz one, since such a filter can significantly attenuate the amplitude of the encoded L–R signal, given that the OIRT stereo composite has a bandwidth of 100 kHz. If you do apply an LPF, it should have a much higher cutoff, around 300–400 kHz.I am looking forward to the test sample — it will be interesting to see how the OIRT stereo composite actually looks.

author: radiolistener
author_rank: Super Contributor
timestamp: September 17, 2025, 07:02:29 pm
content: I came across an article about polar modulation for stereo signals. It refers to a 31.25 kHz subcarrier, which suggests it is describing the OIRT stereo composite standard. However, what seems odd is that the article claims polar modulation assigns the left and right channels to the corresponding polarities of the subcarrier. This is unusual, since earlier publications indicated that the subcarrier carries the difference signal (L−R), in addition to the mono sum signal (L+R). Moreover, the detection circuit shown appears overly simplistic—essentially just two diodes.What exactly is being described here? Is this an earlier revision of the standard, or simply a misunderstanding and the circuit itself is incorrect?

author: gf
author_rank: Super Contributor
timestamp: September 18, 2025, 05:44:31 pm
content: I haven't checked in detail yet but I think the described asymmetric AM does not fit within the +-15kHz bandwidth around the sub-carrier. And if you remove sub-carrier harmonics and their sidebands, I think you lose the intended asymmetry.

author: radiolistener
author_rank: Super Contributor
timestamp: September 18, 2025, 06:20:23 pm
content: Yes, that’s exactly the confusing part. There are many references claiming that OIRT used some kind of “polar modulation”, but I suspect there is some kind of a misinterpretation. From what I can see, the system probably is essentially the same as CCIR stereo: the baseband carries L+R, and the 31.25 kHz subcarrier is DSB-modulated with L−R, only with the subcarrier left partially suppressed (at −14 dB) rather than fully suppressed as in CCIR.The question then is: where do all the statements about direct diode decoding come from? The article above even includes a schematic with nothing more than two diode detectors and RC filters. This seems questionable — could such a simple circuit really decode a stereo signal in which the subcarrier is modulated with L−R?That’s why I’m looking for an actual recording of an OIRT stereo broadcast. With a real composite signal it would be possible to analyze the spectrum and confirm what is really transmitted.I did find a screenshot of an OIRT station transmitting in stereo — the composite signal spectrum is faintly visible there — but unfortunately that’s the only material I’ve managed to locate so far.

author: Njk
author_rank: Frequent Contributor
timestamp: September 19, 2025, 02:13:53 am
content: To radiolistener

author: gf
author_rank: Super Contributor
timestamp: September 19, 2025, 12:12:14 pm
content: Quote from: radiolistener on September 18, 2025, 06:20:23 pmDoing some numerical experiments, it seems that that positive and negative rectification of a composite signal L + R + subcarrier DSB-modulated with L-R, can separate L and R. The separation was imperfect, though, and I did not get reasonable separation at all with DSB-RC. I also don't know if the experiment generalizes to arbitrary L and R signals, since the rectification is a non-linear operation, so additivity is not granted.The asymmetric AM-modulation scheme described in the paper generates a composite signal containing a L+R component, the subcarrier DSB-modulated with L-R, and sidebands of subcarrier harmonics (but no subcarrier harmonics themselves). This signal can, of course, be separated to L and R by positive and negative rectification (and subsequent lowpass filtering), but due to the presence of sidebands of subcarrier harmormics, it has a much higher occupied bandwidth. After removing the sidebands of subcarrier harmormics with a lowpass, we would basically end up with a compositive signal L + R + subcarrier DSB-modulated with L-R (but not DSB-RC).EDIT: Here's a simulation of the asymmetric AM with random L and R random signals, BW-limit to eliminate sidebands of sub-carrier harmonics, and demodulation by positive and negative rectification of the composite signal + lowpass (=> "ideal diode detector", but a much better lowpass). The demodulated signals are decomposed into L, R, DC components and residuals to assess the goodness of separation. With the random L and R the separation is not that bad. Std(resid) could be lower, I don't know yet where exactly it comes from.Code:pkg load signalfs = 1e6fsub = 31250audiobw = 15000SKIP = 20000N = 100000 + SKIP% generate bandwith-limited random L and R signalsL = 2 * rand(1,N) - 1;R = 2 * rand(1,N) - 1;[n,Wn,beta,ftype] = kaiserord([0.95*audiobw audiobw],[1 0],[0.0001 0.0001],fs);hnoise = fir1(n,Wn,ftype,kaiser(n+1,beta),"noscale");L = filter(hnoise,1,L);R = filter(hnoise,1,R);L /= max(abs(L));R /= max(abs(R));% L = cos(2*pi*2000*[0:N-1]/fs);% R = cos(2*pi*3000*[0:N-1]/fs);% subcarriersubc = cos(2*pi*fsub*[0:N-1]/fs);% asymmetric AMcomposite = max(0,subc) .* (1 + L) + min(0,subc) .* (1 - R);% limit BW of composite signal[n,Wn,beta,ftype] = kaiserord([fsub+audiobw 2*fsub-audiobw],[1 0],[0.0001 0.0001],fs);hcomp = fir1(n,Wn,ftype,kaiser(n+1,beta),"noscale");composite = filter(hcomp,1,composite);% lowpass after rectifier[n,Wn,beta,ftype] = kaiserord([audiobw fsub-audiobw],[1 0],[0.0001 0.0001],fs);hbb = fir1(n,Wn,ftype,kaiser(n+1,beta),"noscale");LR1 = [L; R; ones(1,N)];% compensate filter delaysdelay = (length(hcomp)-1)/2 + (length(hbb)-1)/2printf("Factor analysis of lowpass filtered composite signal:\n");x = filter(hbb,1,composite);lr1 = x(SKIP+1:end) * pinv(circshift(LR1,delay,2)(:,SKIP+1:end));resid = x(SKIP+1:end) - lr1*circshift(LR1,delay,2)(:,SKIP+1:end);printf(" mono: %9.6f * L + %9.6f * R + %9.6f + resid, std(resid) = %.6f\n", lr1, std(resid));printf("Factor analysis of rectified + lowpass filtered composite signal:\n");x = filter(hbb,1,max(0,composite));lr1 = x(SKIP+1:end) * pinv(circshift(LR1,delay,2)(:,SKIP+1:end));resid = x(SKIP+1:end) - lr1*circshift(LR1,delay,2)(:,SKIP+1:end);printf(" positive: %9.6f * L + %9.6f * R + %9.6f + resid, std(resid) = %.6f\n", lr1, std(resid));x = filter(hbb,1,min(0,composite));lr1 = x(SKIP+1:end) * pinv(circshift(LR1,delay,2)(:,SKIP+1:end));resid = x(SKIP+1:end) - lr1*circshift(LR1,delay,2)(:,SKIP+1:end);printf(" negative: %9.6f * L + %9.6f * R + %9.6f + resid, std(resid) = %.6f\n", lr1, std(resid));Example output:Code:fs = 1000000fsub = 31250audiobw = 15000delay = 4012Factor analysis of lowpass filtered composite signal:mono: 0.317287 * L + 0.317287 * R + -0.000000 + resid, std(resid) = 0.000005Factor analysis of rectified + lowpass filtered composite signal:positive: 0.316714 * L + 0.000577 * R + 0.320410 + resid, std(resid) = 0.002654negative: 0.000573 * L + 0.316710 * R + -0.320410 + resid, std(resid) = 0.002654EDIT: My first conclusion:The described modulation scheme generates directly a composite signal (including the mono component), not just the modulated subcarrier.The unfiltered composite signal can be demodulated virtually exactly with two ideal diodes + LPF, but is has too much bandwidthAfter limiting the bandwith to 46.25 kHz, demodulation with two ideal diodes is still possible, but it is no longer perfect:a) separation between L and R is no longer perfect, but still not too bad.b) Besides L, R and DC components, the 0-15kHz spectrum contains some residual components(noise/distortion). Still not sure where it comes from; I guess IMD introduced by the rectification. The residual component is larger when L and R are two sine waves, and smaller when L and R are wideband signals.In the tube era, these flaws were likely considered acceptable.While it seems to be a working scheme (with some restrictions), I'm no sure if this is really OIRT. The article does not claim that either; it just talks about "Soviet Stereo". The modulated subcarrier amplitude is relatively high, and the subcarrier itself is not reduced and consumes almost 50% of the composite signal power. But exactly these amplitude ratios, as produced by the described modulator, seem to be necessary in order to make simple diode detection work.

author: radiolistener
author_rank: Super Contributor
timestamp: September 20, 2025, 03:07:25 pm
content: Quote from: gf on September 19, 2025, 12:12:14 pmHm... so, if I understand correctly, it means that the stereo composite can indeed be demodulated using just two diodes, but the result will not be perfect in quality?

author: gf
author_rank: Super Contributor
timestamp: September 20, 2025, 08:49:56 pm
content: Quote from: radiolistener on September 20, 2025, 03:07:25 pmTo be more specific: It seems thatthis particularkind of stereo composite signal can be demodulated/decoded by ideal half-wave rectification + LPF (although the result is not perfect). How well thecircuitcan do the same job is a different question. This would require a circuit simulation. In particular, I cannot imagine an RC filter with a narrow 15...16.25 kHz transition band and high stop band attenuation at 16.25. But if you have speakers that cannot reproduce the residual ultrasound components in the output, and ears that cannot hear them, you may simply not care...Btw, it's interesting that the described asymmetric AM method (plus limiting the bandwidth to 31.25+15 kHz) happens to generate a composite signal equivalent to(L+R) / pi + subcarrier .* (1 + (L-R) / 2)IOW, what we get is the mono signal (L+R)/2, scaled by factor 2/pi, plus the sub-carrier, DSB-modulated with (L-R)/2, 100% modulation. No reduced subcarrier. Although it seems to be a feasible method in principle, is this really OIRT Stereo? I don't think so.EDIT:Quote from: radiolistener on September 20, 2025, 03:07:25 pmAttached is an example of the demodulated R channel spectrum, when the original L and R are sine waves with 3kHz and 4kHz. SFDR is about 25dB, SINAD about 21dB. When L and R are wideband signals (random noise), I see a little bit better SINAD of roughly 29 dB.EDIT: Added audio file of demodulated R channel, with 4 kHz tone.

author: radiolistener
author_rank: Super Contributor
timestamp: September 21, 2025, 06:17:59 pm
content: Thanks toNjk, we obtained a test sample of an OIRT stereo composite signal, recorded with a Rigol oscilloscope connected at the test point between the FM demodulator output and the stereo decoder input of the Leningrad RP-015 receiver.I applied a 50 kHz FIR low-pass filter for decimation and encoded the result into FLAC to reduce file size. The recording contains 24 seconds of music. The song is identified as "Prayer" by Tom Odell at 2:42:https://youtu.be/pTxeOOkTqYo?si=2aeP5-vgOQ81Fkii&t=162The quality is fairly good, although some frequency distortions are audible. Applying a de-emphasis IIR filter significantly reduces them, but slight artifacts remain, most likely due to the limited linearity of the oscilloscope ADC. The 31.25 kHz pilot carrier is well visible.The attached images show the spectrum of the original oscilloscope signal and the spectrum after applying the filter and decimation (file included).Still not tried decoding it yet, only tried to apply a 50 µs IIR de-emphasis filter to the L+R component, which produced good results.

author: Njk
author_rank: Frequent Contributor
timestamp: September 23, 2025, 01:12:32 pm
content: There can be some distortions because of multi-path reception. Very common phenomenon at my location. Tried to mitigate it by adjusting the antenna position but it's of dynamic nature and can happen at any time. BTW, another difference between OIRT and CCIR bands is that the former traditionally uses the horizontal polarization, so a receiving dipole is expected to be placed horizontally, like a TV antenna. While CCIR uses the vertical polarization. But for me, it makes no difference concerning the MPR. It's very annoying and happens with every receiver all the way

author: radiolistener
author_rank: Super Contributor
timestamp: September 23, 2025, 01:35:48 pm
content: I’m currently trying to decode stereo from the test sample shared above. It seems I overlooked something in my earlier analysis. In CCIR, the DSB signal is transmitted without a carrier, so once you recover the carrier (which appears not so easy with proper phase), its makes L-R recovery straightforward. However, in OIRT the signal includes a carrier. When the carrier is locked with a PLL and down-converted, a noticeable DC offset appears. I’d prefer not to rely on a HPF filter. What would be the option to remove this offset/carrier?A second complication is that this makes DSB amplitude recovery problematic, since it requires knowing the exact carrier level.

author: Njk
author_rank: Frequent Contributor
timestamp: September 23, 2025, 03:42:23 pm
content: The subcarrier level is about 100 mVpp. It can be measured when silence is broadcasting

author: radiolistener
author_rank: Super Contributor
timestamp: September 23, 2025, 06:32:24 pm
content: I was not referring to the absolute subcarrier amplitude. For proper stereo decoding it’s essential that the L+R and L–R paths maintain equal gain. The L+R component is straightforward, but the L–R signal first needs to be separated from the carrier and demodulated from DSB. This can be done with a synchronous detector using the PLL-locked carrier. However, because the carrier is present within DSB signal bandwidth, the result includes a DC offset and require HPF to remove it.I’d prefer not to use a high-pass filter just to remove that DC. My idea was to try subtracting the carrier directly, by taking the PLL output and attenuating it by 14 dB, then substract it from composite. The issue is that the actual level of the carrier may vary between transmitters, so a fixed 14 dB attenuation would likely leave a residual offset due to this mismatch.Any idea on how to extract L-R from DSB which include carrier but with no use of HPF?

author: radiolistener
author_rank: Super Contributor
timestamp: September 27, 2025, 01:50:05 am
content: I came across an interesting book by С.В.Мелихов, "Аналоговое и Цифровое Радиовещание" (S.V. Melikhov, "Analog and Digital Broadcasting") – see p.98 – which describes details of the MPX stereo composite for both OIRT polar modulation with a 31.25 kHz subcarrier and the CCIR system with a 19 kHz pilot tone. The book includes block diagrams for different demodulator types along with brief explanations.It turns out that the OIRT composite is essentially equivalent to the CCIR composite, with one key difference: instead of a pilot tone, the carrier is present in the DSB signal, attenuated by 14 dB. In this form, stereo can indeed be decoded with just two diodes.Here’s how a test stereo signal looks in Audacity (test composite is attached in flac file)As you can see, the upper half-wave contains the left channel and the lower half-wave the right channel. I didn’t do anything special here – this effect occurs naturally from combining the L+R component with the DSB-C modulated by L–R component.Below is an example block diagram of a simple polar stereo detector:The description notes that the main advantage of the polar detector is its simplicity and ease of adjustment. The drawbacks are limited channel separation and increased distortion during detection, especially for higher audio frequencies. This limited separation occurs because the phase angle corresponding to zero crossings of the subcarrier (2θ′) is not constant at 180° for each half-period, but depends on the relative amplitudes of signals A and B.The instability of the cutoff angles of diodes VD1 and VD2 leads to nonlinear distortion of signals A and B during detection. The THD of a polar detector in the low and mid-frequency range is about 2–3%. When detecting higher audio frequencies, the distortion increases further, reaching 6–8%. This is due to the fact that the subcarrier frequency of the polar-modulated signal is only 31.25 kHz / 15 kHz = 2.08 times higher than the upper audio frequency, meaning that within one period of the highest audio envelope there are only slightly more than two subcarrier cycles.Because of these drawbacks, polar detectors are not used in high-quality receivers.The book also presents a more refined sum-difference stereo decoder:According to the description, thanks to full-wave detection of the supersonic portion of the polar-modulated signal – where more than four subcarrier periods fit into one period of the highest audio frequency envelope – nonlinear distortion does not exceed 1–2%. Channel separation depends on circuit balancing (adjusted by potentiometers R7 and R8) and can reach about 32–36 dB.Another interesting design is a keyed stereo decoder that uses time-multiplexing:It is noted that the shorter the keying pulses, the greater the channel separation and the more accurately the A and B signals are reproduced. To achieve >30 dB separation and <1% distortion over 0.3–5 kHz, the control pulse width must not exceed 5 µs.Update: test-oirt-composite-50us.flac attachmend was updated due to resample aliasing issue in previous version

author: radiolistener
author_rank: Super Contributor
timestamp: September 27, 2025, 02:12:19 am
content: According to the book, the OIRT stereo composite consists of 0.8*(L+R) + AM-modulated 0.8*(L–R), with the AM carrier suppressed by 14 dB using a partial carrier suppression circuit (Q = 100 ± 5):This can be expressed in Octave as:Code:composite = 0.8*add_LR + (0.8*sub_LR .* osc3125) + 0.2*osc3125;I generated a test signal with these parameters (attached). Note that in my version I simply added the DSB-SC with a -14 dB (0.2) residual carrier at 31.25 kHz, whereas the book specifies that the transmitter uses an AM modulator and then suppresses the carrier by 14 dB. In theory, this results in some attenuation near DC, meaning low frequencies may be slightly reduced. In my test signal, that attenuation is absent, so bass components may sound louder. I think this is the meaning of K(f) function mentioned in the standard:QuoteThe test file with an IQ recording containing an FM-modulated test composite (50 kHz deviation, 50 µs pre-emphasis) is attached. If anyone has the chance to test this signal on a receiver with an OIRT stereo decoder, I’d be grateful for feedback – in particular: are the left and right channels reproduced correctly, and is the loudness and frequency response as expected?The file is provided in FLAC format to save space. FLAC is a lossless format, so no information is lost during conversion. Since most receivers only accept WAV, you can easily convert it using the sox utility by specifying the FLAC file as input and WAV as output:Code:sox test-oirt-wfm-50us.flac test-oirt-wfm-50us.wavPS: The test file is generated with the following pipeline:1) Input wav file has 48 kHz sample rate2) Apply FIR LPF with cutoff=15 kHz and 140 dB stop-band attenuation (296 taps)3) Upsample from 48 kHz to 192 kHz4) Apply pre-emphasis approximated IIR: \$H(z) = 1 + k - k z^{-1};\$ where \$k = F_s \cdot \tau\$5) composite = 0.8*add_LR + ((0.8*sub_LR) .* osc3125) + 0.2*osc3125;6) Upsample from 192 kHz to 960 kHz7) Do FM modulation with trapezoid integration:Code:wfm_df = 50000; % FM deviation Δf = ±50 kHzphi = 2*pi*wfm_df/Fs * cumtrapz(composite); % Trapezoid integration, H(s)=1/s -> H(z)=T/2 * (1+z^-1)/(1-z^-1)iq = exp( 1j*phi );8) Apply FIR LPF with cutoff=115.5 kHz (50+31.25+15 kHz bandwidth + 19.25 kHz safeguard) and 140 dB stop-band attenuation (384 taps)9) Downsample 960 kHz to 384 kHz10) Save to flac with 8-bit resolutionUpdate: test-oirt-wfm-50us.flac was updated due to resample images issue in previous version

author: radiolistener
author_rank: Super Contributor
timestamp: September 27, 2025, 03:20:41 am
content: The book states that a keyed stereo decoder with time-multiplexing of the stereo channels can achieve better performance than a sum-difference stereo decoder. As I understand it, this implies that in DSP one could simply apply upsampling for more accurate phasing, then sample at the peaks of the oscillator locked by the PLL, and finally apply a low-pass filter to the positive and negative half-waves, resulting in a high-quality signal. Am I correct in this interpretation? How much should the sampling rate be increased in practice to achieve good channel separation and low THD+N?I’m currently working on decoding using a PLL to recover the carrier, then mixing the signal down to the PLL-locked frequency, applying an LPF, integrating the DC component introduced by the subcarrier with 1-st order IIR LPF with 5 Hz cut-off, and subtracting it from the demodulated L–R. The L+R component is obtained simply by applying the same LPF to composite. The decoder works, but channel separation is somewhat not excelent, and a parasitic buzzing tone appears in the background around 2.5 kHz. A decoded file is attached.I haven’t been able to determine the source of this tone. I noticed it seems related to the input sampling rate: at 192 kHz, the buzz is present, but when using Fs = 31.25 × 6 = 187.5 kHz, it disappears. It seems likely that PLL noise due to imperfect phase alignment with the samples is causing it. I’m using a PLL with an arctangent phase detector. What could be the cause? Interestingly, the same PLL works without noise when decoding a CCIR signal at Fs=192 kHz.I experimented with adding a low-pass filter at the PLL phase detector input. This does shift the “humming” component to a lower frequency—roughly corresponding to the loop filter cutoff—but the noise still persists. Moreover, lowering the cutoff below 100 Hz leads to self-oscillation. What methods can be used to further reduce this background noise?Update: A minor issue with the resampling process was discovered, which was introducing image components into the L+R band. I’ve fixed it and re-uploaded the composite, WFM, and decoded files. However, this did not affect the background noise during decoding — it is still present.

author: Njk
author_rank: Frequent Contributor
timestamp: September 27, 2025, 11:41:55 am
content: Quote from: radiolistener on September 27, 2025, 02:12:19 amCould you provide an example for such device?

author: Njk
author_rank: Frequent Contributor
timestamp: September 27, 2025, 12:32:21 pm
content: BTW, the presence of subcarrier in the OIRT baseband signal provides one more advantage. In case of multi-path reception, everything becomes distorted, including the subcarrier sine wave. That facilitates easy indication of the multi-path condition. Use a tank tuned to the second harmonic of the subcarrier (62.5 kHz) to measure the harmonic's amplitude and show the number to the user. This is implemented in the L. RP-015 decoder (see the schematic diagram above).

author: gf
author_rank: Super Contributor
timestamp: September 27, 2025, 01:51:07 pm
content: Quote from: radiolistener on September 23, 2025, 06:32:24 pmIdeally, if the composite signal is exactly k1*(L+R)/2 + k2*subcarrier*(L-R)/2 +0.19953 * subcarrier, wheresubcarrierhas a peak amplitude of 1, then the DC offset (after down-conversion by multiplication with exp(-2i*pi*fsubcarrier*t)) should be a fixed constant value of 0.19953/2 = 0.099763, which you could subtract. However, in the case of imperfections, a high pass filter is likely the only option for removing an unknown DC component. You could use a very low cutoff, say 1 Hz. Note, by the way, that L-R is already high-pass filtered anyway, by the notch filter which reduces the carrier after AM modulation. So low frequencies are already imperfect anyway.

author: gf
author_rank: Super Contributor
timestamp: September 27, 2025, 04:18:52 pm
content: Quote from: radiolistener on September 27, 2025, 01:50:05 amIn other words, the composite signal is sampled at the positive and negative peaks of the subcarrier sine wave. Then, L and R are reconstructed with a brickwall lowpass filter. I tried that, and it does indeed seem to work very well.However, I don't find it well suited for a DSP implementation because it requires a very high sample rate for precise timing of the sampling points if the sample rate and subcarrier frequency are unrelated. Perhaps interpolation could mitigate this issue, but since the subcarrier needs to be recovered anyway, downconversion via multiplying by the recovered complex subcarrier is easier.

author: radiolistener
author_rank: Super Contributor
timestamp: September 27, 2025, 05:12:37 pm
content: Quote from: Njk on September 27, 2025, 11:41:55 amIt can be any SDR with transmit capability that supports an IQ baseband bandwidth of at least 384 kHz — for example, a PlutoSDR, HackRF One, or similar hardware.As an alternative, this could also be tested with your receiver by using a recording of the stereo composite itself instead of the IQ FM signal. In that case, you would need any playback device capable of reproducing a 50 kHz bandwidth signal from a digital recording and feeding it into the appropriate test point of the receiver. However, such playback devices may be hard to find in practice, since typical audio interfaces include a low-pass filter with a cutoff around 20 kHz.Here is actual spectrum of the test signal fromthis file.

author: radiolistener
author_rank: Super Contributor
timestamp: September 27, 2025, 06:08:14 pm
content: Quote from: gf on September 27, 2025, 01:51:07 pmAccording to the book, the exact coefficients are k1=k2=0.8. However, it states that these factors are applied directly to the L+R and L−R signals, rather than to the DSB/AM component. The remaining portion of the amplitude is allocated to the subcarrier, which is given as 0.2 according to the book.Thus, the expression takes the form 0.8*M + ((0.8*S) .* subcarrier) + 0.2*subcarrierwhere\$M = \frac{L + R}{2}\$; \$S = \frac{L - R}{2}\$With this proportion, the resulting composite has a peak amplitude of exactly 1, which I have verified — so in terms of scaling factors, everything checks out.The only practical question is how the subcarrier is attenuated. One option is to generate the subcarrier separately, attenuate it precisely to 0.2, and then add it to the DSB-SC: (0.8*S) .* subcarrier + 0.2*subcarrier. This is spectrally clean and does not affect the signal shape.Alternatively, as described in the book, transmitters can use AM modulation (DSB-C): (0.8*S + 1) .* subcarrier, in which case the subcarrier does not need to be added separately. However, this approach requires spectral shaping of the signal, which according to the book is implemented using anRC networkwith Q = 100 ± 5, essentially an IIR filter.The first approach is more in line with a DSP implementation, while the second corresponds to the design philosophy of traditional analog transmitters. However, given that transmitters are designed to employ such a filter, it may be more appropriate to adopt the same approach in DSP as well, in order to ensure proper reconstruction of the low-frequency components of the signal.Quote from: gf on September 27, 2025, 01:51:07 pmYes, in general this approach does work. However, I have encountered a subtle issue: it produces a faint, periodically varying hum. As I mentioned earlier, I provided anexample recordingof the decoded signal where this hum is present and you can hear it in pauses. I am not entirely sure of its origin, but it appears to be linked to the composite signal’s sampling rate: at Fs = 192 kHz the hum is noticeable, whereas at Fs = 187.5 kHz it disappears. My current suspicion is that this may be related to noise introduced by the DSP PLL when operating at sampling rates that are not an integer multiple of 31.25 kHz, but I cannot rule out the possibility of a mistake somewhere in my implementation. It is also possible that this background hum is present in the generated composite itself.

author: gf
author_rank: Super Contributor
timestamp: September 28, 2025, 11:30:54 am
content: Quote from: radiolistener on September 27, 2025, 06:08:14 pmObviously, the 0.2 stands for the -14dB reduced carrier (exact value would be 0.19953).QuoteI wonder if it is possibly easier for a PLL to lock if there is a gap around the subcarrier?QuoteHmmm, there's not much the encoder/modulator can do wrong. 192 kSa/s should be fine. And the effect of high-pass filtering the L-R channel should only reduce the stereo width at low frequencies - it is not supposed to introduce (nonlinear) distortion.To rule out the encoder/decoder, try demodulating without using the PLL-recovered subcarrier. Instead, use the same complex subcarrier, exp(-2i*pi*f_(subcarrier)*t), whose real part was used by the encoder for the modulation.Btw, how do you demodulate/decode?L = composite .* (1 + 2 * recovered_complex_subcarrier)R = composite .* (1 - 2 * recovered_complex_subcarrier)% whererecovered_complex_subcarrieris a complex sine wave exp(-2i*pi*f*t)% with correct frequency and phaseFinally, DC-removal + de-emphasis + lowpass filterting of L and R witha brickwall, cutting off steeply with a 15 kHz ... 16.25 kHz transition band)?I rather suspect the PLL. If it does not recover a clean carrier, the down-conversion can well produce intermodulation products.Check the recovered subcarrier with a FFT (after the PLL has settled).

author: gf
author_rank: Super Contributor
timestamp: September 29, 2025, 12:03:54 pm
content: Quote from: gf on September 28, 2025, 11:30:54 amThe following works nicely for me:[ pre/de-emphasis not yet implemented ]Code:pkg load signal% read stereo audio file, the file must alreay% have sufficient sample rate for composite[x,fs] = audioread("/tmp/test1.wav");L = x(:,1)';R = x(:,2)';% 15 kHz brickwall lowpass[n,Wn,beta,ftype] = kaiserord([14500 15000],[1 0],[0.0001 0.0001],fs);n += mod(n,2);lp15k = fir1(n,Wn,ftype,kaiser(n+1,beta),"noscale");% limit audio bandwithL = fftfilt(lp15k,L);R = fftfilt(lp15k,R);% generate subcarrierN = length(L)fsubc = 31250subc = exp(-2i*pi*fsubc*[0:length(L)-1]/fs);% stereo encodercomposite = 0.8*(L+R)/2 + 0.8*real(subc).*(L-R)/2 + 0.2*real(subc);audiowrite("/tmp/composite.wav", composite', fs);% stereo decoderLL = composite .* (1 + 2 * subc);RR = composite .* (1 - 2 * subc);LL -= mean(LL);RR -= mean(RR);LL = fftfilt(lp15k,LL);RR = fftfilt(lp15k,RR);audiowrite("/tmp/decoded.wav", real([LL;RR])', fs);Test signal is the first one from here:https://pixabay.com/music/search/30%20sec/

author: gf
author_rank: Super Contributor
timestamp: September 29, 2025, 03:21:24 pm
content: Generated composite signal.

author: gf
author_rank: Super Contributor
timestamp: September 29, 2025, 03:21:59 pm
content: Stereo decoded from the generated composite, using the original subcarrier from the modulator.

author: gf
author_rank: Super Contributor
timestamp: September 29, 2025, 07:05:18 pm
content: I also tried playing with a PLL, based on this document [ I did some modifications, though ]:https://s3.amazonaws.com/embeddedrelated/user/113580/digital%20plls%20part%203_68269.pdfMy sample rate (176400) is not related to the subcarrier frequency.[ Btw, in Octave, the PLL code runs horribly slow, as it is necessary to loop over the samples instead of working with matrices. ]Attached is the L/R decoded from my generated composite, using a PLL-recoverd subcarrier for the demodulation.With an intentionally wrong initial frequency (offset of 100 ppm), it locks within a few seconds. It doesn't seem to work that badly.[ However, so far I had no luck when I tried to lock it to Njk's composite signal and to decode it. The result is significantly distorted. ]

author: radiolistener
author_rank: Super Contributor
timestamp: September 29, 2025, 07:54:37 pm
content: Quote from: gf on September 29, 2025, 07:05:18 pmFor such real-time-like processing, a common approach is to implement the heavy part in C++ as a MEX function, which can then be called directly from Octave almost as fast as native code. The only con is that each time you modify CPP file, you need to recompile it - just execute command like:Code:mkoctfile --mex PLL_MEX.cppit will generate PLL_MEX.mex and you can call it from octave as PLL_MEX(...).For example, here is one of my old attempts to implement PLL (I'm not very familiar with PLL math, so it may be mistaken). Currently I'm using another one based onliquid-dsplibrary, but its less readable.1)The MEX extension codeCode:// linux: mkoctfile --mex PLL_MEX.cpp#include "mex.h"#include <cmath>void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {// Inputs:// prhs = samples (double vector)// prhs = w0// prhs = min_w// prhs = max_w// prhs = alpha// prhs = beta// prhs = phaseAdj// prhs = lockAlpha// prhs = lockOneMinusAlpha// prhs = lockThreshold// prhs = phase// prhs = phaseErrorAvgdouble *samples = mxGetPr(prhs);size_t N = mxGetNumberOfElements(prhs);double w0 = mxGetScalar(prhs);double min_w = mxGetScalar(prhs);double max_w = mxGetScalar(prhs);double alpha = mxGetScalar(prhs);double beta = mxGetScalar(prhs);double phaseAdj = mxGetScalar(prhs);double lockAlpha = mxGetScalar(prhs);double lockOneMinusAlpha = mxGetScalar(prhs);double lockThreshold = mxGetScalar(prhs);double phase = mxGetScalar(prhs);double phaseErrorAvg = mxGetScalar(prhs);// Outputsplhs = mxCreateDoubleMatrix(N,1,mxCOMPLEX); // vcoplhs = mxCreateDoubleMatrix(N,1,mxREAL); // isLockedplhs = mxCreateDoubleMatrix(N,1,mxREAL); // adjustedPhaseplhs = mxCreateDoubleMatrix(N,1,mxREAL); // phaseErrorAvgplhs = mxCreateDoubleMatrix(1,3,mxREAL); // updated state: phase, w0, phaseErrorAvgdouble *vco_re = mxGetPr(plhs);double *vco_im = mxGetPi(plhs);double *locked = mxGetPr(plhs);double *adjPhase = mxGetPr(plhs);double *peAvg = mxGetPr(plhs);double *stateOut = mxGetPr(plhs);for (size_t n=0; n<N; n++) {// generate VCOdouble c = cos(phase);double s = sin(phase);double x = samples;// Costas phase detector// I = input * cos(VCO)// Q = input * (-sin(VCO))double I = x * c;double Q = x * (-s);// phase error = I*Q (Costas detector)double phaseError = I * Q;// loop filterw0 += beta * phaseError;if (w0 > max_w) w0 = max_w;if (w0 < min_w) w0 = min_w;// exponential moving average of squared phase errorphaseErrorAvg = lockOneMinusAlpha * phaseErrorAvg + lockAlpha * phaseError * phaseError;// update phasephase += w0 + alpha * phaseError;phase = fmod(phase, 2*M_PI);double adjP = phase + phaseAdj;// lock detectionint isLock = (phaseErrorAvg < lockThreshold) ? 1 : 0;// store outputsvco_re = c;vco_im = s;adjPhase = adjP;peAvg = phaseErrorAvg;locked = isLock;}// Return updated statestateOut = phase;stateOut = w0;stateOut = phaseErrorAvg;}2) Usage:Code:Fs = ...;f0 = 31250; % target frequency Hzdf0=20; % frequency range Hzbw=10; % bandwidth Hzzeta=0.707;lockTime=0.5; % secondslockThreshold=1.0;w0 = 2*pi*f0 / Fs;min_w = (2*pi*f0 - df0) / Fs;max_w = (2*pi*f0 + df0) / Fs;alpha = 2*zeta * 2*pi*bw / Fs;beta = alpha^2 / (4.0 * zeta^2);phaseAdj = -1.75;lockAlpha = 1.0 - exp(-1.0 / (Fs * lockTime));lockOneMinusAlpha = 1.0 - lockAlpha;phase = 0;adjustedPhase = 0;phaseErrorAvg = 0;isLocked = 0;% call MEX[vco, isLocked, adjustedPhase, phaseErrorAvg, state] = PLL_MEX(...samples, w0, min_w, max_w, alpha, beta, ...phaseAdj, lockAlpha, lockOneMinusAlpha, ...lockThreshold, phase, phaseErrorAvg);

author: radiolistener
author_rank: Super Contributor
timestamp: September 29, 2025, 08:11:20 pm
content: Quote from: gf on September 28, 2025, 11:30:54 amCool, nice approach, I did it separately:Code:mixed = composite .* _osc3125;mixed *= 2; % correct amplitude% remove DCfc_dc = 10; % 10-20 Hz cutoff for DC estimation[b_dc, a_dc] = butter(1, fc_dc/(Fs/2), 'low');dc_est = filter(b_dc, a_dc, mixed); % low-frequency component ~DCmixed -= dc_est;% extract L-R_sub_LR = filter(lpf_15k, 1, mixed);_sub_LR /= 0.4;% extract L+R_add_LR = filter(lpf_15k, 1, composite);_add_LR /= 0.4;_L = (_add_LR + _sub_LR) / 2;_R = (_add_LR - _sub_LR) / 2;

author: tszaboo
author_rank: Super Contributor
timestamp: September 29, 2025, 09:15:39 pm
content: Quote from: radiolistener on September 23, 2025, 06:32:24 pmWhat happens mathematically, if you demodulate the signal 31.25 kHz/2 offset from the carrier frequency? It's too late right now to think clearly, as it's almost midnight, but I think using the mirror image (negative frequency) of the L-R signal and mixing it with the L+R might be somehow simple.

author: Njk
author_rank: Frequent Contributor
timestamp: October 02, 2025, 09:48:55 pm
content: Looks like it's implemented in the gqrx somehow (starting from v.2.4)https://github.com/gqrx-sdr/gqrx/blob/master/src/dsp/stereo_demod.cpp

author: gf
author_rank: Super Contributor
timestamp: October 03, 2025, 08:30:45 am
content: Looks like they do bandpass-filtering, before feeding into the PLL (which I did not do in my experiments - I directly tried to lock to the composite), This certainly improves locking and far-from-carrier noise (it won't improve close-in phase noise, though). Maybe I should try this as well.

author: radiolistener
author_rank: Super Contributor
timestamp: October 03, 2025, 10:48:18 pm
content: I tried installing gqrx. The interface is a bit unusual, but I managed to feed it a file. It runs rather slowly—unfortunately my machine doesn’t have enough performance for smooth playback without dropouts—but it does decode OIRT stereo. However, it seems to swap the L and R channels, and the stereo detection doesn’t always trigger. It’s unclear whether this is due to immature code or a misconfiguration on my part. But at a glance it appears to achieve good channel separation, so it’s worth studying the code more carefully.

author: gf
author_rank: Super Contributor
timestamp: October 04, 2025, 06:21:37 pm
content: Can the gqrx stereo decoder demodulate Njk's recorderd composite w/o distortion?

author: radiolistener
author_rank: Super Contributor
timestamp: October 05, 2025, 08:57:48 pm
content: Quote from: gf on October 04, 2025, 06:21:37 pmI removed it because with all its libraries and dependencies it was taking up quite a lot of disk space. However, I’m planning to extract just the OIRT/CCIR stereo decoding part into a separate test program for experimentation and will try it.