Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Further amazing simplifications!!!! (and comments)

  • Loading branch information...
commit d4a801fa6be314aff9353b9732c9064b5d02ba65 1 parent 83612fa
@keithw authored
Showing with 19 additions and 23 deletions.
  1. +16 −17 library/au_receive.py
  2. +3 −6 library/au_sendreceive.py
View
33 library/au_receive.py
@@ -52,36 +52,35 @@ def receive( self, num_samples, stream, samples_per_chunk ):
return self.demodulate( raw_receive( num_samples, stream, samples_per_chunk ) )
def __init__( self, center_frequency, bandwidth ):
- self.reference_carrier = 1
-
self.tuner = Filter( center_frequency - bandwidth, center_frequency + bandwidth )
self.lowpass = Filter( 0, bandwidth )
- def demodulate( self, samples, carrier=0, offset=0 ):
+ def demodulate( self, samples ):
# Tune in band around carrier frequency
samples = self.tuner( samples )
# Shift the modulated waveform back down to baseband
- SAMPLES = numpy.arange( offset, offset + len( samples ) )
- ARGS = SAMPLES * (CARRIER_CYCLES_PER_SECOND * 2.0 * math.pi / SAMPLES_PER_SECOND)
- LOCAL_CARRIER = numpy.cos(ARGS) + complex(0,1) * numpy.sin(ARGS)
- demodulated_samples = samples * LOCAL_CARRIER
+ # By multiplying by a complex exponential
+
+ # First, we make the complex exponential (the local carrier)
+ args = numpy.arange(0,len(samples)) * CARRIER_CYCLES_PER_SECOND * 2 * math.pi / SAMPLES_PER_SECOND
+ local_carrier = numpy.cos(args) + complex(0,1) * numpy.sin(args)
- # calculate average amplitude (DC amplitude)
- # we will use this for auto gain control if user has not supplied carrier phase
- if carrier==0:
- carrier = sum( demodulated_samples ) / len( samples )
+ # Now, we shift down to baseband (and also up to 2x LOCAL_CARRIER)
+ demodulated_samples = samples * local_carrier
- self.reference_carrier = carrier
+ # We assume the transmitted data had equal zeros and ones, and therefore
+ # that the average value is the (complex) amplitude of the carrier
+ estimated_carrier = sum( demodulated_samples ) / len( samples )
- # Shift samples in time back to original phase and amplitude (using carrier)
- constant = (DC/AMPLITUDE)/carrier
- constant2 = DC/AMPLITUDE
- shifted_samples = demodulated_samples * constant - constant2
+ # Rotate and shift samples in time back to original phase and amplitude,
+ # including subtracting off the DC offset
+ shifted_samples = (demodulated_samples/estimated_carrier - 1) * DC/AMPLITUDE
+ # Throw out the imaginary part
shifted_samples = [x.real for x in shifted_samples]
- # Low-pass filter
+ # Low-pass filter to remove 2x carrier component
filtered_samples = self.lowpass( shifted_samples )
return filtered_samples
View
9 library/au_sendreceive.py
@@ -68,9 +68,7 @@ def extract_payload( self, signal, payload_len ):
# demodulate payload using carrier reference from preamble
slice_start = payload_start - 3*SECOND_CARRIER_LEN/4
slice_end = payload_start + payload_len
- extracted_payload = self.receiver.demodulate( signal[ slice_start : slice_end ],
- carrier=self.receiver.reference_carrier,
- offset=slice_start )[ payload_start - slice_start: ]
+ extracted_payload = self.receiver.demodulate( signal[ slice_start : slice_end ] )[ payload_start - slice_start: ]
if len( extracted_payload ) != payload_len:
raise Exception( "WARNING: Only received %d of %d samples sent" % ( len(extracted_payload),
@@ -171,9 +169,8 @@ def detect_preamble( self, received_signal ):
# second, better demodulation
slice_start = preamble_start - 3*SECOND_CARRIER_LEN/4
slice_end = preamble_end + 3*SECOND_CARRIER_LEN/4
- preamble_decoded = self.receiver.demodulate( received_signal[ slice_start : slice_end ],
- offset=slice_start )[ preamble_start - slice_start:
- preamble_end - slice_start ]
+ preamble_decoded = self.receiver.demodulate( received_signal[ slice_start : slice_end ] )[ preamble_start - slice_start:
+ preamble_end - slice_start ]
# find REAL phase of preamble
expected_preamble = []
Please sign in to comment.
Something went wrong with that request. Please try again.