예제 #1
0
파일: tune.go 프로젝트: ziutek/dvb
func Tune(fpath, sys, pol string, freqHz int64, bwHz int, srBd uint) (fe frontend.Device, err error) {
	var polar rune
	switch pol {
	case "h", "v":
		polar = rune((pol)[0])
	default:
		err = errors.New("unknown polarization: " + pol)
		return
	}
	fe, err = frontend.Open(fpath)
	if err != nil {
		return
	}
	switch sys {
	case "t":
		if err = fe.SetDeliverySystem(dvb.SysDVBT); err != nil {
			return
		}
		if err = fe.SetModulation(dvb.QAMAuto); err != nil {
			return
		}
		if err = fe.SetFrequency(uint32(freqHz)); err != nil {
			return
		}
		if err = fe.SetInversion(dvb.InversionAuto); err != nil {
			return
		}
		if bwHz != 0 {
			if err = fe.SetBandwidth(uint32(bwHz)); err != nil {
				return
			}
		}
		if err = fe.SetCodeRateHP(dvb.FECAuto); err != nil {
			return
		}
		if err = fe.SetCodeRateLP(dvb.FECAuto); err != nil {
			return
		}
		if err = fe.SetTxMode(dvb.TxModeAuto); err != nil {
			return
		}
		if err = fe.SetGuard(dvb.GuardAuto); err != nil {
			return
		}
		if err = fe.SetHierarchy(dvb.HierarchyNone); err != nil {
			return
		}
	case "s", "s2":
		if sys == "s" {
			if err = fe.SetDeliverySystem(dvb.SysDVBS); err != nil {
				return
			}
			if err = fe.SetModulation(dvb.QPSK); err != nil {
				return
			}
		} else {
			if err = fe.SetDeliverySystem(dvb.SysDVBS2); err != nil {
				return
			}
			if err = fe.SetModulation(dvb.PSK8); err != nil {
				return
			}
			if err = fe.SetRolloff(dvb.RolloffAuto); err != nil {
				return
			}
			if err = fe.SetPilot(dvb.PilotAuto); err != nil {
				return
			}
		}
		if err = fe.SetSymbolRate(uint32(srBd)); err != nil {
			return
		}
		if err = fe.SetInnerFEC(dvb.FECAuto); err != nil {
			return
		}
		if err = fe.SetInversion(dvb.InversionAuto); err != nil {
			return
		}
		ifreq, tone, volt := frontend.SecParam(freqHz, polar)
		if err = fe.SetFrequency(ifreq); err != nil {
			return
		}
		if err = fe.SetTone(tone); err != nil {
			return
		}
		if err = fe.SetVoltage(volt); err != nil {
			return
		}
	case "ca", "cb", "cc":
		switch sys {
		case "ca":
			err = fe.SetDeliverySystem(dvb.SysDVBCAnnexA)
		case "cb":
			err = fe.SetDeliverySystem(dvb.SysDVBCAnnexB)
		case "cc":
			err = fe.SetDeliverySystem(dvb.SysDVBCAnnexC)
		}
		if err != nil {
			return
		}
		if err = fe.SetModulation(dvb.QAMAuto); err != nil {
			return
		}
		if err = fe.SetFrequency(uint32(freqHz)); err != nil {
			return
		}
		if err = fe.SetInversion(dvb.InversionAuto); err != nil {
			return
		}
		if err = fe.SetSymbolRate(uint32(srBd)); err != nil {
			return
		}
		if err = fe.SetInnerFEC(dvb.FECAuto); err != nil {
			return
		}
	default:
		err = errors.New("unknown delivery system: " + sys)
		return
	}
	err = fe.Tune()
	return
}
예제 #2
0
파일: main.go 프로젝트: ziutek/dvb
func main() {
	adapterPath := flag.String(
		"a", "/dev/dvb/adapter0",
		"path to the adapter directory",
	)
	frontendPath := flag.String(
		"f", "frontend0",
		"frontend path, relative to the adapter directory",
	)
	demuxPath := flag.String(
		"d", "demux0",
		"demux path, relative to the adapter directory",
	)
	flag.Usage = usage
	flag.Parse()

	args := flag.Args()

	if len(args) < 4 {
		usage()
		os.Exit(1)
	}

	freq, err := strconv.ParseInt(args[0], 0, 64)
	checkErr(err)
	freq *= 1e6

	var polar byte
	switch args[1] {
	case "v", "V":
		polar = 'v'
	case "h", "H":
		polar = 'h'
	default:
		die("wrong polarisation: " + args[1])
	}

	sr, err := strconv.ParseUint(args[2], 0, 32)
	checkErr(err)

	args = args[3:]
	pids := make([]int16, len(args))
	for i, a := range args {
		pid, err := strconv.ParseInt(a, 0, 64)
		checkErr(err)
		if uint64(pid) > 8192 {
			die(a + " isn't in valid PID range [0, 8192]")
		}
		pids[i] = int16(pid)
	}

	fe, err := frontend.Open(filepath.Join(*adapterPath, *frontendPath))
	checkErr(err)

	checkErr(fe.SetDeliverySystem(dvb.SysDVBS2))
	checkErr(fe.SetModulation(dvb.PSK8))
	checkErr(fe.SetRolloff(dvb.RolloffAuto))
	checkErr(fe.SetPilot(dvb.PilotAuto))
	checkErr(fe.SetSymbolRate(uint32(sr * 1e3)))
	checkErr(fe.SetInnerFEC(dvb.FECAuto))
	checkErr(fe.SetInversion(dvb.InversionAuto))
	ifreq, tone, volt := frontend.SecParam(freq, rune(polar))
	checkErr(fe.SetFrequency(ifreq))
	checkErr(fe.SetTone(tone))
	checkErr(fe.SetVoltage(volt))

	checkErr(fe.Tune())

	deadline := time.Now().Add(5 * time.Second)
	var ev frontend.Event
	for ev.Status()&frontend.HasLock == 0 {
		timedout, err := frontend.API3{fe}.WaitEvent(&ev, deadline)
		checkErr(err)
		if timedout {
			die("tuning timeout")
		}
		fmt.Fprintln(os.Stderr, ev.Status())
	}
	fmt.Fprintln(os.Stderr, "tuned!")

	dmx := demux.Device(filepath.Join(*adapterPath, *demuxPath))
	f, err := dmx.NewStreamFilter(
		&demux.StreamFilterParam{
			Pid:  pids[0],
			In:   demux.InFrontend,
			Out:  demux.OutTSDemuxTap,
			Type: demux.Other,
		},
	)
	checkErr(err)
	defer f.Close()

	for _, pid := range pids[1:] {
		checkErr(f.AddPid(pid))
	}
	checkErr(f.SetBufferSize(1024 * ts.PktLen))
	checkErr(f.Start())

	r := ts.NewPktStreamReader(f)
	pkt := new(ts.ArrayPkt)

	for {
		t := time.Now()
		n := 4000
		for i := 0; i < n; i++ {
			checkErr(r.ReadPkt(pkt))
		}
		dt := time.Now().Sub(t)
		pps := time.Duration(n) * time.Second / dt
		fmt.Printf("%d pkt/s (%d kb/s)\n", pps, pps*ts.PktLen*8/1000)
	}
}