示例#1
0
        /// <summary>
        /// Führt die DiSEqC Steuerung aus.
        /// </summary>
        /// <param name="token">Die Informationen zur aktuellen Wahl der Quellgruppe.</param>
        /// <returns>Das Ergebnis der Operation.</returns>
        private PipelineResult ApplyDiSEqC( DataGraph.TuneToken token )
        {
            // See if we are fully active
            var message = (token == null) ? null : token.DiSEqCMessage;
            if (message == null)
            {
                // Shutdown connection
                Close();

                // Reset
                m_LastDiSEqC = null;

                // Next
                return PipelineResult.Continue;
            }

            // Attach to tuner
            var tuner = token.Pipeline.Graph.TunerFilter;
            if (tuner == null)
                return PipelineResult.Continue;

            // Verify that grpah is created
            if (token.Pipeline.Graph.TransportStreamAnalyser == null)
                return PipelineResult.Continue;

            // Already did it
            if (message.Equals( m_LastDiSEqC ))
                return PipelineResult.Continue;

            // Open the device
            Open( tuner );
            try
            {
                // Process
                var data = (byte[]) message.Request.Clone();
                var error = bdaapiSetDiSEqCMsg( Device, data, (byte) data.Length, (byte) message.Repeat, message.Burst, Polarisation.NotSet );
                if (error == APIErrorCodes.Success)
                    m_LastDiSEqC = message.Clone();
                else
                    throw new DVBException( error.ToString() );
            }
            catch (Exception e)
            {
                // Report
                EventLog.WriteEntry( "DVB.NET", string.Format( "TechnoTrend BDA API DiSEqC: {0}", e ), EventLogEntryType.Error );

                // Force recalibrate on next call
                m_LastDiSEqC = null;
            }

            // Next one, please
            return PipelineResult.Continue;
        }
示例#2
0
            /// <summary>
            /// Bereitet die internen Strukturen für die Konfiguration einer Quellgruppe für den
            /// Satellitenempfang vor.
            /// </summary>
            /// <param name="initializer">Methode zur Übernahme der Parameter der Quellgruppe.</param>
            /// <returns>Ein neuer Namensraum.</returns>
            private IDVBTuningSpace2 PrepareSatellite(out Action <ILocator> initializer)
            {
                // Get native types
                var location = GroupLocation as SatelliteLocation;
                var group    = SourceGroup as SatelliteGroup;

                // Create DiSEqC message
                if (location != null)
                {
                    if (group != null)
                    {
                        DiSEqCMessage = StandardDiSEqC.FromSourceGroup(group, location);
                    }
                }

                // Create tuning space
                var space = Activator.CreateInstance(Type.GetTypeFromCLSID(DVBSTuningSpaceClassIdentifier));

                try
                {
                    // Change type
                    var tuningSpace = (IDVBSTuningSpace)space;

                    // Configure
                    tuningSpace.UniqueName   = "DVBNET Satellite";
                    tuningSpace.FriendlyName = "DVB.NET Satellite Tuning Space";
                    tuningSpace.NetworkType  = "{FA4B375A-45B4-4D45-8440-263957B11623}";
                    tuningSpace.SystemType   = DVBSystemType.Satellite;

                    // Configure location
                    if (location != null)
                    {
                        // Configure
                        tuningSpace.LNBSwitch         = checked ((int)location.SwitchFrequency);
                        tuningSpace.HighOscillator    = checked ((int)location.Frequency2);
                        tuningSpace.LowOscillator     = checked ((int)location.Frequency1);
                        tuningSpace.SpectralInversion = SpectralInversion.Automatic;
                        tuningSpace.FrequencyMapping  = string.Empty;
                        tuningSpace.InputRange        = string.Empty;
                        tuningSpace.NetworkID         = -1;
                    }

                    // Create locator
                    var locator = Activator.CreateInstance(Type.GetTypeFromCLSID(DVBSLocatorClassIdentifier));
                    try
                    {
                        // Configure group
                        if (group == null)
                        {
                            initializer = null;
                        }
                        else
                        {
                            initializer = clone =>
                            {
                                // Change type
                                var dvbs = (IDVBSLocator)clone;

                                // Configure
                                dvbs.Modulation         = group.UsesS2Modulation ? ModulationType.VSB8 : ModulationType.QPSK;
                                dvbs.SymbolRate         = checked ((int)(group.SymbolRate / 1000));
                                dvbs.CarrierFrequency   = checked ((int)group.Frequency);
                                dvbs.InnerFECRate       = BinaryConvolutionCodeRate.NotSet;
                                dvbs.OuterFECRate       = BinaryConvolutionCodeRate.NotSet;
                                dvbs.SignalPolarisation = Polarisation.NotSet;
                                dvbs.WestPosition       = group.IsWestPosition;
                                dvbs.OuterFEC           = FECMethod.NotSet;
                                dvbs.InnerFEC           = FECMethod.NotSet;
                                dvbs.OrbitalPosition    = -1;
                                dvbs.Elevation          = -1;
                                dvbs.Azimuth            = 0;

                                // Set polarisation
                                switch (group.Polarization)
                                {
                                case Polarizations.Horizontal: dvbs.SignalPolarisation = Polarisation.Horizontal; break;

                                case Polarizations.Vertical: dvbs.SignalPolarisation = Polarisation.Vertical; break;
                                }

                                // Set rate
                                switch (group.InnerFEC)
                                {
                                case InnerForwardErrorCorrectionModes.Conv1_2: dvbs.InnerFEC = FECMethod.Viterbi; dvbs.InnerFECRate = BinaryConvolutionCodeRate.Rate1_2; break;

                                case InnerForwardErrorCorrectionModes.Conv2_3: dvbs.InnerFEC = FECMethod.Viterbi; dvbs.InnerFECRate = BinaryConvolutionCodeRate.Rate2_3; break;

                                case InnerForwardErrorCorrectionModes.Conv3_4: dvbs.InnerFEC = FECMethod.Viterbi; dvbs.InnerFECRate = BinaryConvolutionCodeRate.Rate3_4; break;

                                case InnerForwardErrorCorrectionModes.Conv3_5: dvbs.InnerFEC = FECMethod.Viterbi; dvbs.InnerFECRate = BinaryConvolutionCodeRate.Rate3_5; break;

                                case InnerForwardErrorCorrectionModes.Conv4_5: dvbs.InnerFEC = FECMethod.Viterbi; dvbs.InnerFECRate = BinaryConvolutionCodeRate.Rate4_5; break;

                                case InnerForwardErrorCorrectionModes.Conv5_6: dvbs.InnerFEC = FECMethod.Viterbi; dvbs.InnerFECRate = BinaryConvolutionCodeRate.Rate5_6; break;

                                case InnerForwardErrorCorrectionModes.Conv7_8: dvbs.InnerFEC = FECMethod.Viterbi; dvbs.InnerFECRate = BinaryConvolutionCodeRate.Rate7_8; break;

                                case InnerForwardErrorCorrectionModes.Conv8_9: dvbs.InnerFEC = FECMethod.Viterbi; dvbs.InnerFECRate = BinaryConvolutionCodeRate.Rate8_9; break;

                                case InnerForwardErrorCorrectionModes.Conv9_10: dvbs.InnerFEC = FECMethod.Viterbi; dvbs.InnerFECRate = BinaryConvolutionCodeRate.Rate9_10; break;
                                }
                            }
                        };

                        // Change type - actually test it
                        tuningSpace.DefaultLocator = (ILocator)locator;
                    }
                    finally
                    {
                        // Cleanup
                        BDAEnvironment.Release(ref locator);
                    }

                    // Report
                    return((IDVBTuningSpace2)tuningSpace);
                }
                catch
                {
                    // Cleanup
                    BDAEnvironment.Release(ref space);

                    // Forward
                    throw;
                }
            }
示例#3
0
        /// <summary>
        /// Wählt eine Quellgruppe aus.
        /// </summary>
        /// <param name="group">Díe Daten der Quellgruppe.</param>
        /// <param name="location">Die Wahl des Ursprungs, über den die Quellgruppe empfangen werden kann.</param>
        public void Tune( SourceGroup group, GroupLocation location )
        {
            // May repeat some times
            for (int retryCount = 3; retryCount-- > 0; Thread.Sleep( 250 ))
            {
                // All supported in order of importance
                if (!Tune( group as SatelliteGroup, location as SatelliteLocation ).HasValue)
                    if (!Tune( group as CableGroup ).HasValue)
                        if (!Tune( group as TerrestrialGroup ).HasValue)
                            throw new DVBException( "Unsupported channel type " + group.GetType().FullName );

                // Done if locked
                if (SignalStatus.Locked)
                    break;

                // Enforce reset
                m_lastMessage = null;
            }
        }
示例#4
0
        /// <summary>
        /// Wählt eine Quellgruppe aus.
        /// </summary>
        /// <param name="group">Díe Daten der Quellgruppe.</param>
        /// <param name="location">Die Wahl des Ursprungs, über den die Quellgruppe empfangen werden kann.</param>
        /// <returns>Gesetzt, wenn es sich um eine DVB-S Quellgruppe handelt.</returns>
        private Channel_S? Tune( SatelliteGroup group, SatelliteLocation location )
        {
            // Not us
            if (location == null)
                return null;
            if (group == null)
                return null;

            // Validate
            if (FrontendType != FrontendType.Satellite)
                throw new DVBException( "Expected " + FrontendType.ToString() + " Channel" );

            // Create channel
            var data =
                new Channel_S
                {
                    Mode = group.UsesS2Modulation ? DVBSMode.DVB_S2 : DVBSMode.DVB_S,
                    Inversion = SpectrumInversion.Auto,
                    SymbolRate = group.SymbolRate,
                    Frequency = group.Frequency,
                };


            // Attach to the DiSEqC setting
            var selector = StandardDiSEqC.FromSourceGroup( group, location );

            // See if the message is different from the last one
            if (!selector.Equals( m_lastMessage ))
            {
                // Remember
                m_lastMessage = selector.Clone();

                // As long as necessary
                for (int nCount = selector.Repeat; nCount-- > 0; Thread.Sleep( 120 ))
                {
                    // Send it
                    DVBException.ThrowOnError( _SendDiSEqCMsg( m_Class.ClassPointer, selector.Request, (byte) selector.Request.Length, selector.Burst ), "Could not send DiSEqC message" );

                    // Set repeat flag
                    if (selector.Request.Length > 0)
                        selector.Request[0] |= 1;
                }
            }

            // Calculated items
            data.b22kHz = (group.Frequency >= location.SwitchFrequency) ? 1 : 0;
            data.LOF = (0 == data.b22kHz) ? location.Frequency1 : location.Frequency2;

            // Power modes
            switch (group.Polarization)
            {
                case Polarizations.Horizontal: data.LNBPower = PowerMode.Horizontal; break;
                case Polarizations.Vertical: data.LNBPower = PowerMode.Vertical; break;
                case Polarizations.NotDefined: data.LNBPower = PowerMode.Off; break;
                default: throw new ArgumentException( group.Polarization.ToString(), "Polarization" );
            }

            // Process
            return data.SetChannel( this, false );
        }
示例#5
0
        /// <summary>
        /// Übernimmt die Ansteuerung einer Antenne.
        /// </summary>
        /// <param name="tune">Der aktuelle Änderungswunsch.</param>
        /// <returns>Beschreibt, wie weiter fortzufahren ist.</returns>
        private PipelineResult ApplyDiSEqC( DataGraph.TuneToken tune )
        {
            // Not active
            var diseqc = (tune == null) ? null : tune.DiSEqCMessage;
            if (diseqc == null)
            {
                // Reset request - or first call at all
                m_LastDiSEqC = null;

                // Next
                return PipelineResult.Continue;
            }

            // Attach to tuner
            var tuner = tune.Pipeline.Graph.TunerFilter;
            if (tuner == null)
                return PipelineResult.Continue;

            // Verify that grpah is created
            if (tune.Pipeline.Graph.TransportStreamAnalyser == null)
                return PipelineResult.Continue;

            // Request the message to send
            if (diseqc.Equals( m_LastDiSEqC ))
                return PipelineResult.Continue;

            // Attach to the one input pin of the tuner
            using (var input = tuner.GetSinglePin( PinDirection.Input ))
            using (var propertySet = KsPropertySet.Create<NovaDiSEqCMessage>( input.Interface ))
                if (propertySet != null)
                {
                    // Create the identifier of the property to use
                    var nodeReference = KsPNode.Create( BdaTunerExtensionProperties, BDATunerExtensions.DiSEqC, BDANodes.Tuner );

                    // Check for support of the property
                    if (!propertySet.DoesSupport( nodeReference, PropertySetSupportedTypes.Set ))
                        return PipelineResult.Continue;

                    // Create structures
                    var message = new NovaDiSEqCMessage();

                    // Create a copy
                    var command = (byte[]) diseqc.Request.Clone();

                    // As long as necessary
                    for (int nCount = diseqc.Repeat; nCount-- > 0; Thread.Sleep( 120 ))
                        try
                        {
                            // Prepare the message
                            message.Request = new byte[151];
                            message.Response = new byte[9];

                            // Fill the message
                            command.CopyTo( message.Request, 0 );

                            // Set the lengths
                            message.RequestLength = (uint) command.Length;
                            message.ResponseLength = 0;

                            // Configure
                            message.ToneBurstModulation = (ToneBurstModulationModes) diseqc.Burst;
                            message.ResponseMode = DiSEqCReceiveModes.NoReply;
                            message.DiSEqCVersion = DiSEqCVersions.Version1;
                            message.AmplitudeAttenuation = 3;
                            message.LastMessage = true;

                            // Send the message
                            propertySet.Set( nodeReference, message );

                            // Set repeat flag
                            if (command.Length > 0)
                                command[0] |= 1;
                        }
                        catch
                        {
                            // Reset
                            m_LastDiSEqC = null;

                            // Forward
                            throw;
                        }

                    // Remember
                    m_LastDiSEqC = diseqc.Clone();
                }

            // Done
            return PipelineResult.Continue;
        }
示例#6
0
        /// <summary>
        /// Wählt eine Quellgruppe aus.
        /// </summary>
        /// <param name="group">Díe Daten der Quellgruppe.</param>
        /// <param name="location">Die Wahl des Ursprungs, über den die Quellgruppe empfangen werden kann.</param>
        /// <returns>Gesetzt, wenn es sich um eine DVB-S Quellgruppe handelt.</returns>
        private bool SendChannel( SatelliteGroup group, SatelliteLocation location )
        {
            // Not us
            if (location == null)
                return false;
            if (group == null)
                return false;

            // Validate
            if (FrontendType != FrontendType.Satellite)
                throw new DVBException( "Expected " + FrontendType.ToString() + " Channel" );

            // Create channel
            var channel =
                new Channel_S
                {
                    Inversion = SpectrumInversion.Auto,
                    SymbolRate = group.SymbolRate,
                    Frequency = group.Frequency,
                };

            // Attach to the DiSEqC setting
            var selector = StandardDiSEqC.FromSourceGroup( group, location );

            // See if the message is different from the last one
            if (!selector.Equals( m_lastMessage ))
            {
                // Remember
                m_lastMessage = selector.Clone();

                // As long as necessary
                for (int nCount = selector.Repeat; nCount-- > 0; Thread.Sleep( 120 ))
                {
                    // Send it
                    DVBException.ThrowOnError( CDVBFrontend_SendDiSEqCMsg( m_Class.ClassPointer, selector.Request, (byte) selector.Request.Length, selector.Burst ), "Could not send DiSEqC Message" );

                    // Set repeat flag
                    if (selector.Request.Length > 0)
                        selector.Request[0] |= 1;
                }
            }

            // Calculated items
            channel.b22kHz = (group.Frequency >= location.SwitchFrequency) ? 1 : 0;
            channel.LOF = (0 == channel.b22kHz) ? location.Frequency1 : location.Frequency2;

            // Power modes
            switch (group.Polarization)
            {
                case Polarizations.Horizontal: channel.LNBPower = PowerMode.Horizontal; break;
                case Polarizations.Vertical: channel.LNBPower = PowerMode.Vertical; break;
                case Polarizations.NotDefined: channel.LNBPower = PowerMode.Off; break;
                default: throw new ArgumentException( group.Polarization.ToString(), "Polarization" );
            }

            // Process
            CheckChannel( CDVBFrontend_SetChannel( m_Class.ClassPointer, channel, false ) );

            // Check up for synchronisation
            Channel_S val1, val2;

            // Get channel twice
            CheckChannel( CDVBFrontend_GetChannel( m_Class.ClassPointer, out val1 ) );
            CheckChannel( CDVBFrontend_GetChannel( m_Class.ClassPointer, out val2 ) );

            // Did it
            return true;
        }
示例#7
0
        /// <summary>
        /// Wählt eine Quellgruppe aus.
        /// </summary>
        /// <param name="group">Díe Daten der Quellgruppe.</param>
        /// <param name="location">Die Wahl des Ursprungs, über den die Quellgruppe empfangen werden kann.</param>
        /// <returns>Gesetzt, wenn es sich um eine DVB-S Quellgruppe handelt.</returns>
        public void SetChannel( SourceGroup group, GroupLocation location )
        {
            // Stop all filters
            StopFilters();

            // May repeat some times
            for (int nRetry = 3; nRetry-- > 0; )
            {
                // Supported types in order of importance
                if (!SendChannel( group as SatelliteGroup, location as SatelliteLocation ))
                    if (!SendChannel( group as CableGroup ))
                        if (!SendChannel( group as TerrestrialGroup ))
                            throw new DVBException( "Unsupported Channel Type " + group.GetType().FullName );

                // Wait for the signal
                for (int n = 10; n-- > 0; Thread.Sleep( 50 ))
                    if (SignalStatus.Locked)
                        return;

                // Force to resend DiSEqC command
                m_lastMessage = null;
            }
        }
示例#8
0
        /// <summary>
        /// Initialize the frontend.
        /// </summary>
        /// <remarks>
        /// When the C++ method invocation reports a hardware error the call is repeated
        /// up to three times with a <see cref="Thread.Sleep(int)"/>(500) between the calls. 
        /// If the error holds a <see cref="DVBException"/> is thrown.
        /// <see cref="StopFilters"/>
        /// </remarks>
        /// <exception cref="DVBException">
        /// Thrown when the C++ method invocation reports some <see cref="DVBError"/>.
        /// </exception>
        public void Initialize()
        {
            // Time to stop all filters
            StopFilters();

            // Execute
            DVBError eCode = CDVBFrontend_Init( m_Class.ClassPointer );

            // Retry
            for (int nRetry = 3; (DVBError.Hardware == eCode) && (nRetry-- > 0); )
            {
                // Delay
                Thread.Sleep( 500 );

                // Try again
                eCode = CDVBFrontend_Init( m_Class.ClassPointer );
            }

            // Validate
            if (DVBError.None != eCode) throw new DVBException( "Can not initialize Frontend", eCode );

            // Reset
            m_lastMessage = null;
        }
示例#9
0
        /// <summary>
        /// Führt die DiSEqC Steuerung aus.
        /// </summary>
        /// <param name="token">Die aktuellen Informationen zum Wechsel der Quellgruppe.</param>
        /// <returns>Meldet, wie die weitere Abarbeitung zu erfolgen hat.</returns>
        private PipelineResult ApplyDiSEqC( DataGraph.TuneToken token )
        {
            // Not active
            var diseqc = (token == null) ? null : token.DiSEqCMessage;
            if (diseqc == null)
            {
                // Reset request - or first call at all
                m_LastDiSEqC = null;

                // Next
                return PipelineResult.Continue;
            }

            // Attach to tuner
            var tuner = token.Pipeline.Graph.TunerFilter;
            if (tuner == null)
                return PipelineResult.Continue;

            // Verify that grpah is created
            if (token.Pipeline.Graph.TransportStreamAnalyser == null)
                return PipelineResult.Continue;

            // Request the message to send
            if (diseqc.Equals( m_LastDiSEqC ))
                return PipelineResult.Continue;

            // Attach to the one input pin of the tuner
            using (var input = tuner.GetSinglePin( PinDirection.Input ))
            using (var propertySet = KsPropertySet.Create<DiSEqCMessage>( input.Interface ))
                if (propertySet != null)
                {
                    // Create the identifier of the property to use
                    var nodeReference = KsPNode.Create( TunerExtensionPropertiesS2, TunerExtensionProperties.DiSEqC, 0 );

                    // Check for support of the property
                    if (!propertySet.DoesSupport( nodeReference, PropertySetSupportedTypes.Set ))
                        return PipelineResult.Continue;

                    // Create structures
                    var message = new DiSEqCMessage();

                    // Create a copy
                    var command = (byte[]) diseqc.Request.Clone();

                    // As long as necessary
                    try
                    {
                        // Prepare the message
                        message.Request = new byte[151];

                        // Fill the message
                        command.CopyTo( message.Request, 0 );

                        // Configure
                        message.RequestLength = (byte) command.Length;
                        message.LastMessage = true;
                        message.Power = 0;

                        // Send the message
                        propertySet.Set( nodeReference, message );
                    }
                    catch
                    {
                        // Reset
                        m_LastDiSEqC = null;

                        // Forward
                        throw;
                    }

                    // Remember
                    m_LastDiSEqC = diseqc.Clone();
                }

            // Next
            return PipelineResult.Continue;
        }