Modems
The SDRVM comes with a series of modems sharing the common features.
These are :
Symbol rate
The symbol rate depends on two different factors :
- The sample rate (noted R in the following),
- The number of samples per symbol (noted k in the following).
Each symbol uses k samples transmitted at R samples per second. Hence the bit rate is : R/k.
When the modulateBits() method is called, it returns a IQData object where the sample rate is set to 0. You have to specify the sample rate to be used, depending on the symbol rate you want.
- Example :
We want to generate a 2400 symbols/sec (bits/second in this case) GMSK signal.
- We will use a sample rate of 48000 Hz,
- We need to set the 'samples per symbol' value to 48000/2400=20
var samples_per_symbol = 20 ;
var sample_rate = 48e3 ;
var filter_delay = 3 ;
var bt = .35 ;
var txmodem = new GMSKModem('tx') ;
txmodem.configure({
'sps' : samples_per_symbol,
'delay' : filter_delay,
'bt' : bt
});
var bitrate = sample_rate / samples_per_symbol ;
print('GMSK params :');
print(' Sample rate:' + sample_rate + ' Hz');
print(' Speed : ' + bitrate + ' Bits per second.') ;
Delay
Processing delay :
Modems embeds FIR filters. The output of the FIR filters is delayed by N-1, where N is the number of taps in the filter. When started, the FIR outputs N-2 zeros before the first valid sample is available.
When used as demodulators, converting the input IQ samples to symbols, this delay must be taken into account.
Consequence:
The following example shows what happens if we push the output of the modulator into a demodulator :
function printBits( x ) {
var l=0 ;
var m = '' ;
while( l < x.length ) {
for( var b=0 ; (b<8) && (l<x.length) ; b++,l++) {
if( x[l]>0 ) {
m = m + '1' ;
} else {
m = m + '0' ;
}
}
m = m + ' ' ;
}
print(m);
}
// Generate 16 bytes message
var L = 21*8 ;
var tx_bits = new Uint8Array(L) ;
for( var i=0 ; i < L ; i+=2 ) {
tx_bits[i] = 1 ;
tx_bits[i+1] = 0 ;
}
var samples_per_symbol = 50 ;
var sample_rate = 48e3 ;
var filter_delay = 3 ;
var bt = .35 ;
var txmodem = new GMSKModem('tx') ;
var rx_modem = new GMSKModem('rx');
txmodem.configure({
'sps' : samples_per_symbol,
'delay' : filter_delay,
'bt' : bt
});
rx_modem.configure({
'sps' : samples_per_symbol,
'delay' : filter_delay,
'bt' : bt
});
// modulate, demodulate to compare
var IQ = txmodem.modulateBits( tx_bits ) ;
IQ.setSampleRate(sample_rate);
var rx_bits = rx_modem.demodulate(IQ);
// print the output bits
printBits(tx_bits);
printBits(rx_bits);
This code will produce the following output :
(boot:0)> 10101010 10101010 10101010 10101010 ...
(boot:0)> 00010110 10101010 10101010 10101010 ...
One will note that the first ouput bits are different. This is the consequence of the FIR delay : A series of 0 is generated before the demodulator correctly decodes the input stream.
Last update: January 8, 2022