Example #1
0
/// Fading/AWGN Channel that operates on each sample
func (m *ChannelEmulator) FadingChannel(InCH gocomm.Complex128Channel) {
	outCH := m.Pins["symbolOut"].Channel.(gocomm.Complex128Channel)
	NextSize := 1
	N0 := .01 /// 10dB SNR
	var chdataOut gocomm.SComplex128Obj
	var chdataIn gocomm.SComplex128Obj
	for i := 0; i < NextSize; i++ {

		chdataIn = <-InCH
		sample := chdataIn.Ch
		chdataOut.Message = chdataIn.Message
		chdataOut.MaxExpected = chdataIn.MaxExpected
		NextSize = chdataIn.MaxExpected

		var hn complex128
		if chdataIn.Message == "BYPASS" {
			hn = 1
			chdataOut.Ch = sample
		} else {
			hn = sources.RandNC(N0)
			psample := sample * hn
			chdataOut.Ch = psample
		}

		outCH <- chdataOut
	}

}
Example #2
0
func (m *MPChannel) updateCoeff(timestamp float64) {
	/// first time
	generated := false
	if m.TimeStamp == -1 {
		m.Coeff.Resize(m.pdp.Size())
		for i := 0; i < m.pdp.Size(); i++ {
			m.Coeff[i] = sources.RandNC(m.pdp[i])
		}
		generated = true
		m.TimeStamp = 0 /// Unusuall if inbetween the MPchannel timestamp has got RESET !!

	} else {

		/// Existing channel-coeff is valid till m.Timestamp+m.TS,
		valid := timestamp < (m.TimeStamp + m.Ts)

		if !valid {
			/// TRIGGER NEW COEFF
			m.Coeff = vlib.NewVectorC(m.pdp.Size())
			for i := 0; i < m.pdp.Size(); i++ {
				m.Coeff[i] = sources.RandNC(m.pdp[i])
			}

			m.TimeStamp = timestamp
			generated = true
		}

	}

	/// Write new coeff to feedback channel if new was generated
	if m.FeedbackCH != nil && generated {
		var chdata gocomm.SComplex128AObj
		chdata.Ch = m.Coeff
		chdata.TimeStamp = m.TimeStamp
		chdata.Ts = m.Ts
		// fmt.Printf("\n CH:GENERATED @ %v with Coeff : %v, Gain : %v ", timestamp, m.Coeff[0], cmplx.Abs(m.Coeff[0])*cmplx.Abs(m.Coeff[0]))
		m.FeedbackCH <- chdata
	}

}
Example #3
0
func (m *MPChannel) ChannelFn(sample gocomm.SComplex128Obj) (result gocomm.SComplex128Obj) {
	/// Read your data from Input channel(s) [inputPin0]
	/// And write it to OutputChannels  [outputPin0]
	// fmt.Printf("\n Channel Param %#v  \n input = %v", m.ChannelParam, sample)

	if m.Ts == -1 {

		m.Coeff.Resize(m.pdp.Size())
		for i := 0; i < m.pdp.Size(); i++ {
			m.Coeff[i] = sources.RandNC(m.pdp[i])
		}
		if m.FeedbackCH != nil {
			var chdata gocomm.SComplex128AObj
			chdata.Ch = m.Coeff
			chdata.TimeStamp = m.TimeStamp
			chdata.MaxExpected = sample.MaxExpected
			chdata.Ts = m.Ts
			fmt.Printf("\n FAST IID generated for sample@%v with %v@%v", sample.TimeStamp, m.TimeStamp, cmplx.Abs(m.Coeff[0])*cmplx.Abs(m.Coeff[0]))
			m.FeedbackCH <- chdata
		}

	} else {

		m.updateCoeff(sample.TimeStamp)

	}
	if m.FilterMemory.Size() != m.Coeff.Size() {
		m.FilterMemory.Resize(m.Coeff.Size())
	}

	result = sample /// Carefull if not same ChType
	// m.TimeStamp = sample.TimeStamp
	m.FilterMemory = m.FilterMemory.ShiftLeft(sample.Ch)

	//dummy := vlib.ElemMultC(m.Coeff, vlib.Conj(m.Coeff))
	foutput := vlib.DotC(m.Coeff, m.FilterMemory)
	// fmt.Printf("\n CHANNEL @%v: I/P %v - Gain : %v  : O/p : %v", sample.TimeStamp, sample.Ch, cmplx.Abs(m.Coeff[0])*cmplx.Abs(m.Coeff[0]), foutput)
	result.Ch = foutput
	result.Message = sample.Message + " Filter"
	result.Ts = sample.Ts
	result.TimeStamp = sample.TimeStamp
	result.MaxExpected = sample.MaxExpected
	// fmt.Printf("\n I/O (hn =%v) : %#v --> %#v", m.Coeff, sample, result)
	return result

}
Example #4
0
func main() {

	rand.Seed(time.Now().Unix())
	// rand.Seed(1)

	start := time.Now()
	var N = 10
	var N0 float64 = 1.0 / 10
	txbits := vlib.VectorB(sources.RandB(N))

	qpskModem := new(core.Modem)
	var BitsPerSymbol = 2
	qpskModem.Init(BitsPerSymbol, "")
	fmt.Printf("\n%v", qpskModem)

	/// Take every N-bit and push to modem-channel-demod

	length := len(txbits)
	// slength := length / BitsPerSymbol

	//var result = make([]complex128, slength)
	/// Actual Modulation happens here

	cnt := 0
	// rxcnt := 0
	// symCH := make([]chan complex128, length)
	COUNT := length / 2
	rxCH := make([]chan []uint8, COUNT)

	for i := 0; i < COUNT; i++ {
		rxCH[i] = make(chan []uint8)
	}

	for i := 0; i < length; i += BitsPerSymbol {

		symCH := make(chan complex128)

		go qpskModem.GenerateSymbolCH(cnt, txbits[i:i+BitsPerSymbol], symCH)
		go func(twowayChannel chan complex128, cnt int) {

			symbol := <-twowayChannel
			noise := sources.RandNC(N0)
			fmt.Printf("\n Added Noise %d %v", cnt, noise)
			rxsymbol := symbol + noise
			twowayChannel <- rxsymbol
		}(symCH, cnt)
		go qpskModem.DemodSymbolCH(cnt, symCH, rxCH[cnt])

		cnt++
	}

	ORDER := true
	//// UNORDERED receiver bits...
	for i := 0; i < COUNT; i++ {

		if ORDER {
			func(cnt int, tmpRxCh chan []uint8) {
				for rxbits := range tmpRxCh {
					fmt.Printf("\n Unordered Loop Detected bits %d %v", cnt, rxbits)
				}

			}(i, rxCH[i])
		} else {
			go func(cnt int, tmpRxCh chan []uint8) {
				for rxbits := range tmpRxCh {
					fmt.Printf("\n Unordered Loop Detected bits %d %v", cnt, rxbits)
				}

			}(i, rxCH[i])
			fmt.Printf("Waiting for routines to finish")
			time.Sleep(2 * time.Second)

		}
	}

	/// Ordered read from the Receiver channels
	// cnt = 0
	// for _, channel := range rxCH {

	// 	for rxbits := range channel {
	// 		fmt.Printf("\n Outer Loop Detected bits %d %v", cnt, rxbits)
	// 	}
	// 	cnt++
	// }

	// txsymbols := qpskModem.ModulateBits(txbits)
	// rxsymbols := vlib.ElemAddCmplx(txsymbols, sources.Noise(len(txsymbols), N0))
	// rxbits := qpskModem.DeModulateBits(rxsymbols)

	// // fmt.Printf("\nTx=%v", txbits)
	// // fmt.Printf("\nRx=%v", rxbits)
	// fmt.Printf("\nERR=%v/%d = %f", txbits.CountErrors(rxbits), len(txbits), float64(txbits.CountErrors(rxbits))/float64(len(txbits)))
	fmt.Printf("\n\n Elapsed %v \n", time.Since(start).String())
}