Re: Coding gain through orthogonal transforms & practical low rate codes (was: Re: QAM constellation script)

2023-05-06 Thread Daniel Estévez

On 06/05/2023 16:40, Marcus Müller wrote:

Yep, that'd be rate-1; you don't need to squint much to see that the 
N-point-DFT has exactly N (=often 2ᵐ) such entries, and when you send N 
symbols in parallel, you get a DSSS-single-user-CDMA system called OFDM :D

But that's not on bit-level.


Hi Marcus,

I wasn't speaking of sending 2^n codes simultaneously, but rather 
choosing one code out of a set of 2^n (our alphabet) to encode m bits 
and transmit that. Afterwards, choose another code out of the same set 
to encode the next m bits and transmit it. Etc.


In your OFDM example (really good point!), instead of OFDM (where you 
transmit in all subcarriers simultaneously), we would get 2^n-FSK (where 
we choose a subcarrier each time), with the possibility of having each 
tone be QAM modulated, if you wish to complicate it further and by 
analogy to OFDM.


While OFDM has the same uncoded BER as the QAM modulation you use in 
each subcarrier (it's really 2^n parallel and independent channels), 
this kind of 2^n-FSK+QAM doesn't have the same BER, I believe.


The (Fast) Hadamard transform is one of 
these things to decompose an arbitrary 2ᵐ length binary vector into 
orthogonal binary vectors of the same length (and I was pointed to it 
when a student of mine, someone else I forget and I were discussing how 
to make two uncorrelated random vectors from a single 64bit random 
vector in the context of WGN generation).


Unfortunately the Hadamard transform is not so good for spread spectrum. 
Some of the vectors you get have really ugly, non-spread spectrum (for 
example, one of the vectors is all 1's). The Hadamard transform has many 
other advantages, though.


In this sense, using different DSSS codes actually achieves some 
coding gain that justifies bandwidth expansion, whereas the 
alternative approach of using a single PN sequence modulated in BPSK 
is as you say a repetition code and doesn't provide any coding gain.


Yep, in the end this is finding a constellation in a higher-dimensional 
space that has better distance than the N times the embedding in 1d 
space. It's probably sphere packing all the way down.


An interesting problem is to consider coherent decoding of an N-symbol 
alphabet chosen from the vector space \mathbb{C}^n, where you are free 
to choose n as large as you want (or you can also do it in continuous 
time, but it doesn't change what happens).


The decision error probability basically depends on the angles between 
the N symbols, so it is advantageous to make these angles as large as 
possible.


The optimal solution that maximizes the minimum angle between the 
vectors is pretty neat. For N=2 you choose two opposite symbols (+1 and 
-1), so the angle is 180deg. For N=3 you choose the vertices of an 
equilateral triangle, so the angle is 120deg. For N=4 you choose the 
vertices of a regular tetrahedron, so the angle is ~109deg. In higher 
dimension we get a regular (N-1)-simplex. I haven't bothered to compute 
how the angle between vertices behaves as N->infty, but it probably 
tends to 90deg.


Choosing vectors following this solution is usually not convenient 
(people often want each component of the vectors to have the same 
amplitude, etc.). So orthogonal codes are a good alternative and more 
flexible solution, that is almost optimal for large N.


Now, of course this utterly disagrees with my gut feeling. We're doing a 
base transform, keeping the bit energy constant. We invert the process 
under white noise and are supposed to get a gain?!
But that's the difference between "classical" DSSS (and the OFDM up 
there) with the consideration that N-FSK might be a better embedding in 
N-dimensional complex space than m BPSK symbols would be: we're not 
necessarily "going back" before making the decision. Some 
representations are smarter than others to make decisions.


Yup. How you map your bits into symbols, and specially the geometry of 
those symbols (understood as vectors in C^n or C^[0,Ts]) matters. In 
fact there is a Shannon capacity for a binary-input channel and another 
(larger) Shannon capacity for an unconstrained input channel.


Surely this idea is very far from getting us a capacity-achieving code 
(any simple FEC beats uncoded m-FSK even if m is pretty large). But on 
the other hand, the typical bandwidth expansions of a DSSS system are 
on the order of 100x or more. I would be curious to know if there's an 
r=1/100 code that is good and can be implemented in practice.


There's a former colleague of mine who did[1] error-correcting codes for 
quantum key exchange reconciliation if you're interested in low-rate codes


The idea is that you have like LDPC codes very much, and wonder how you 
can construct them for low rates so that you don't go directly insane 
while en- and even more importantly while decoding.


That's an interesting idea! My main experience designing my own LDPC 
codes is with high rate code. My understanding from the literature is 
that for 

Coding gain through orthogonal transforms & practical low rate codes (was: Re: QAM constellation script)

2023-05-06 Thread Marcus Müller

Hi Daniel,


On 03/05/2023 18:20, Marcus Müller wrote:


¹ this is the standard situation for me to start a flamewar on the nature of DSSS: from a coding perspective, DSSS is just a repetition code. Repetition codes are what we call "bad", so instead of concatenating a r = 1/F DSSS-repetition-code after a r=4/5 Turbo code, we'd be much much better off just using a r=b/R "proper" code to begin with. I guess the thing is that decoding complexites of very low rate code decoders are usually not fun at bad input SNRs. 


On 06.05.23 09:45, Daniel Estévez wrote:
Not to start a flamewar, since I can see what you mean here, but I'm wondering: is DSSS 
the same as repetition code? A commonly used technique to transmit data with DSSS is to 
use 2^m quasi-orthogonal codes to transmit m bits per "symbol". These 2^m codes may be 
different codes drawn from the same pool (Gold codes, etc.), or circular shifts of the 
same code (this concept is being explored for future GNSS signals under the name of CSK, 
code shift keying). The uncoded BER performance is pretty similar to m-FSK, since the 
"symbols" are nearly orthogonal.


Yep, that'd be rate-1; you don't need to squint much to see that the N-point-DFT has 
exactly N (=often 2ᵐ) such entries, and when you send N symbols in parallel, you get a 
DSSS-single-user-CDMA system called OFDM :D
But that's not on bit-level. The (Fast) Hadamard transform is one of these things to 
decompose an arbitrary 2ᵐ length binary vector into orthogonal binary vectors of the same 
length (and I was pointed to it when a student of mine, someone else I forget and I were 
discussing how to make two uncorrelated random vectors from a single 64bit random vector 
in the context of WGN generation).


I might be misremembering things, but I think that for large m the BER performance of 
uncoded m-FSK is better than uncoded BPSK, simply because the BER curve falls off more 
steeply. 


I'll redefine things (sorry!): you're using an N-FSK, with N=2ᵐ, so that an FSK symbol 
carries m bits.


Thinking in AWGN & discrete time here, with fixed total energy E:
Considering this a bit of a geometric operation, taking an m-dimensional vector from 
{0,1}ᵐ and mapping it directly to a BPSK symbol vector from {+1,-1}ᵐ gives a bit-wise iid 
error probability that's inversely proportional to √m. For the BER curve, we know that 
we'll end up dividing the argument to our Q-function by √m, so d/(dE) BER becomes a 
scaling of -1/√m · f_{normal}(√m·…).


For N-FSK, I'll apply Parseval's Theorem to noise and signal, and find that the N-point 
DFT converts the frequency detection problem to a N-PPM detection problem (and that's 
optimal, since we concentrate all signal energy and keep noise energy maximally spread 
out; the DFT is the matched filterbank, if you will). The symbol error probability is
1 - P(no error), where no error occurs when each and every one of the other DFT output 
bins is lower in energy than the correct one.
WLOG, we put the Energy of the "correct" tone in bin X[0], and let all bins contain iid 
noise realisations:


  ⎧ √E + N[0] for k=0,
X[k] =⎨
  ⎩ N[k]  for k>0

noise and signal being uncorrelated,

   ⎧ E + N²[0]  for k=0,
X²[k] =⎨
   ⎩ N²[k]  for k>0

P(no error) = P(X²[0] > X²[1] ∧ X²[0] > X²[2] ∧ … ∧ X²[0] > X²[N-1])
introducing Z[k] = N²[k] - N²[0]
= P(E > Z[1] ∧ E > Z[2] …)
≤ P(E > Z[1]) · P(E > Z[2]) · …

So, we can find at least a lower bound for the error probability (which probably ends up 
being fairly tight). That bound arrives from the (N-1)th power of the complementary CDF of 
a K=2 𝜒²-distribution.


I'm honestly too lazy to make a plot now, but intuitively, k=2 𝜒²'s PDF is exp(-x/2), to 
the (N-1)th power it's exp(-(N-1)x/2) = exp(-(2ᵐ-1)x/2)


which is going to be a lot smaller than the modified 1/√m-scaled normal PDF we got from 
the BPSK experiment, as long as the SNR is > 1.


In this sense, using different DSSS codes actually achieves some coding gain that 
justifies bandwidth expansion, whereas the alternative approach of using a single PN 
sequence modulated in BPSK is as you say a repetition code and doesn't provide any coding 
gain.


Yep, in the end this is finding a constellation in a higher-dimensional space that has 
better distance than the N times the embedding in 1d space. It's probably sphere packing 
all the way down.


Now, of course this utterly disagrees with my gut feeling. We're doing a base transform, 
keeping the bit energy constant. We invert the process under white noise and are supposed 
to get a gain?!
But that's the difference between "classical" DSSS (and the OFDM up there) with the 
consideration that N-FSK might be a better embedding in N-dimensional complex space than m 
BPSK symbols would be: we're not necessarily "going back" before making the decision. Some 
representations are smarter than others to make decisions.


Surely this idea is very far from getting us a capacity-achieving code (an

Re: QAM constellation script

2023-05-06 Thread Daniel Estévez

On 03/05/2023 18:20, Marcus Müller wrote:

¹ this is the standard situation for me to start a flamewar on the 
nature of DSSS: from a coding perspective, DSSS is just a repetition 
code. Repetition codes are what we call "bad", so instead of 
concatenating a r = 1/F DSSS-repetition-code after a r=4/5 Turbo code, 
we'd be much much better off just using a r=b/R "proper" code to begin 
with. I guess the thing is that decoding complexites of very low rate 
code decoders are usually not fun at bad input SNRs.


Hi Marcus,

Not to start a flamewar, since I can see what you mean here, but I'm 
wondering: is DSSS the same as repetition code? A commonly used 
technique to transmit data with DSSS is to use 2^m quasi-orthogonal 
codes to transmit m bits per "symbol". These 2^m codes may be different 
codes drawn from the same pool (Gold codes, etc.), or circular shifts of 
the same code (this concept is being explored for future GNSS signals 
under the name of CSK, code shift keying). The uncoded BER performance 
is pretty similar to m-FSK, since the "symbols" are nearly orthogonal.


I might be misremembering things, but I think that for large m the BER 
performance of uncoded m-FSK is better than uncoded BPSK, simply because 
the BER curve falls off more steeply. In this sense, using different 
DSSS codes actually achieves some coding gain that justifies bandwidth 
expansion, whereas the alternative approach of using a single PN 
sequence modulated in BPSK is as you say a repetition code and doesn't 
provide any coding gain.


Surely this idea is very far from getting us a capacity-achieving code 
(any simple FEC beats uncoded m-FSK even if m is pretty large). But on 
the other hand, the typical bandwidth expansions of a DSSS system are on 
the order of 100x or more. I would be curious to know if there's an 
r=1/100 code that is good and can be implemented in practice. Probably 
there are diminishing returns when r -> 0, and decoding cost blows up. 
Hence the usual idea of concatenating a DSSS-repetition-code and an 
outer usual FEC (maybe not an r=4/5 Turbo, but r=1/6).


Best,
Daniel.



OpenPGP_signature
Description: OpenPGP digital signature


Re: QAM constellation script

2023-05-04 Thread Marcus Müller

> Tough I can foresee objections from narrow-band users of
> QO100 :)

Those should be on the narrowband transceiver on a slightly different band!

Cheers,
Marcus


smime.p7s
Description: S/MIME Cryptographic Signature


Re: QAM constellation script

2023-05-04 Thread George Katsimaglis
 Hi,
I have already make a proposal that with fh=False a multi user CDMA can be 
used.Each user will have a unique time in sawtooth shifting, the same time he 
can see all other Tx signals.Each Tx will be seen as 'constant frequency' as 
all users shift frequency the same rate.I do not claim that is the most 
efficient way, but that is technically possible.
George SV1BDS 
On Thursday, May 4, 2023 at 11:04:42 AM GMT+3, Adrian Musceac 
 wrote:  
 
 On Wednesday, 3 May 2023 19:20:10 EEST Marcus Müller wrote:
> Hi George,
> 
> that's a multiplicative voice scrambler!
> 
> The pre-Second World war voice scrambler system "SIGSALY" [1] was kind
> of similar;
> just that the scrambling sequence came out of a noisy vacuum tube, not
> Python's random.random(), and that the combination method was taking
> samples and adding them modulo 6, instead of multiplying the phase
> (which is inherently modulo 2π).
> 

That was a really nice description, thank you for taking the time to write 
that. The original project is also interesting, even if we call it differently.
So to me this looks like a basic CDMA access scheme, is there really any 
advantage to using it as opposed to standard FDMA as traditionally used on 
QO100? From an amateur radio operator perspective.

Adrian






  

Re: QAM constellation script

2023-05-04 Thread George Katsimaglis
 
Hi Marcus,
In QO100 there are Doppler shifts (that is the reason of the 200 Hz shift in 
flowchart).I have already implement a flowchart of calculating it using the 
middle BPSK beacon of QO100 using the frequency error of costal loop.My ground 
station is equipped with GPSDO.I have already do spread spectrum experiments 
with direct sequence of 1 M in QO100.Also initially I used FreeDV (which uses 
CODEC2) instead of USB in narrow band of SS.I use USB as it is more forgiving 
to frequency shifts due to Doppler.I have also implemented digital voice using 
CODEC2,HDLC, BPSK/QPSK in QO100 (thanks t\o GNURadio!!!).My QO100 ground 
station setup (90 cm for Rx and 3W@80 cm Tx ) permits me a few dB less signal 
than maximum allowed (beacon level) for a 2.7 kHz bandwidth in NB transponder. 
Once more : THANKS for the detailed answer!!!
George SV1BDS

On Wednesday, May 3, 2023 at 07:20:13 PM GMT+3, Marcus Müller 
 wrote:  
 
 Hi George,

that's a multiplicative voice scrambler!

The pre-Second World war voice scrambler system "SIGSALY" [1] was kind 
of similar;
just that the scrambling sequence came out of a noisy vacuum tube, not 
Python's random.random(), and that the combination method was taking 
samples and adding them modulo 6, instead of multiplying the phase 
(which is inherently modulo 2π).

So, that should work quite nicely for spreading; it's not as great for 
the secretive purposes the (later) Allies developed the original scramblers:

 1. We're re-using the same 10240 length sequence as scrambling signal –
    that's very fine for the spreading, but from a cryptographic point
    of view, if the secrecy of a message depended on an eavesdropper not
    knowing the sequence, not great, because it's easy with a bit of
    statistics to recover an approximative spreading sequence.
 2. Since the bandwidth of the scrambled signal is much higher than the
    unscrambled message signal, an envelope detector on the whole
    bandwidth can probably (I didn't try) recover a pretty intelligible
    version of the audio signal (in the end, if the power of the audio
    signal is low, due to the multiplications, so is the power of the
    signal you transmit; it's kind of similar to AM, but instead of
    modulating a carrier, we modulate a white noise source). Of course,
    knowing the spreading sequence (i.e., knowing how to seed
    random.seed()) gives a large processing gain and thus much better
    SNR at the receiver's output than plain power detection.

But you're no trying to send secret messages – you're just trying to use 
a wide band of spectrum, and for that, your solution works fine, if your 
synchronization between transmitter and receiver is good enough in time 
and frequency.

There's a bit of a hurdle there: No two oscillators are /exactly/ the 
same, and there's also things like Doppler – so you need to use your 
preamble (fh==False case) to not only know at which time you need to 
start your random multiplication, but also to know by how many Hertz 
your receiver is tuned off the "correct" frequency. If your receiver 
doesn't have the exact same frequency as the transmitter, you see that 
by a frequency shift in the baseband, so a multiplication with an exp(2j 
· π · f_error · t), and that means that the phase of every sample gets 
shifted by an additional f_error/f_sample more, and the receiver might 
no longer work. To combat that, you need frequency recovery (which could 
very nicely be done on a preamble, it's just not inherently trivial to 
do it with a chirp), and because your receiver's oscillator might still 
drift over time, maybe adding a pilot tone every so and so many seconds 
might help.

In practice, what you'd probably do is take your idea and change a few 
things about it. I'll illustrate the design process with sensible 
example values below. Sensible in the sense that all the things are 
available technologies in the open source space, and not too hard to get 
to work on normal hardware:

It seems you're directly modulating analog audio. Instead, since ca the 
1980s, you'd usually use a voice encoder / decoder pair (i.e., a 
vocoder) to transform the voice into bits, then add error correction to 
them, then spread these – that's a lot easier, and you get the chance to 
use the energy you transmit for the bandwidth the "useful" information 
in your voice actually has, and the energy necessary to make it have the 
least error in the presence of noise, instead of having to transport the 
full audio bandwidth! Then, you could design a system to use the simple 
Direct-Sequence Spread Spectrum (DSSS) method.

DSSS is rather easy: you take a transmit symbol, and repeat it by a 
spreading factor F, and then flip the sign of the symbols ("chips") 
according to a fixed pseudorandom bit sequence that receiver and 
transmitter both share. You send the signal with the full sample rate, 
meaning that you increase the bandwidth by F (that's the spreading). At 
the receiver, you flip in

Re: QAM constellation script

2023-05-04 Thread Adrian Musceac
Sorry,, I meant to send the previous email to the list.

On Thursday, 4 May 2023 13:01:10 EEST Marcus Müller wrote:

> Because you intuitively would start with a single symbol and multiply it
> with the *whole* sequence. What George's code does is different: It takes
> each sample of the audio signal and multiplies it with a corresponding
> random sample.
> 

I understand now. I wouldn't use a random number generator for this. Still, 
pretty interesting. Tough I can foresee objections from narrow-band users of 
QO100 :)

Cheers,
Adrian







Re: QAM constellation script

2023-05-04 Thread Marcus Müller

Hey,

On 04.05.23 11:38, Adrian Musceac wrote:

On Thursday, 4 May 2023 12:11:47 EEST you wrote:

Hi Adrian,

for CDMA, two things need to be different:

1. you need at least one orthogonal other sequence used by another user /
data stream – that MA in CDMA is multiple access :)


I was assuming multiple pairs of users would use orthogonal codes to avoid
interference between themselves.


Problem is you need to come up with a sequence that's (approximately) orthogonal to the 
first 10240 values from random().


For the first such sequence: easy.

To find the third sequence in that code, you would already need to incorporate the two 
existing sequences to find a third orthogonal one.


To find the Nth sequence, you need to incorporate all N-1 previous ones.

A 10240-dimensional space should have 10240 base vectors – so complexity of finding a good 
set of CDMA sequences from the random.random() starting point is 10240!; not a nice number.




2. In classical CDMA, you would need your data to be a constant that you
multiply with your sequences –  if you multiply a signal that changes
during the duration of your sequence, you lose all guarantees that another
signal using another orthogonal sequence is still orthogonal.


I'll have to try and parse this later because I have a hard time understanding
how the data payload could change during chipping.


Because you intuitively would start with a single symbol and multiply it with the *whole* 
sequence. What George's code does is different: It takes each sample of the audio signal 
and multiplies it with a corresponding random sample.




The other one is that in classical FDMA, you take a x kHz wide signal, and
put it on one of a defined set of x kHz wide channels. If something else
disturbs that channel, bad luck. In spread-spectrum systems, you gain
robustness agains narrowband interferers.



Won't shared used of the spectrum by both narrow band transmissions and spread
transmissions manifest in a rise of the noise floor and SNR degradation for
both types of users?


Yes! But in one case, "A 10 kHz wide interferer in a user's channel" means no 
communication for that specific user, but in the spread spectrum case, it just means a 
slightly reduced SNR.



This is a question I asked myself before but in the case of LoRa.


LoRa's interesting because they combine multiple "mechanisms" of spreading, and because 
the despreading is technically especially interesting (and maybe more similar to what I'd 
call "pulse compression" in wideband radar).


Cheers,
Marcus



Re: QAM constellation script

2023-05-04 Thread Marcus Müller

Hi Adrian,

for CDMA, two things need to be different:

1. you need at least one orthogonal other sequence used by another user / data stream – 
that MA in CDMA is multiple access :)
2. In classical CDMA, you would need your data to be a constant that you multiply with 
your sequences –  if you multiply a signal that changes during the duration of your 
sequence, you lose all guarantees that another signal using another orthogonal sequence is 
still orthogonal.


> is there really any
> advantage to using it as opposed to standard FDMA as traditionally used on
> QO100? From an amateur radio operator perspective.

Hm, I think the point was distributing the signal energy across a larger range. That can 
be done for several reasons – inhibiting detection through an adversary being one (and the 
classical origin story of Frequency-Hopping Spread Spectrum), although one that doesn't 
apply to amateur radio.


The other one is that in classical FDMA, you take a x kHz wide signal, and put it on one 
of a defined set of x kHz wide channels. If something else disturbs that channel, bad 
luck. In spread-spectrum systems, you gain robustness agains narrowband interferers.


There's a couple other "side-benefits" you might be getting from a wider bandwidth; from 
the ability to more easily transport a higher-resolution time information (nice if you 
want to do ranging!) to the fact that if I take some fixed transmit power and distribute 
it across a wider band, I still get the same energy per bit that I transmit, but at a 
lower spectral power density – and often, that's what is regulated. (that is of course 
what allows to make signals harder to detect: pushing the PSD of your signal below noise 
floor)


Cheers,
Marcus



Re: QAM constellation script

2023-05-04 Thread Adrian Musceac
On Wednesday, 3 May 2023 19:20:10 EEST Marcus Müller wrote:
> Hi George,
> 
> that's a multiplicative voice scrambler!
> 
> The pre-Second World war voice scrambler system "SIGSALY" [1] was kind
> of similar;
> just that the scrambling sequence came out of a noisy vacuum tube, not
> Python's random.random(), and that the combination method was taking
> samples and adding them modulo 6, instead of multiplying the phase
> (which is inherently modulo 2π).
> 

That was a really nice description, thank you for taking the time to write 
that. The original project is also interesting, even if we call it differently.
So to me this looks like a basic CDMA access scheme, is there really any 
advantage to using it as opposed to standard FDMA as traditionally used on 
QO100? From an amateur radio operator perspective.

Adrian








Re: QAM constellation script

2023-05-03 Thread Marcus Müller

Hi George,

that's a multiplicative voice scrambler!

The pre-Second World war voice scrambler system "SIGSALY" [1] was kind 
of similar;
just that the scrambling sequence came out of a noisy vacuum tube, not 
Python's random.random(), and that the combination method was taking 
samples and adding them modulo 6, instead of multiplying the phase 
(which is inherently modulo 2π).


So, that should work quite nicely for spreading; it's not as great for 
the secretive purposes the (later) Allies developed the original scramblers:


1. We're re-using the same 10240 length sequence as scrambling signal –
   that's very fine for the spreading, but from a cryptographic point
   of view, if the secrecy of a message depended on an eavesdropper not
   knowing the sequence, not great, because it's easy with a bit of
   statistics to recover an approximative spreading sequence.
2. Since the bandwidth of the scrambled signal is much higher than the
   unscrambled message signal, an envelope detector on the whole
   bandwidth can probably (I didn't try) recover a pretty intelligible
   version of the audio signal (in the end, if the power of the audio
   signal is low, due to the multiplications, so is the power of the
   signal you transmit; it's kind of similar to AM, but instead of
   modulating a carrier, we modulate a white noise source). Of course,
   knowing the spreading sequence (i.e., knowing how to seed
   random.seed()) gives a large processing gain and thus much better
   SNR at the receiver's output than plain power detection.

But you're no trying to send secret messages – you're just trying to use 
a wide band of spectrum, and for that, your solution works fine, if your 
synchronization between transmitter and receiver is good enough in time 
and frequency.


There's a bit of a hurdle there: No two oscillators are /exactly/ the 
same, and there's also things like Doppler – so you need to use your 
preamble (fh==False case) to not only know at which time you need to 
start your random multiplication, but also to know by how many Hertz 
your receiver is tuned off the "correct" frequency. If your receiver 
doesn't have the exact same frequency as the transmitter, you see that 
by a frequency shift in the baseband, so a multiplication with an exp(2j 
· π · f_error · t), and that means that the phase of every sample gets 
shifted by an additional f_error/f_sample more, and the receiver might 
no longer work. To combat that, you need frequency recovery (which could 
very nicely be done on a preamble, it's just not inherently trivial to 
do it with a chirp), and because your receiver's oscillator might still 
drift over time, maybe adding a pilot tone every so and so many seconds 
might help.


In practice, what you'd probably do is take your idea and change a few 
things about it. I'll illustrate the design process with sensible 
example values below. Sensible in the sense that all the things are 
available technologies in the open source space, and not too hard to get 
to work on normal hardware:


It seems you're directly modulating analog audio. Instead, since ca the 
1980s, you'd usually use a voice encoder / decoder pair (i.e., a 
vocoder) to transform the voice into bits, then add error correction to 
them, then spread these – that's a lot easier, and you get the chance to 
use the energy you transmit for the bandwidth the "useful" information 
in your voice actually has, and the energy necessary to make it have the 
least error in the presence of noise, instead of having to transport the 
full audio bandwidth! Then, you could design a system to use the simple 
Direct-Sequence Spread Spectrum (DSSS) method.


DSSS is rather easy: you take a transmit symbol, and repeat it by a 
spreading factor F, and then flip the sign of the symbols ("chips") 
according to a fixed pseudorandom bit sequence that receiver and 
transmitter both share. You send the signal with the full sample rate, 
meaning that you increase the bandwidth by F (that's the spreading). At 
the receiver, you flip in the same manner, "unflipping" the original 
flips, so you just get the noisy original repeated symbols. You add up F 
of them, which gives you F times the amplitude of the original signal.
Because you scale the signal amplitude by F, you get F² times the signal 
power. Noise is uncorrelated to itself, so the amplitudes don't add up 
linearly – the noise variance and hence the power does. So, noise power 
increases  with F, signal power with F², so SNR increases with F.


1. your audio bitstream has a bit rate b. You typically find that by
   listening to a few examples of audio encoders until one has the
   quality you need and nice low bitrate.
   /Example:/ b = 2.4 kb/s (model assumption: voice codec at 2.4 kb/s
   (e.g. codec2[6], or LPCnet)
2. your transmission allows for a certain number of bit errors until it
   gets ugly, so you define a maximum acceptable Bit-Error Rate (BER)
   /Example/: e = 10⁻⁵
3. you choose a class of 

Σχετ: Re: Σχετ: Re: Σχετ: Re: QAM constellation script

2023-05-01 Thread George Katsimaglis
Hi Marcus,
Thanks for your detailed answer!!!Can we consider this approach as a new spread 
spectrum technology or is really an existing one?
Best regards
George SV1BDS 
Στάλθηκε από το Ταχυδρομείο Yahoo σε Android 
 
  Στις Δευ, 1 Μαΐ, 2023 στις 23:14, ο χρήστηςMarcus 
Müller έγραψε:   Hi George,
thanks for the reply!

>>    "VCO generator":

>    It produces two different vectors depending of fh Boolean value. A 
>sawtooth vector of
>    values between  -0.5 and 0.5 or the same random values between -0.5 and 
>0.5. The
>    sawtooth values used in alignment phase (adjusting myblock).

Yes, indeed! But I was focussing on the self.fh == True case.
>>    "Repeat":
> 
>    This block offloads the previous block as is too heavy to produce random 
>numbers at
>    the rate needed.

Well, you did not write it very efficiently, but agreed, if you just need to 
repeat the 
vector, by all means, this is a nice way to do it.


>>    "VCO (complex)":
>    The VCO complex, with the values specified, produce frequencies between 
>-500 kHz for
>    -0.5 and +500 kHz for +0.5 input. This block creates the frequency change.

But only for fh == False. For fh == True, you're really just piping in random 
numbers to a 
mapper that maps the random numbers from [-0.5,+0,5] to a point on the unit 
circle with 
phase [-π;+π]. This phase is then what is output *for every sample*, 
separately. Your VCO 
really does only this:

output[i] = output[i-1] · exp(1j · sensitivity/sampling_rate · input[i]),

and in your case, sensitivity/sampling_rate == 2π ,

output[i] = output[i-1] · exp(1j · 2π · input[i])
          = output[i-1] · random phase increment in [-π;+π].

and because your input is just random independent numbers between -0.5 and 
+0.5, you just 
get random independent numbers on the output: (pseudo-)White noise.

Connect a QT GUI Frequency Sink to the output of your VCO (complex), set 
fh==True and 
looks how flat and random the output spectrum is.

(I'm attaching a subgraph of your flow graph with that sink, and also a 
screenshot from 
the QT GUI Frequency Sink)

>>    "Multiply":
>    It moves the USB voice signal by frequency created from previous steps.

Sorry, definitely no USB created anywhere! If that was the case, the QT GUI 
Frequency Sink 
mentioned above would have to show zero for the upper half (before you complex 
conjugate), 
or the lower half of the spectrum, because you shift your 0-frequency-symmetric 
message 
signal spectrum by the frequencies in the spectrum of your VCO's output, and if 
you only 
want them to end up in the USB, then all these "shifting" frequencies would 
have to be in 
the upper half of the spectrum.

>    You can better understand it considering frequencies rather than phases.

I'm about to say the same to you :)
Notice that frequency is the derivative of the phase. In your VCO block, you 
generate 
completely random phase increments. The derivative of that is just again 
complete 
randomness – every single sample.

Anything that you really can say "has a frequency" needs to have the same phase 
increment 
for multiple samples. But you're switching the phase increment with every 
sample - 
completely randomly.

This really nicely spreads the signal power from narrowband input signal into 
the full 
sampling rate bandwidth, but it's really not frequency hopping.

Best regards,
Marcus  


Re: Σχετ: Re: Σχετ: Re: QAM constellation script

2023-05-01 Thread Marcus Müller

Hi George,
thanks for the reply!


"VCO generator":



It produces two different vectors depending of fh Boolean value. A sawtooth 
vector of
values between  -0.5 and 0.5 or the same random values between -0.5 and 
0.5. The
sawtooth values used in alignment phase (adjusting myblock).


Yes, indeed! But I was focussing on the self.fh == True case.

"Repeat":


This block offloads the previous block as is too heavy to produce random 
numbers at
the rate needed.


Well, you did not write it very efficiently, but agreed, if you just need to repeat the 
vector, by all means, this is a nice way to do it.




"VCO (complex)":

The VCO complex, with the values specified, produce frequencies between 
-500 kHz for
-0.5 and +500 kHz for +0.5 input. This block creates the frequency change.


But only for fh == False. For fh == True, you're really just piping in random numbers to a 
mapper that maps the random numbers from [-0.5,+0,5] to a point on the unit circle with 
phase [-π;+π]. This phase is then what is output *for every sample*, separately. Your VCO 
really does only this:


output[i] = output[i-1] · exp(1j · sensitivity/sampling_rate · input[i]),

and in your case, sensitivity/sampling_rate == 2π ,

output[i] = output[i-1] · exp(1j · 2π · input[i])
  = output[i-1] · random phase increment in [-π;+π].

and because your input is just random independent numbers between -0.5 and +0.5, you just 
get random independent numbers on the output: (pseudo-)White noise.


Connect a QT GUI Frequency Sink to the output of your VCO (complex), set fh==True and 
looks how flat and random the output spectrum is.


(I'm attaching a subgraph of your flow graph with that sink, and also a screenshot from 
the QT GUI Frequency Sink)



"Multiply":

It moves the USB voice signal by frequency created from previous steps.


Sorry, definitely no USB created anywhere! If that was the case, the QT GUI Frequency Sink 
mentioned above would have to show zero for the upper half (before you complex conjugate), 
or the lower half of the spectrum, because you shift your 0-frequency-symmetric message 
signal spectrum by the frequencies in the spectrum of your VCO's output, and if you only 
want them to end up in the USB, then all these "shifting" frequencies would have to be in 
the upper half of the spectrum.



You can better understand it considering frequencies rather than phases.


I'm about to say the same to you :)
Notice that frequency is the derivative of the phase. In your VCO block, you generate 
completely random phase increments. The derivative of that is just again complete 
randomness – every single sample.


Anything that you really can say "has a frequency" needs to have the same phase increment 
for multiple samples. But you're switching the phase increment with every sample - 
completely randomly.


This really nicely spreads the signal power from narrowband input signal into the full 
sampling rate bandwidth, but it's really not frequency hopping.


Best regards,
Marcus

demo.pdf
Description: Adobe PDF document


demo.grc
Description: application/gnuradio-grc


Σχετ: Re: Σχετ: Re: QAM constellation script

2023-04-29 Thread George Katsimaglis
Hi Marcus ,

Στάλθηκε από το Ταχυδρομείο Yahoo σε Android 
 
  Στις Σάβ, 29 Απρ, 2023 στις 14:23, ο χρήστηςMarcus 
Müller έγραψε:   Hi George,

that flow graph doesn't frequency-hop :) It does something different, 
rather cool. Please correct me if I got anything wrong about your 
self-written blocks below:

What you do is:

"VCO generator":

Produces always the same 10240-long vector with pseudo-random values,


It produces two different vectors depending of fh Boolean value. A sawtooth 
vector of values between  -0.5 and 0.5 or the same random values between -0.5 
and 0.5. The sawtooth values used in alignment phase (adjusting myblock).
"Repeat":

Repeat that vector you get 100 times (but that makes no difference, you 
could have just taken 100 vectors from "VCO generator", they are all the 
same)
This does **not** repeat the elements within the vector 100 times


This block offloads the previous block as is too heavy to produce random 
numbers at the rate needed.
"My block"Shift the vector in order to match the receiving keys.

"VCO (complex)":

Takes every input values and uses it (scaled with a factor) as phase 
increment relative to the last value it has generated.
With the uncorrelated random [0,1] source at the input, and the scaling 
being such that the phase increment range is always [0;2pi], this just 
generates a pseudo-random point on the unit circle each output item

The VCO complex, with the values specified, produce frequencies between -500 
kHz for -0.5 and +500 kHz for +0.5 input. This block creates the frequency 
change. All values between -0.5 and +0.5 produce frequencies between them.VCO 
is voltage controlled oscillator. It produces frequencies depending of 
"voltage" input.

"Complex Conj":

Well, takes the complex conjugate of each item individually – still just 
points of uncorrelated random phase!

Inverse the frequencies created.

"Multiply":

You're multiplying the samples from your reception with a different 
sample each from a repeating, white pseudorandom noise:
This is spectral whitening :) But not frequency hopping.

It moves the USB voice signal by frequency created from previous steps.

You can better understand it considering frequencies rather than phases.
Best regards,
Marcus
Best regards,George SV1BDS 
On 4/28/23 14:03, George Katsimaglis wrote:
> Hi,
>
> Thanks for the answers.
> I attach the Rx flowchart and grc of the frequency hopping. I have 
> successfully used it on QO100 satellite.
>
> George SV1BDS
>
>
> Στάλθηκε από το Ταχυδρομείο Yahoo σε Android 
> 
>
>    Στις Πέμ, 27 Απρ, 2023 στις 14:57, ο χρήστηςMarcus Müller
>     έγραψε:
>    Hi George,
>
>    > Also I have implemented 1.000.000 hops/sec frequency hopping at
>    QO100 satellite, spread
>    > over 1 MHz, using 10240 different frequencies.
>    > Is this project of general interest?
>
>    Well, that's impossible to say, but honestly: it probably is! And
>    also, you shouldn't care
>    too much :) It's cool in any case!
>    My advise is: Just put it out there.
>
>    But I do have signal theory questions:
>
>    We know that if a signal has a bandwidth of 1 MHz, we can
>    (complex) sample it and contain
>    all its signal content with a sampling rate of 1 MS/s.
>
>    If you're doing a million hops per second, how are you achieving a
>    bandwidth of only 1
>    MHz? That means that every hop only gets a single sample, and you
>    can't signify
>    "frequency" with just a single number.
>
>    So, I might have misunderstood you there, but it would seem what
>    you claim to have done is
>    mathematically not possible :(
>
>    > I create this script using Python to create QAM constellations
>    points.
>    > May be of general interest.
>
>    It's nice, but GNU Radio already comes with that!
>
>    from gnuradio import digital
>    constellation = digital.constellation_16qam()
>    points = constellation.points()
>
>    (and you can just use digital.constellation_16qam().points() in a
>    GRC block parameter, no
>    need to build a string!)
>
>    These are also power-normalized to 1.
>
>    If you don't want normalized (or different sizes of) QAM
>    constellation,
>
>    digital.qam.make_non_differential_constellation(M, gray_coded)
>
>    is your friend;
>
>    digital.qam.make_non_differential_constellation(4096, True)
>
>    makes a nice 4096-QAM, but it's average power isn't 1; you can fix
>    that
>
>    points = digital.qam.make_non_differential_constellation(4096, True)
>    average_pwr = sum(point**2 for point in points) / len(points)
>    print(f"Average power: {average_pwr}; normalization factor hence:
>    {average_pwr**(-1/2)}")
>    normalized_points = [ point * average_pwr**(-1/2) for point in
>    points ]
>
>    Similarly, since you're doing satellite communications, you might
>    be interes

Re: Σχετ: Re: QAM constellation script

2023-04-29 Thread Marcus Müller

Hi George,

that flow graph doesn't frequency-hop :) It does something different, 
rather cool. Please correct me if I got anything wrong about your 
self-written blocks below:


What you do is:

"VCO generator":

Produces always the same 10240-long vector with pseudo-random values,


"Repeat":

Repeat that vector you get 100 times (but that makes no difference, you 
could have just taken 100 vectors from "VCO generator", they are all the 
same)

This does **not** repeat the elements within the vector 100 times


"VCO (complex)":

Takes every input values and uses it (scaled with a factor) as phase 
increment relative to the last value it has generated.
With the uncorrelated random [0,1] source at the input, and the scaling 
being such that the phase increment range is always [0;2pi], this just 
generates a pseudo-random point on the unit circle each output item



"Complex Conj":

Well, takes the complex conjugate of each item individually – still just 
points of uncorrelated random phase!



"Multiply":

You're multiplying the samples from your reception with a different 
sample each from a repeating, white pseudorandom noise:

This is spectral whitening :) But not frequency hopping.


Best regards,
Marcus

On 4/28/23 14:03, George Katsimaglis wrote:

Hi,

Thanks for the answers.
I attach the Rx flowchart and grc of the frequency hopping. I have 
successfully used it on QO100 satellite.


George SV1BDS


Στάλθηκε από το Ταχυδρομείο Yahoo σε Android 



Στις Πέμ, 27 Απρ, 2023 στις 14:57, ο χρήστηςMarcus Müller
 έγραψε:
Hi George,

> Also I have implemented 1.000.000 hops/sec frequency hopping at
QO100 satellite, spread
> over 1 MHz, using 10240 different frequencies.
> Is this project of general interest?

Well, that's impossible to say, but honestly: it probably is! And
also, you shouldn't care
too much :) It's cool in any case!
My advise is: Just put it out there.

But I do have signal theory questions:

We know that if a signal has a bandwidth of 1 MHz, we can
(complex) sample it and contain
all its signal content with a sampling rate of 1 MS/s.

If you're doing a million hops per second, how are you achieving a
bandwidth of only 1
MHz? That means that every hop only gets a single sample, and you
can't signify
"frequency" with just a single number.

So, I might have misunderstood you there, but it would seem what
you claim to have done is
mathematically not possible :(

> I create this script using Python to create QAM constellations
points.
> May be of general interest.

It's nice, but GNU Radio already comes with that!

from gnuradio import digital
constellation = digital.constellation_16qam()
points = constellation.points()

(and you can just use digital.constellation_16qam().points() in a
GRC block parameter, no
need to build a string!)

These are also power-normalized to 1.

If you don't want normalized (or different sizes of) QAM
constellation,

digital.qam.make_non_differential_constellation(M, gray_coded)

is your friend;

digital.qam.make_non_differential_constellation(4096, True)

makes a nice 4096-QAM, but it's average power isn't 1; you can fix
that

points = digital.qam.make_non_differential_constellation(4096, True)
average_pwr = sum(point**2 for point in points) / len(points)
print(f"Average power: {average_pwr}; normalization factor hence:
{average_pwr**(-1/2)}")
normalized_points = [ point * average_pwr**(-1/2) for point in
points ]

Similarly, since you're doing satellite communications, you might
be interested in PSKs,
an A-PSKs.

You can create a PSK using

digital.psk.psk_constellation(m=4, mod_code='gray', differential=True)

e.g.

digital.psk.psk_constellation(16, differential=False)


If you don't have GNU Radio but just python,

str([(i, j) for i in range(-n, n, 2) for j in range (-n, n, 2)])

does the same as your code, but might be a bit easier to read
(again, if you want to use
this in GRC, don't do the conversion to `str`; GRC accepts any
valid Python in its fields).

Best regards,
Marcus






Σχετ: Re: QAM constellation script

2023-04-28 Thread George Katsimaglis
Hi,
Thanks for the answers.I attach the Rx flowchart and grc of the frequency 
hopping. I have successfully used it on QO100 satellite.
George SV1BDS 

Στάλθηκε από το Ταχυδρομείο Yahoo σε Android 
 
  Στις Πέμ, 27 Απρ, 2023 στις 14:57, ο χρήστηςMarcus 
Müller έγραψε:   Hi George,

 > Also I have implemented 1.000.000 hops/sec frequency hopping at QO100 
 > satellite, spread
 > over 1 MHz, using 10240 different frequencies.
 > Is this project of general interest?

Well, that's impossible to say, but honestly: it probably is! And also, you 
shouldn't care 
too much :) It's cool in any case!
My advise is: Just put it out there.

But I do have signal theory questions:

We know that if a signal has a bandwidth of 1 MHz, we can (complex) sample it 
and contain 
all its signal content with a sampling rate of 1 MS/s.

If you're doing a million hops per second, how are you achieving a bandwidth of 
only 1 
MHz? That means that every hop only gets a single sample, and you can't signify 
"frequency" with just a single number.

So, I might have misunderstood you there, but it would seem what you claim to 
have done is 
mathematically not possible :(

> I create this script using Python to create QAM constellations points.
> May be of general interest.

It's nice, but GNU Radio already comes with that!

from gnuradio import digital
constellation = digital.constellation_16qam()
points = constellation.points()

(and you can just use digital.constellation_16qam().points() in a GRC block 
parameter, no 
need to build a string!)

These are also power-normalized to 1.

If you don't want normalized (or different sizes of) QAM constellation,

digital.qam.make_non_differential_constellation(M, gray_coded)

is your friend;

digital.qam.make_non_differential_constellation(4096, True)

makes a nice 4096-QAM, but it's average power isn't 1; you can fix that

points = digital.qam.make_non_differential_constellation(4096, True)
average_pwr = sum(point**2 for point in points) / len(points)
print(f"Average power: {average_pwr}; normalization factor hence: 
{average_pwr**(-1/2)}")
normalized_points = [ point * average_pwr**(-1/2) for point in points ]

Similarly, since you're doing satellite communications, you might be interested 
in PSKs, 
an A-PSKs.

You can create a PSK using

digital.psk.psk_constellation(m=4, mod_code='gray', differential=True)

e.g.

digital.psk.psk_constellation(16, differential=False)


If you don't have GNU Radio but just python,

str([(i, j) for i in range(-n, n, 2) for j in range (-n, n, 2)])

does the same as your code, but might be a bit easier to read (again, if you 
want to use 
this in GRC, don't do the conversion to `str`; GRC accepts any valid Python in 
its fields).

Best regards,
Marcus


  


FH_USBTESTRx.pdf
Description: Adobe PDF document


FH_USBTESTRx.grc
Description: Binary data


Re: QAM constellation script

2023-04-27 Thread Marcus Müller

Hi George,

> Also I have implemented 1.000.000 hops/sec frequency hopping at QO100 
satellite, spread
> over 1 MHz, using 10240 different frequencies.
> Is this project of general interest?

Well, that's impossible to say, but honestly: it probably is! And also, you shouldn't care 
too much :) It's cool in any case!

My advise is: Just put it out there.

But I do have signal theory questions:

We know that if a signal has a bandwidth of 1 MHz, we can (complex) sample it and contain 
all its signal content with a sampling rate of 1 MS/s.


If you're doing a million hops per second, how are you achieving a bandwidth of only 1 
MHz? That means that every hop only gets a single sample, and you can't signify 
"frequency" with just a single number.


So, I might have misunderstood you there, but it would seem what you claim to have done is 
mathematically not possible :(



I create this script using Python to create QAM constellations points.
May be of general interest.


It's nice, but GNU Radio already comes with that!

from gnuradio import digital
constellation = digital.constellation_16qam()
points = constellation.points()

(and you can just use digital.constellation_16qam().points() in a GRC block parameter, no 
need to build a string!)


These are also power-normalized to 1.

If you don't want normalized (or different sizes of) QAM constellation,

digital.qam.make_non_differential_constellation(M, gray_coded)

is your friend;

digital.qam.make_non_differential_constellation(4096, True)

makes a nice 4096-QAM, but it's average power isn't 1; you can fix that

points = digital.qam.make_non_differential_constellation(4096, True)
average_pwr = sum(point**2 for point in points) / len(points)
print(f"Average power: {average_pwr}; normalization factor hence: 
{average_pwr**(-1/2)}")
normalized_points = [ point * average_pwr**(-1/2) for point in points ]

Similarly, since you're doing satellite communications, you might be interested in PSKs, 
an A-PSKs.


You can create a PSK using

digital.psk.psk_constellation(m=4, mod_code='gray', differential=True)

e.g.

digital.psk.psk_constellation(16, differential=False)


If you don't have GNU Radio but just python,

str([(i, j) for i in range(-n, n, 2) for j in range (-n, n, 2)])

does the same as your code, but might be a bit easier to read (again, if you want to use 
this in GRC, don't do the conversion to `str`; GRC accepts any valid Python in its fields).


Best regards,
Marcus




QAM constellation script

2023-04-23 Thread George Katsimaglis
Hello,
I create this script using Python to create QAM constellations points.May be of 
general interest.
# constellation creation script by George SV1BDSn = 7 # 3 for 16QAM, 7 for 
64QAM, 15 for 256QAM, 31 for 1024QAM, 63 for 4096QAMc = '['for i in 
range(-n,n+2,2):  for j in range(-n,n+2,2):    c += 
'('+format(i,'d')+format(j,'+d')+'j),'c = c[:-1]+']'print(c)
Also I have implemented 1.000.000 hops/sec frequency hopping at QO100 
satellite, spread over 1 MHz, using 10240 different frequencies.Is this project 
of general interest?
Best regardsGeorge SV1BDS 

Re: Constellation script

2020-01-21 Thread CEL
Hi Michel,

welcome to the mailing list.

I must admit that I don't really know what you want to do.

Can you explain it, so that doesn't know what a DMR-C4FM relay is,
understands?

I think you're referring to some GRC flow graphs, but sadly we don't
know which ones you have been looking at. So, specific links would be
very appreciated.

Best regards,
Marcus

On Mon, 2020-01-20 at 17:41 +0100, michel slepoukha wrote:
> Hello all!
> I designed in 2018 the DMR-C4FM relay from Albi (Tarn), F5ZLH
> it works…
> Well, not that good, because we noticed  a poor signal quality:
> 
> 
> with the constellation, on a portable equipment such as the Rpi 4. we will 
> beable to adjust the relay settings
> And there only GNURadio is installed correctly and worked perfectly with an 
> RTL-SDR key.
> But most of the flow chart examples use logical signal sources and if some of 
> them have an RTL-SDR key as input, they are either incomplete or with errors 
> (wonder if this is not done expressly?) . And above all, no script linked to 
> the flow chart concerned.
> So, I can only turn to the competence of your team to finally have this 
> script validated.
> Configuration is simple: SDR-RTL → constellation
> With thanks for help
> Mike
> 


smime.p7s
Description: S/MIME cryptographic signature


Constellation script

2020-01-20 Thread michel slepoukha

Hello all!
I designed in 2018 the DMR-C4FM relay from Albi (Tarn), F5ZLH
it works…
Well, not that good, because we noticed  a poor signal quality:


with the constellation, on a portable equipment such as the Rpi 4. we 
will beable to adjust the relay settings
And there only GNURadio is installed correctly and worked perfectly with 
an RTL-SDR key.
But most of the flow chart examples use logical signal sources and if 
some of them have an RTL-SDR key as input, they are either incomplete or 
with errors (wonder if this is not done expressly?) . And above all, no 
script linked to the flow chart concerned.
So, I can only turn to the competence of your team to finally have this 
script validated.

Configuration is simple: SDR-RTL → constellation
With thanks for help
Mike

--
  Michel SLEPOUKHA F5ZZ
   (FR5FI - TU2DD - 6W8IY)
 F5ZZ-10  JN13AV