From: <an...@us...> - 2007-11-05 13:23:57
|
Revision: 1029 http://mp-plugins.svn.sourceforge.net/mp-plugins/?rev=1029&view=rev Author: and-81 Date: 2007-11-05 05:23:54 -0800 (Mon, 05 Nov 2007) Log Message: ----------- Modified Paths: -------------- trunk/plugins/IR Server Suite/IR Server Plugins/Microsoft MCE Transceiver/IrDecoder.cs trunk/plugins/IR Server Suite/IR Server Plugins/Microsoft MCE Transceiver/MicrosoftMceTransceiver.cs trunk/plugins/IR Server Suite/IR Server Suite.sln Added Paths: ----------- trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/ trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/IgorPlug Receiver.cs trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/IgorPlug Receiver.csproj trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/IrDecoder.cs trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/MceDetectionData.cs trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/Properties/ trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/Properties/AssemblyInfo.cs trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/RemoteDetectionData.cs Removed Paths: ------------- trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug USB Receiver/ Added: trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/IgorPlug Receiver.cs =================================================================== --- trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/IgorPlug Receiver.cs (rev 0) +++ trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/IgorPlug Receiver.cs 2007-11-05 13:23:54 UTC (rev 1029) @@ -0,0 +1,423 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading; + +using Microsoft.Win32.SafeHandles; + +using IRServerPluginInterface; + +namespace IgorPlugReceiver +{ + + public class IgorPlugReceiver : IRServerPluginBase, IRemoteReceiver + { + + #region Constants + + const int NO_ERROR = 0; + const int DEVICE_NOT_PRESENT = 1; + const int NO_DATA_AVAILABLE = 2; + const int INVALID_BAUDRATE = 3; + const int OVERRUN_ERROR = 4; + + const int FNCNumberDoSetInfraBufferEmpty = 1; // restart of infra reading (if was stopped by RAM reading) + const int FNCNumberDoGetInfraCode = 2; // transmit of receved infra code (if some code in infra buffer) + + const int DeviceBuffer = 256; + + const double TimeCodeMultiplier = 85.3; + + #endregion Constants + + #region Enumerations + + [Flags] + enum CreateFileAccessTypes : uint + { + GenericRead = 0x80000000, + GenericWrite = 0x40000000, + GenericExecute = 0x20000000, + GenericAll = 0x10000000, + } + + [Flags] + enum CreateFileShares : uint + { + None = 0x00, + Read = 0x01, + Write = 0x02, + Delete = 0x04, + } + + enum CreateFileDisposition : uint + { + None = 0, + New = 1, + CreateAlways = 2, + OpenExisting = 3, + OpenAlways = 4, + TruncateExisting = 5, + } + + [Flags] + enum CreateFileAttributes : uint + { + None = 0x00000000, + Readonly = 0x00000001, + Hidden = 0x00000002, + System = 0x00000004, + Directory = 0x00000010, + Archive = 0x00000020, + Device = 0x00000040, + Normal = 0x00000080, + Temporary = 0x00000100, + SparseFile = 0x00000200, + ReparsePoint = 0x00000400, + Compressed = 0x00000800, + Offline = 0x00001000, + NotContentIndexed = 0x00002000, + Encrypted = 0x00004000, + Write_Through = 0x80000000, + Overlapped = 0x40000000, + NoBuffering = 0x20000000, + RandomAccess = 0x10000000, + SequentialScan = 0x08000000, + DeleteOnClose = 0x04000000, + BackupSemantics = 0x02000000, + PosixSemantics = 0x01000000, + OpenReparsePoint = 0x00200000, + OpenNoRecall = 0x00100000, + FirstPipeInstance = 0x00080000, + } + + #endregion Enumerations + + #region Interop + + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] + static extern SafeFileHandle CreateFile( + [MarshalAs(UnmanagedType.LPTStr)] string fileName, + [MarshalAs(UnmanagedType.U4)] CreateFileAccessTypes fileAccess, + [MarshalAs(UnmanagedType.U4)] CreateFileShares fileShare, + IntPtr securityAttributes, + [MarshalAs(UnmanagedType.U4)] CreateFileDisposition creationDisposition, + [MarshalAs(UnmanagedType.U4)] CreateFileAttributes flags, + IntPtr templateFile); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + static extern bool CloseHandle( + SafeFileHandle handle); + + [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] + static extern bool DeviceIoControl( + SafeFileHandle handle, + uint ioControlCode, + byte[] inBuffer, int inBufferSize, + byte[] outBuffer, int outBufferSize, + out int bytesReturned, + IntPtr overlapped); + + #endregion Interop + + #region Variables + + int _remoteFirstRepeat = 400; + int _remoteHeldRepeats = 250; + + RemoteHandler _remoteHandler; + //KeyboardHandler _keyboardHandler; + //MouseHandler _mouseHandler; + + Thread _readThread; + + IrProtocol _lastRemoteButtonCodeType = IrProtocol.None; + uint _lastRemoteButtonKeyCode = 0; + DateTime _lastRemoteButtonTime = DateTime.Now; + bool _remoteButtonRepeated = false; + + #endregion Variables + + #region Implementation + + public override string Name { get { return "IgorPlug"; } } + public override string Version { get { return "1.0.3.5"; } } + public override string Author { get { return "and-81"; } } + public override string Description { get { return "IgorPlug Receiver"; } } + + public override bool Start() + { + ThreadStart readThreadStart = new ThreadStart(ReadThread); + _readThread = new Thread(readThreadStart); + _readThread.IsBackground = true; + _readThread.Start(); + + return true; + } + public override void Suspend() + { + Stop(); + } + public override void Resume() + { + Start(); + } + public override void Stop() + { + _readThread.Abort(); + + if (_readThread.IsAlive) + _readThread.Join(); + } + + /// <summary> + /// Callback for remote button presses. + /// </summary> + public RemoteHandler RemoteCallback + { + get { return _remoteHandler; } + set { _remoteHandler = value; } + } + + void ReadThread() + { + try + { + byte[] timingCode = new byte[DeviceBuffer]; + int codeLength = 0; + int returnCode; + + DoSetInfraBufferEmpty(); + + while (true) + { + returnCode = DoGetInfraCode(ref timingCode, ref codeLength); + + switch (returnCode) + { + case NO_ERROR: + break; + + case NO_DATA_AVAILABLE: + continue; + + case DEVICE_NOT_PRESENT: + throw new IOException("Device not present"); + + case INVALID_BAUDRATE: + throw new IOException("Invalid baud rate"); + + case OVERRUN_ERROR: + throw new IOException("Overrun error"); + + default: + throw new IOException(String.Format("Unknown error ({0})", returnCode)); + } + + byte[] data = new byte[codeLength]; + Array.Copy(timingCode, data, codeLength); + + int[] timingData = GetTimingData(data); + + IrDecoder.DecodeIR(timingData, new RemoteCallback(RemoteEvent), null, null); + + Thread.Sleep(100); + DoSetInfraBufferEmpty(); + } + } +#if TRACE + catch (ThreadAbortException ex) + { + Trace.WriteLine(ex.ToString()); +#else + catch (ThreadAbortException) + { +#endif + } + } + + void RemoteEvent(IrProtocol codeType, uint keyCode, bool firstPress) + { +#if TRACE + Trace.WriteLine(String.Format("Remote: {0}, {1}, {2}", Enum.GetName(typeof(IrProtocol), codeType), keyCode, firstPress)); +#endif + + if (!firstPress && _lastRemoteButtonCodeType == codeType && _lastRemoteButtonKeyCode == keyCode) + { + TimeSpan timeBetween = DateTime.Now.Subtract(_lastRemoteButtonTime); + + if (!_remoteButtonRepeated && timeBetween.TotalMilliseconds < _remoteFirstRepeat) + { +#if TRACE + Trace.WriteLine("Skip First Repeat"); +#endif + return; + } + + if (_remoteButtonRepeated && timeBetween.TotalMilliseconds < _remoteHeldRepeats) + { +#if TRACE + Trace.WriteLine("Skip Held Repeat"); +#endif + return; + } + + if (_remoteButtonRepeated && timeBetween.TotalMilliseconds > _remoteFirstRepeat) + _remoteButtonRepeated = false; + else + _remoteButtonRepeated = true; + } + else + { + _lastRemoteButtonCodeType = codeType; + _lastRemoteButtonKeyCode = keyCode; + _remoteButtonRepeated = false; + } + + _lastRemoteButtonTime = DateTime.Now; + + if (_remoteHandler != null) + _remoteHandler(keyCode.ToString()); + } + + static int[] GetTimingData(byte[] data) + { + List<int> timingData = new List<int>(data.Length); + + int multiplier = 1; + + foreach (byte dataByte in data) + { + timingData.Add((int)Math.Round(dataByte * TimeCodeMultiplier * multiplier)); + + multiplier *= -1; + } + + return timingData.ToArray(); + } + + static bool SendToDriver(byte FNumber, int Param1, int Param2, ref byte[] OutputData, ref int OutLength) + { + bool Result = false; + + SafeFileHandle handle = CreateFile("\\\\.\\IgorPlugUSB_0", + CreateFileAccessTypes.GenericRead | CreateFileAccessTypes.GenericWrite, + CreateFileShares.Read | CreateFileShares.Write, + IntPtr.Zero, + CreateFileDisposition.OpenExisting, + CreateFileAttributes.None, + IntPtr.Zero); + + if (handle.IsInvalid) + throw new Exception("Cannot Open IgorUSB Driver!"); + + try + { + int RepeatCount = 3; + int OutLengthMax; + + OutLengthMax = (OutLength > 255 ? 256 : OutLength) & 0xFF; + + byte[] Input = new byte[5]; + byte[] tmp; + Input[0] = FNumber; + tmp = BitConverter.GetBytes(Param1); + Input[1] = tmp[0]; + Input[2] = tmp[1]; + tmp = BitConverter.GetBytes(Param2); + Input[3] = tmp[0]; + Input[4] = tmp[1]; + + try + { + do + { + Result = DeviceIoControl(handle, 0x808, Input, 5, OutputData, OutLengthMax, out OutLength, IntPtr.Zero); + Result = Result && (OutLength > 0); + RepeatCount--; + } while ((OutLength == 0) && (RepeatCount > 0)); + } + catch + { + Result = false; + } + } + finally + { + CloseHandle(handle); + } + + return Result; + } + + static int DoSetInfraBufferEmpty() + { + int OutLength = 1; + byte[] OutputData = new byte[DeviceBuffer]; + + if (SendToDriver(FNCNumberDoSetInfraBufferEmpty, 0, 0, ref OutputData, ref OutLength)) + return NO_ERROR; + else + return DEVICE_NOT_PRESENT; + } + + static int DoGetInfraCode(ref byte[] TimeCodeDiagram, ref int DiagramLength) + { + int OutLength; + byte[] OutputData = new byte[DeviceBuffer]; + + int LastReadedCode = -1; + int BytesToRead; + byte[] tmpData = new byte[DeviceBuffer]; + int LastWrittenIndex; + int i, j, k; + + DiagramLength = 0; + OutLength = 3; + if (!SendToDriver(FNCNumberDoGetInfraCode, 0, 0, ref OutputData, ref OutLength)) + return DEVICE_NOT_PRESENT; //dev not present + + BytesToRead = OutputData[0]; + if ((LastReadedCode == OutputData[1]) || (OutLength <= 1) || (BytesToRead == 0)) + return NO_ERROR; + + LastReadedCode = OutputData[1]; + LastWrittenIndex = OutputData[2]; + i = 0; + while (i < BytesToRead) + { + OutLength = BytesToRead - i; + if (!SendToDriver(2, i + 3, 0, ref tmpData, ref OutLength)) + { + DoSetInfraBufferEmpty(); + LastReadedCode = -1; + return DEVICE_NOT_PRESENT; + } + + for (j = 0; j < OutLength; j++) + OutputData[i + j] = tmpData[j]; // 'memcpy + + i += OutLength; + } + + j = LastWrittenIndex % BytesToRead; + k = 0; + for (i = j; i < BytesToRead; i++) + TimeCodeDiagram[k++] = OutputData[i]; + for (i = 0; i < j; i++) + TimeCodeDiagram[k++] = OutputData[i]; + DiagramLength = BytesToRead; + DoSetInfraBufferEmpty(); + return NO_ERROR; + } + + #endregion Implementation + + } + +} Added: trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/IgorPlug Receiver.csproj =================================================================== --- trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/IgorPlug Receiver.csproj (rev 0) +++ trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/IgorPlug Receiver.csproj 2007-11-05 13:23:54 UTC (rev 1029) @@ -0,0 +1,86 @@ +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>8.0.50727</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{A4023992-CCD6-461E-8E14-219A496734C5}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>IgorPlugReceiver</RootNamespace> + <AssemblyName>IgorPlug Receiver</AssemblyName> + <RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>false</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <TreatWarningsAsErrors>true</TreatWarningsAsErrors> + <UseVSHostingProcess>false</UseVSHostingProcess> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>none</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants> + </DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <TreatWarningsAsErrors>true</TreatWarningsAsErrors> + <UseVSHostingProcess>false</UseVSHostingProcess> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> + <OutputPath>bin\x86\Debug\</OutputPath> + <DefineConstants>TRACE;DEBUG</DefineConstants> + <TreatWarningsAsErrors>true</TreatWarningsAsErrors> + <DebugType>full</DebugType> + <PlatformTarget>x86</PlatformTarget> + <UseVSHostingProcess>false</UseVSHostingProcess> + <ErrorReport>prompt</ErrorReport> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> + <OutputPath>bin\x86\Release\</OutputPath> + <Optimize>true</Optimize> + <TreatWarningsAsErrors>true</TreatWarningsAsErrors> + <DebugType> + </DebugType> + <PlatformTarget>x86</PlatformTarget> + <UseVSHostingProcess>false</UseVSHostingProcess> + <ErrorReport>prompt</ErrorReport> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="System.Data" /> + <Reference Include="System.Windows.Forms" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="IgorPlug Receiver.cs" /> + <Compile Include="IrDecoder.cs" /> + <Compile Include="MceDetectionData.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="RemoteDetectionData.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\IR Server Plugin Interface\IR Server Plugin Interface.csproj"> + <Project>{D8B3D28F-62CE-4CA7-86CE-B7EAD614A94C}</Project> + <Name>IR Server Plugin Interface</Name> + <Private>False</Private> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> + <PropertyGroup> + <PostBuildEvent>copy "$(TargetName).*" "\MediaPortal Development\Plugin Releases\IR Server Suite\IR Server Plugins\"</PostBuildEvent> + </PropertyGroup> +</Project> \ No newline at end of file Added: trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/IrDecoder.cs =================================================================== --- trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/IrDecoder.cs (rev 0) +++ trunk/plugins/IR Server Suite/IR Server Plugins/IgorPlug Receiver/IrDecoder.cs 2007-11-05 13:23:54 UTC (rev 1029) @@ -0,0 +1,2221 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace IgorPlugReceiver +{ + + #region Enumerations + + /// <summary> + /// Protocol of IR Code. + /// </summary> + enum IrProtocol + { + /// <summary> + /// No protocol. + /// </summary> + None, + + /// <summary> + /// Daewoo protocol. + /// </summary> + Daewoo, + /// <summary> + /// ITT protocol (unsupported). + /// </summary> + ITT, + /// <summary> + /// JVC protocol. + /// </summary> + JVC, + /// <summary> + /// Matsushita protocol. + /// </summary> + Matsushita, + /// <summary> + /// Mitsubishi protocol. + /// </summary> + Mitsubishi, + /// <summary> + /// NEC protocol. + /// </summary> + NEC, + /// <summary> + /// Nokia NRC17 protocol. + /// </summary> + NRC17, + /// <summary> + /// Panasonic protocol. + /// </summary> + Panasonic, + /// <summary> + /// Philips RC5 protocol. + /// </summary> + RC5, + /// <summary> + /// Philips RC5X protocol. + /// </summary> + RC5X, + /// <summary> + /// Philips RC6 protocol (Mode 0). + /// </summary> + RC6, + /// <summary> + /// Philips RC6 protocol (Mode 6A). + /// </summary> + RC6A, + /// <summary> + /// Microsoft's protocol variation of Philips RC6. + /// </summary> + RC6_MCE, + /// <summary> + /// RCA protocol. + /// </summary> + RCA, + /// <summary> + /// Philips RC-MM protocol. This protocol cannot be reliably (if at all) decoded by the MCE device. + /// </summary> + RCMM, + /// <summary> + /// RECS-80 protocol. + /// </summary> + RECS80, + /// <summary> + /// Sharp protocol (unsupported). + /// </summary> + Sharp, + /// <summary> + /// Sony SIRC protocol. + /// </summary> + SIRC, + /// <summary> + /// Toshiba protocol. + /// </summary> + Toshiba, + /// <summary> + /// X-Sat protocol (unsupported). + /// </summary> + XSAT, + + /// <summary> + /// Unknown protocol. + /// </summary> + Unknown, + } + + #endregion Enumerations + + #region Delegates + + delegate void RemoteCallback(IrProtocol codeType, uint keyCode, bool firstPress); + delegate void KeyboardCallback(uint keyCode, uint modifiers); + delegate void MouseCallback(int deltaX, int deltaY, bool rightButton, bool leftButton); + + #endregion Delegates + + /// <summary> + /// Used for decoding received IR Codes. + /// </summary> + static class IrDecoder + { + + #region Constants + + const ushort ToggleBitMce = 0x8000; + const ushort ToggleMaskMce = 0x7FFF; + const ushort CustomerMce = 0x800F; + + const ushort ToggleBitRC5 = 0x0800; + const ushort ToggleMaskRC5 = 0xF7FF; + + const uint ToggleBitRC5X = 0x00020000; + const ushort ToggleMaskRC5X = 0xFFFF; + + const uint RC6HeaderMask = 0xFFFFFFF0; + + const uint PrefixRC6 = 0x000FC950; + const uint PrefixRC6A = 0x000FCA90; + + const uint MceMouse = 1; + const uint MceKeyboard = 4; + + #endregion Constants + + #region Detection Data + + static RemoteDetectionData Daewoo_Data = new RemoteDetectionData(); + static RemoteDetectionData JVC_Data = new RemoteDetectionData(); + static RemoteDetectionData Matsushita_Data = new RemoteDetectionData(); + static RemoteDetectionData Mitsubishi_Data = new RemoteDetectionData(); + static RemoteDetectionData NEC_Data = new RemoteDetectionData(); + static RemoteDetectionData NRC17_Data = new RemoteDetectionData(); + static RemoteDetectionData Panasonic_Data = new RemoteDetectionData(); + static RemoteDetectionData RC5_Data = new RemoteDetectionData(); + static RemoteDetectionData RC6_Data = new RemoteDetectionData(); + static RemoteDetectionData RCA_Data = new RemoteDetectionData(); + static RemoteDetectionData RECS80_Data = new RemoteDetectionData(); + static RemoteDetectionData SIRC_Data = new RemoteDetectionData(); + static RemoteDetectionData Toshiba_Data = new RemoteDetectionData(); + + static MceDetectionData MCE_Data = new MceDetectionData(); + + #endregion Detection Data + + #region Methods + + /// <summary> + /// Decode timing data to discover IR Protocol and packet payload. + /// </summary> + /// <param name="timingData">Input timing data.</param> + /// <param name="remoteCallback">Method to call when Remote button decoded.</param> + /// <param name="keyboardCallback">Method to call when Keyboard event decoded.</param> + /// <param name="mouseCallback">Method to call when Mouse event decoded.</param> + public static void DecodeIR(int[] timingData, RemoteCallback remoteCallback, KeyboardCallback keyboardCallback, MouseCallback mouseCallback) + { + if (timingData == null) + return; + + DetectDaewoo(timingData, remoteCallback); +// DetectITT(timingData, remoteCallback); + DetectJVC(timingData, remoteCallback); + DetectMatsushita(timingData, remoteCallback); + DetectMitsubishi(timingData, remoteCallback); + DetectNEC(timingData, remoteCallback); + DetectNRC17(timingData, remoteCallback); + DetectPanasonic(timingData, remoteCallback); + DetectRC5(timingData, remoteCallback); + DetectRC6(timingData, remoteCallback); + DetectRCA(timingData, remoteCallback); +// DetectRCMM(timingData, remoteCallback); + DetectRECS80(timingData, remoteCallback); +// DetectSharp(timingData, remoteCallback); + DetectSIRC(timingData, remoteCallback); + DetectToshiba(timingData, remoteCallback); +// DetectXSAT(timingData, remoteCallback); + + DetectMCE(timingData, keyboardCallback, mouseCallback); + //DetectIMon(timingData, keyboardCallback, mouseCallback); + } + + static void DetectDaewoo(int[] timingData, RemoteCallback remoteCallback) + { + for (int i = 0; i < timingData.Length; i++) + { + int duration = Math.Abs(timingData[i]); + bool pulse = (timingData[i] > 0); + bool ignored = true; + + switch (Daewoo_Data.State) + { + + #region HeaderPulse + case RemoteDetectionState.HeaderPulse: + //Console.WriteLine("Daewoo HeaderPulse"); + + if (pulse && duration >= 7800 && duration <= 8200) + { + Daewoo_Data.State = RemoteDetectionState.HeaderSpace; + ignored = false; + } + break; + #endregion HeaderPulse + + #region HeaderSpace + case RemoteDetectionState.HeaderSpace: + //Console.WriteLine("Daewoo HeaderSpace"); + + if (!pulse && duration >= 3800 && duration <= 4200) + { + Daewoo_Data.State = RemoteDetectionState.Data; + Daewoo_Data.HalfBit = 0; + Daewoo_Data.Bit = 0; + Daewoo_Data.Code = 0; + ignored = false; + } + else if (!pulse && duration >= 10000 && duration <= 40000) // For Repeats + { + Daewoo_Data.State = RemoteDetectionState.Data; + Daewoo_Data.HalfBit = 0; + Daewoo_Data.Bit = 0; + Daewoo_Data.Code = 0; + ignored = false; + } + break; + #endregion HeaderSpace + + #region Data + case RemoteDetectionState.Data: + //Console.WriteLine("Daewoo Data"); + + if (pulse && duration >= 350 && duration <= 750) + { + Daewoo_Data.HalfBit = 1; + ignored = false; + } + else if (!pulse && duration >= 250 && duration <= 650 && Daewoo_Data.HalfBit == 1) + { + Daewoo_Data.Code <<= 1; + Daewoo_Data.Bit++; + Daewoo_Data.HalfBit = 0; + ignored = false; + } + else if (!pulse && duration >= 1250 && duration <= 1650 && Daewoo_Data.HalfBit == 1) + { + Daewoo_Data.Code <<= 1; + Daewoo_Data.Code |= 1; + Daewoo_Data.Bit++; + Daewoo_Data.HalfBit = 0; + ignored = false; + } + else + { + //Console.WriteLine("Daewoo Error"); + } + + if (Daewoo_Data.Bit == 16) + { + remoteCallback(IrProtocol.Daewoo, Daewoo_Data.Code, false); + Daewoo_Data.State = RemoteDetectionState.Leading; + } + break; + #endregion Data + + #region Leading + case RemoteDetectionState.Leading: + //Console.WriteLine("Daewoo Leading"); + + if (pulse && duration >= 350 && duration <= 750) + { + Daewoo_Data.State = RemoteDetectionState.HeaderSpace; + ignored = false; + } + break; + #endregion Leading + + } + + if (ignored && (Daewoo_Data.State != RemoteDetectionState.HeaderPulse)) + Daewoo_Data.State = RemoteDetectionState.HeaderPulse; + } + } + static void DetectJVC(int[] timingData, RemoteCallback remoteCallback) + { + for (int i = 0; i < timingData.Length; i++) + { + int duration = Math.Abs(timingData[i]); + bool pulse = (timingData[i] > 0); + bool ignored = true; + + switch (JVC_Data.State) + { + + #region HeaderPulse + case RemoteDetectionState.HeaderPulse: + //Console.WriteLine("JVC HeaderPulse: {0}", timingData[i]); + + if (pulse && duration >= 8300 && duration <= 8500) + { + JVC_Data.State = RemoteDetectionState.HeaderSpace; + ignored = false; + } + break; + #endregion HeaderPulse + + #region HeaderSpace + case RemoteDetectionState.HeaderSpace: + //Console.WriteLine("JVC HeaderSpace: {0}", timingData[i]); + + if (!pulse && duration >= 4100 && duration <= 4300) + { + JVC_Data.Toggle = 0; + + JVC_Data.State = RemoteDetectionState.Data; + JVC_Data.HalfBit = 0; + JVC_Data.Bit = 0; + JVC_Data.Code = 0; + ignored = false; + } + break; + #endregion HeaderSpace + + #region Data + case RemoteDetectionState.Data: + //Console.WriteLine("JVC Data: {0}", timingData[i]); + + if (pulse && duration >= 450 && duration <= 650) + { + JVC_Data.HalfBit = 1; + ignored = false; + } + else if (!pulse && duration >= 450 && duration <= 650 && JVC_Data.HalfBit == 1) + { + JVC_Data.Code <<= 1; + JVC_Data.Bit++; + JVC_Data.HalfBit = 0; + ignored = false; + } + else if (!pulse && duration >= 1450 && duration <= 1700 && JVC_Data.HalfBit == 1) + { + JVC_Data.Code <<= 1; + JVC_Data.Code |= 1; + JVC_Data.Bit++; + JVC_Data.HalfBit = 0; + ignored = false; + } + else if (!pulse && duration >= 10000) + { + if (JVC_Data.Bit == 16) + { + bool first = false; + if (JVC_Data.Code != JVC_Data.Toggle) + first = true; + + remoteCallback(IrProtocol.JVC, JVC_Data.Code, first); + ignored = false; + + JVC_Data.Toggle = (int)JVC_Data.Code; + + if (duration > 25000) + JVC_Data.State = RemoteDetectionState.HeaderPulse; + else + JVC_Data.State = RemoteDetectionState.Data; + + JVC_Data.HalfBit = 0; + JVC_Data.Bit = 0; + JVC_Data.Code = 0; + } + else if (JVC_Data.Bit == 32) + { + remoteCallback(IrProtocol.Unknown, JVC_Data.Code, false); + } + else + { + //Console.WriteLine("JVC Error"); + } + + } + else + { + //Console.WriteLine("JVC Error"); + } + + break; + #endregion Data + + } + + if (ignored && (JVC_Data.State != RemoteDetectionState.HeaderPulse)) + JVC_Data.State = RemoteDetectionState.HeaderPulse; + } + } + static void DetectMatsushita(int[] timingData, RemoteCallback remoteCallback) + { + for (int i = 0; i < timingData.Length; i++) + { + int duration = Math.Abs(timingData[i]); + bool pulse = (timingData[i] > 0); + bool ignored = true; + + switch (Matsushita_Data.State) + { + + #region HeaderPulse + case RemoteDetectionState.HeaderPulse: + //Console.WriteLine("Matsushita HeaderPulse: {0}, {1}", pulse, duration); + + if (pulse && duration >= 3300 && duration <= 3700) + { + Matsushita_Data.State = RemoteDetectionState.HeaderSpace; + ignored = false; + } + //else + //Console.WriteLine("HeaderPulse fall through"); + + break; + #endregion HeaderPulse + + #region HeaderSpace + case RemoteDetectionState.HeaderSpace: + //Console.WriteLine("Matsushita HeaderSpace: {0}, {1}", pulse, duration); + + if (!pulse && duration >= 3300 && duration <= 3700) + { + Matsushita_Data.State = RemoteDetectionState.Data; + Matsushita_Data.HalfBit = 0; + Matsushita_Data.Bit = 0; + Matsushita_Data.Code = 0; + ignored = false; + } + //else + //Console.WriteLine("HeaderSpace fell through"); + + break; + #endregion HeaderSpace + + #region Data + case RemoteDetectionState.Data: + //Console.Write("MData: {0}, {1}\t", pulse, duration); + + if (pulse && duration >= 650 && duration <= 1050) + { + Matsushita_Data.HalfBit = 1; + ignored = false; + } + else if (!pulse && duration >= 650 && duration <= 1050 && Matsushita_Data.HalfBit == 1) + { + Matsushita_Data.Code <<= 1; + Matsushita_Data.Bit++; + Matsushita_Data.HalfBit = 0; + ignored = false; + } + else if (!pulse && duration >= 2450 && duration <= 2850 && Matsushita_Data.HalfBit == 1) + { + Matsushita_Data.Code <<= 1; + Matsushita_Data.Code |= 1; + Matsushita_Data.Bit++; + Matsushita_Data.HalfBit = 0; + ignored = false; + } + else if (!pulse && duration >= 20000 && Matsushita_Data.HalfBit == 1) + { + if (Matsushita_Data.Bit != 22) + break; + + uint code = Matsushita_Data.Code >> 12; + remoteCallback(IrProtocol.Matsushita, code, false); + Matsushita_Data.State = RemoteDetectionState.HeaderPulse; + Matsushita_Data.HalfBit = 0; + ignored = false; + } + else + { + //Console.WriteLine("Matsushita Error"); + } + + break; + #endregion Data + + } + + if (ignored && (Matsushita_Data.State != RemoteDetectionState.HeaderPulse)) + { + //Console.WriteLine("ignored"); + Matsushita_Data.State = RemoteDetectionState.HeaderPulse; + } + } + } + static void DetectMitsubishi(int[] timingData, RemoteCallback remoteCallback) + { + for (int i = 0; i < timingData.Length; i++) + { + int duration = Math.Abs(timingData[i]); + bool pulse = (timingData[i] > 0); + bool ignored = true; + + switch (Mitsubishi_Data.State) + { + + #region HeaderPulse + case RemoteDetectionState.HeaderPulse: + //Console.WriteLine("Mitsubishi HeaderPulse: {0}, {1}", pulse, duration); + + if (pulse && duration >= 7800 && duration <= 8200) + { + Mitsubishi_Data.State = RemoteDetectionState.HeaderSpace; + ignored = false; + } + //else + //Console.WriteLine("HeaderPulse fall through"); + + break; + #endregion HeaderPulse + + #region HeaderSpace + case RemoteDetectionState.HeaderSpace: + //Console.WriteLine("Mitsubishi HeaderSpace: {0}, {1}", pulse, duration); + + if (!pulse && duration >= 3800 && duration <= 4200) + { + Mitsubishi_Data.State = RemoteDetectionState.Data; + Mitsubishi_Data.HalfBit = 0; + Mitsubishi_Data.Bit = 0; + Mitsubishi_Data.Code = 0; + ignored = false; + } + //else + //Console.WriteLine("HeaderSpace fell through"); + + break; + #endregion HeaderSpace + + #region Data + case RemoteDetectionState.Data: + //Console.Write("MData: {0}, {1}\t", pulse, duration); + + if (pulse && duration >= 350 && duration <= 650) + { + Mitsubishi_Data.HalfBit = 1; + ignored = false; + } + else if (!pulse && duration >= 350 && duration <= 650 && Mitsubishi_Data.HalfBit == 1) + { + Mitsubishi_Data.Code <<= 1; + Mitsubishi_Data.Bit++; + Mitsubishi_Data.HalfBit = 0; + ignored = false; + } + else if (!pulse && duration >= 1300 && duration <= 1700 && Mitsubishi_Data.HalfBit == 1) + { + Mitsubishi_Data.Code <<= 1; + Mitsubishi_Data.Code |= 1; + Mitsubishi_Data.Bit++; + Mitsubishi_Data.HalfBit = 0; + ignored = false; + } + else if (!pulse && duration >= 3800 && duration <= 4200 && Mitsubishi_Data.HalfBit == 1 && Mitsubishi_Data.Bit == 8) + { + Mitsubishi_Data.HalfBit = 0; + ignored = false; + } + else if (!pulse && duration >= 20000 && Mitsubishi_Data.HalfBit == 1 && Mitsubishi_Data.Bit == 16) + { + remoteCallback(IrProtocol.Mitsubishi, Mitsubishi_Data.Code, false); + Mitsubishi_Data.State = RemoteDetectionState.HeaderPulse; + Mitsubishi_Data.HalfBit = 0; + ignored = false; + } + else + { + Console.WriteLine("Mitsubishi Error"); + } + + break; + #endregion Data + + } + + if (ignored && (Mitsubishi_Data.State != RemoteDetectionState.HeaderPulse)) + { + Console.WriteLine("ignored"); + Mitsubishi_Data.State = RemoteDetectionState.HeaderPulse; + } + } + } + static void DetectNEC(int[] timingData, RemoteCallback remoteCallback) + { + for (int i = 0; i < timingData.Length; i++) + { + int duration = Math.Abs(timingData[i]); + bool pulse = (timingData[i] > 0); + bool ignored = true; + + switch (NEC_Data.State) + { + + #region HeaderPulse + case RemoteDetectionState.HeaderPulse: + //Console.WriteLine("NEC HeaderPulse: {0}", timingData[i]); + + if (pulse && duration >= 8800 && duration <= 9200) + { + NEC_Data.State = RemoteDetectionState.HeaderSpace; + ignored = false; + } + + break; + #endregion HeaderPulse + + #region HeaderSpace + case RemoteDetectionState.HeaderSpace: + //Console.WriteLine("NEC HeaderSpace: {0}", timingData[i]); + + if (!pulse && duration >= 4300 && duration <= 4700) + { + NEC_Data.State = RemoteDetectionState.Data; + NEC_Data.HalfBit = 0; + NEC_Data.Bit = 0; + NEC_Data.Code = 0; + ignored = false; + } + else if (!pulse && duration >= 2050 && duration <= 2450) // For Repeats + { + //Console.Write("Repeat"); + + if (NEC_Data.Code != 0) + { + uint address = (NEC_Data.Code >> 24) & 0xFF; + uint command = (NEC_Data.Code >> 8) & 0xFF; + + uint code = (address << 8) + command; + + //Console.WriteLine(" Code: {0}", code); + + remoteCallback(IrProtocol.NEC, code, false); + + NEC_Data.State = RemoteDetectionState.Leading; + ignored = false; + } + //else + //Console.WriteLine("Code = 0 fell through"); + } + + break; + #endregion HeaderSpace + + #region Data + case RemoteDetectionState.Data: + //Console.WriteLine("NEC Data: {0}", timingData[i]); + + if (pulse && duration >= 350 && duration <= 750) + { + NEC_Data.HalfBit = 1; + ignored = false; + } + else if (!pulse && duration >= 350 && duration <= 650 && NEC_Data.HalfBit == 1) + { + NEC_Data.Code <<= 1; + NEC_Data.Bit++; + NEC_Data.HalfBit = 0; + ignored = false; + } + else if (!pulse && duration >= 1200 && duration <= 2800 && NEC_Data.HalfBit == 1) + { + NEC_Data.Code <<= 1; + NEC_Data.Code |= 1; + NEC_Data.Bit++; + NEC_Data.HalfBit = 0; + ignored = false; + } + else if (!pulse && duration >= 12000) + { + if (NEC_Data.Bit != 32) + { + if (NEC_Data.Code != 0) + { + //Console.WriteLine("Invalid NEC: {0}bit, {1:X}", NEC_Data.Bit, NEC_Data.Code); + remoteCallback(IrProtocol.Unknown, NEC_Data.Code, false); + } + break; + } + + uint address = (NEC_Data.Code >> 24) & 0xFF; + uint notAddress = (NEC_Data.Code >> 16) & 0xFF; + + uint command = (NEC_Data.Code >> 8) & 0xFF; + uint notCommand = NEC_Data.Code & 0xFF; + + if ((address + notAddress == 0xFF) && (command + notCommand == 0xFF)) + { + uint code = (address << 8) + command; + remoteCallback(IrProtocol.NEC, code, true); + NEC_Data.State = RemoteDetectionState.HeaderPulse; + ignored = false; + } + else + { + //Console.WriteLine("Invalid NEC: {0:X}", NEC_Data.Code); + remoteCallback(IrProtocol.Unknown, NEC_Data.Code, false); + } + } + else + { + //Console.WriteLine("NEC Error"); + } + + break; + #endregion Data + + #region Leading + case RemoteDetectionState.Leading: + Console.WriteLine("NEC Leading: {0}", timingData[i]); + + // For Repeats + if (pulse && duration >= 400 && duration <= 800) + { + ignored = false; + } + else if (!pulse && duration > 10000) // Repeats + { + ignored = false; + NEC_Data.State = RemoteDetectionState.HeaderPulse; + } + + break; + #endregion Leading + + } + + if (ignored && (NEC_Data.State != RemoteDetectionState.HeaderPulse)) + NEC_Data.State = RemoteDetectionState.HeaderPulse; + } + } + static void DetectNRC17(int[] timingData, RemoteCallback remoteCallback) + { + for (int i = 0; i < timingData.Length; i++) + { + int duration = Math.Abs(timingData[i]); + bool pulse = (timingData[i] > 0); + bool ignored = true; + + switch (NRC17_Data.State) + { + + #region HeaderPulse + case RemoteDetectionState.HeaderPulse: + //Console.WriteLine("NRC17 HeaderPulse: {0}", timingData[i]); + + if (pulse && (duration >= 400) && (duration <= 650)) + { + NRC17_Data.State = RemoteDetectionState.HeaderSpace; + ignored = false; + } + break; + #endregion HeaderPulse + + #region HeaderSpace + case RemoteDetectionState.HeaderSpace: + //Console.WriteLine("NRC17 HeaderSpace: {0}", timingData[i]); + + if (!pulse && + (((duration >= 2350) && (duration <= 2600)) || // Normal battery + ((duration >= 3350) && (duration <= 3600)))) // Low battery + { + NRC17_Data.State = RemoteDetectionState.Data; + NRC17_Data.HalfBit = 0; + NRC17_Data.Bit = 17; + NRC17_Data.Header = 0; + NRC17_Data.Code = 0; + ignored = false; + } + break; + #endregion HeaderSpace + + #region Data + case RemoteDetectionState.Data: + //Console.WriteLine("NRC17 Data: {0}", timingData[i]); + + if (NRC17_Data.HalfBit == 0) + { + if (pulse && (duration >= 300) && (duration <= 700)) + { + // Logic 1 + NRC17_Data.HalfBit = 1; + NRC17_Data.Code |= (uint)(1 << NRC17_Data.Bit--); + ignored = false; + } + else if (!pulse && (duration >= 300) && (duration <= 700)) + { + // Logic 0 + NRC17_Data.HalfBit = 1; + NRC17_Data.Bit--; + ignored = false; + } + } + else + { + if (!pulse && (duration >= 300) && (duration <= 700)) + { + NRC17_Data.HalfBit = 0; + ignored = false; + } + else if (pulse && (duration >= 300) && (duration <= 700)) + { + NRC17_Data.HalfBit = 0; + ignored = false; + } + else if (!pulse && (duration >= 800) && (duration <= 1200)) + { + NRC17_Data.HalfBit = 1; + NRC17_Data.Bit--; + ignored = false; + } + else if (pulse && (duration >= 800) && (duration <= 1200)) + { + NRC17_Data.HalfBit = 1; + NRC17_Data.Code |= (uint)(1 << NRC17_Data.Bit--); + ignored = false; + } + } + + if (NRC17_Data.Bit == 0) + { + NRC17_Data.Code &= 0xFFFF; // 16-bits (Ignore leading bit which is always 1) + remoteCallback(IrProtocol.NRC17, NRC17_Data.Code, false); + + //Console.WriteLine("NRC17: {0}", NRC17_Data.Code); + + NRC17_Data.State = RemoteDetectionState.HeaderPulse; + } + + break; + #endregion Data + + } + + if (ignored && (NRC17_Data.State != RemoteDetectionState.HeaderPulse)) + NRC17_Data.State = RemoteDetectionState.HeaderPulse; + } + } + static void DetectPanasonic(int[] timingData, RemoteCallback remoteCallback) + { + for (int i = 0; i < timingData.Length; i++) + { + int duration = Math.Abs(timingData[i]); + bool pulse = (timingData[i] > 0); + bool ignored = true; + + switch (Panasonic_Data.State) + { + + #region HeaderPulse + case RemoteDetectionState.HeaderPulse: + //Console.WriteLine("Panasonic HeaderPulse: {0}", timingData[i]); + + if (pulse && duration >= 3150 && duration <= 3900) + { + Panasonic_Data.State = RemoteDetectionState.HeaderSpace; + ignored = false; + } + //else + //Console.WriteLine("HeaderPulse fall through"); + + break; + #endregion HeaderPulse + + #region HeaderSpace + case RemoteDetectionState.HeaderSpace: + //Console.WriteLine("Panasonic HeaderSpace: {0}", timingData[i]); + + if (!pulse && duration >= 3150 && duration <= 3900) + { + Panasonic_Data.State = RemoteDetectionState.Data; + Panasonic_Data.HalfBit = 0; + Panasonic_Data.Bit = 0; + Panasonic_Data.Code = 0; + ignored = false; + } + else if (!pulse && duration >= 2050 && duration <= 2450) // For Repeats + { + //Console.Write("Repeat"); + + if (Panasonic_Data.Code != 0) + { + uint address = (Panasonic_Data.Code >> 24) & 0xFF; + uint command = (Panasonic_Data.Code >> 8) & 0xFF; + + uint code = (address << 8) + command; + + //Console.WriteLine(" Code: {0}", code); + + remoteCallback(IrProtocol.Panasonic, code, false); + + Panasonic_Data.State = RemoteDetectionState.Leading; + ignored = false; + } + //else + //Console.WriteLine("Code = 0 fell through"); + } + //else + //Console.WriteLine("HeaderSpace fell through"); + + break; + #endregion HeaderSpace + + #region Data + case RemoteDetectionState.Data: + //Console.WriteLine("Panasonic Data: {0}", timingData[i]); + + if (pulse && duration >= 600 && duration <= 1150) + { + Panasonic_Data.HalfBit = 1; + ignored = false; + } + else if (!pulse && duration >= 600 && duration <= 1150 && Panasonic_Data.HalfBit == 1) + { + Panasonic_Data.Code <<= 1; + Panasonic_Data.Bit++; + Panasonic_Data.HalfBit = 0; + ignored = false; + } + else if (!pulse && duration >= 1800 && duration <= 3450 && Panasonic_Data.HalfBit == 1) + { + Panasonic_Data.Code <<= 1; + Panasonic_Data.Code |= 1; + Panasonic_Data.Bit++; + Panasonic_Data.HalfBit = 0; + ignored = false; + } + else if (!pulse && duration >= 8000) + { + if (Panasonic_Data.Bit != 22) + break; + + + uint custom = (Panasonic_Data.Code >> 17) & 0x1F; + uint data = (Panasonic_Data.Code >> 11) & 0x3F; + + uint notCustom = (Panasonic_Data.Code >> 6) & 0x1F; + uint notData = Panasonic_Data.Code & 0x3F; + + if ((custom + notCustom == 0x1F) && (data + notData == 0x3F)) + { + uint code = (custom << 8) + data; + remoteCallback(IrProtocol.Panasonic, code, true); + Panasonic_Data.State = RemoteDetectionState.HeaderPulse; + ignored = false; + } + else + { + Console.WriteLine("custom != notCustom || data != notData fall through"); + Console.WriteLine("{0:X}", Panasonic_Data.Code); + } + } + else + { + //Console.WriteLine("Panasonic Error"); + } + + break; + #endregion Data + + #region Leading + case RemoteDetectionState.Leading: + //Console.WriteLine("Panasonic Leading: {0}", timingData[i]); + + // For Repeats + if (pulse && duration >= 400 && duration <= 800) + { + ignored = false; + } + else if (!pulse && duration >= 38000 && duration <= 40000) // First Repeat + { + ignored = false; + Panasonic_Data.State = RemoteDetectionState.HeaderPulse; + } + else if (!pulse && duration >= 94600 && duration <= 95000) // Multiple Repeats + { + ignored = false; + Panasonic_Data.State = RemoteDetectionState.HeaderPulse; + } + //else + //Console.WriteLine("Leading fall through"); + + break; + #endregion Leading + + } + + if (ignored && (Panasonic_Data.State != RemoteDetectionState.HeaderPulse)) + { + //Console.WriteLine("Panasonic Ignored"); + Panasonic_Data.State = RemoteDetectionState.HeaderPulse; + } + } + } + static void DetectRC5(int[] timingData, RemoteCallback remoteCallback) + { + for (int i = 0; i < timingData.Length; i++) + { + int duration = Math.Abs(timingData[i]); + bool pulse = (timingData[i] > 0); + bool ignored = true; + + switch (RC5_Data.State) + { + + #region HeaderPulse + case RemoteDetectionState.HeaderPulse: + //Console.WriteLine("RC5 HeaderPulse: {0}", timingData[i]); + + if (pulse) + { + if ((duration >= 750) && (duration <= 1100)) + { + RC5_Data.State = RemoteDetectionState.HeaderSpace; + RC5_Data.Bit = 13; + RC5_Data.Code = (uint)1 << RC5_Data.Bit; + ignored = false; + } + else if ((duration >= 1500) && (duration <= 2000)) + { + RC5_Data.State = RemoteDetectionState.Data; + RC5_Data.Bit = 13; + RC5_Data.Code = (uint)1 << RC5_Data.Bit; + RC5_Data.HalfBit = 0; + ignored = false; + } + } + break; + #endregion HeaderPulse + + #region HeaderSpace + case RemoteDetectionState.HeaderSpace: + //Console.WriteLine("RC5 HeaderSpace: {0}", timingData[i]); + + if (!pulse && (duration >= 750) && (duration <= 1000)) + { + RC5_Data.State = RemoteDetectionState.Data; + RC5_Data.HalfBit = 0; + ignored = false; + } + break; + #endregion HeaderSpace + + #region Data + case RemoteDetectionState.Data: + //Console.WriteLine("RC5 Data: {0}", timingData[i]); + + if (RC5_Data.HalfBit == 0) + { + if (pulse) + { + if (((duration >= 750) && (duration <= 1100)) || ((duration >= 1500) && (duration <= 2000))) + { + RC5_Data.HalfBit = (byte)((duration >= 1500) ? 0 : 1); + RC5_Data.Bit--; + RC5_Data.Code |= (uint)1 << RC5_Data.Bit; + ignored = false; + + if ((RC5_Data.Bit == 0) || ((RC5_Data.Bit == 1) && (duration >= 1500))) + RC5_Data.State = RemoteDetectionState.KeyCode; + } + else + { + //Console.WriteLine("RC5 Error: {0} on bit {1}", timingData[i], RC5_Data.Bit); + } + } + else + { + if (((duration >= 750) && (duration <= 1100)) || ((duration >= 1500) && (duration <= 2000))) + { + RC5_Data.HalfBit = (byte)((duration >= 1500) ? 0 : 1); + RC5_Data.Bit--; + ignored = false; + + if (RC5_Data.Bit == 0) + RC5_Data.State = RemoteDetectionState.KeyCode; + } + else if ((RC5_Data.Bit == 7) && (((duration >= 4300) && (duration <= 4700)) || ((duration >= 5200) && (duration <= 5600)))) + { + ignored = false; + RC5_Data.HalfBit = (byte)((duration >= 5200) ? 0 : 1); + RC5_Data.Code <<= 6; + RC5_Data.Bit += 5; + } + else + { + //Console.WriteLine("RC5 Space Error: {0} on bit {1}", timingData[i], RC5_Data.Bit); + } + } + break; + } + + if ((duration >= 750) && (duration <= 1100)) + { + RC5_Data.HalfBit = 0; + ignored = false; + + if ((RC5_Data.Bit == 1) && pulse) + RC5_Data.State = RemoteDetectionState.KeyCode; + } + else if ((RC5_Data.Bit == 7) && (((duration >= 3400) && (duration <= 3800)) || ((duration >= 4300) && (duration <= 4700)))) + { + RC5_Data.HalfBit = (byte)((duration >= 4300) ? 0 : 1); + RC5_Data.Code <<= 6; + RC5_Data.Bit += 6; + ignored = false; + } + else + { + //Console.WriteLine("RC5 Duration Error: {0} on bit {1}", timingData[i], RC5_Data.Bit); + } + break; + #endregion Data + + #region Leading + case RemoteDetectionState.Leading: + //Console.WriteLine("RC5 Leading: {0}", timingData[i]); + + if (pulse) + break; + + if (duration > 10000) + { + RC5_Data.State = RemoteDetectionState.HeaderPulse; + ignored = false; + } + break; + #endregion Leading + + } + + if (RC5_Data.State == RemoteDetectionState.KeyCode) + { + bool toggleOn; + + bool first = true; + bool RC5X; + + if (RC5_Data.Code > 0xFFFF) // RC5X + { + toggleOn = ((RC5_Data.Code & ToggleBitRC5X) == ToggleBitRC5X); + RC5_Data.Code &= ToggleMaskRC5X; + RC5X = true; + } + else // RC5 + { + toggleOn = ((RC5_Data.Code & ToggleBitRC5) == ToggleBitRC5); + RC5_Data.Code &= ToggleMaskRC5; + RC5X = false; + } + + if ((toggleOn && RC5_Data.Toggle == 1) || (!toggleOn && RC5_Data.Toggle == 2)) + first = false; + + RC5_Data.Toggle = toggleOn ? 1 : 2; + + if (RC5X) + remoteCallback(IrProtocol.RC5X, RC5_Data.Code, first); + else + remoteCallback(IrProtocol.RC5, RC5_Data.Code, first); + + RC5_Data.State = RemoteDetectionState.HeaderPulse; + } + + if (ignored && (RC5_Data.State != RemoteDetectionState.Leading) && (RC5_Data.State != RemoteDetectionState.HeaderPulse)) + RC5_Data.State = RemoteDetectionState.HeaderPulse; + } + + } + static void DetectRC6(int[] timingData, RemoteCallback remoteCallback) + { + for (int i = 0; i < timingData.Length; i++) + { + int duration = Math.Abs(timingData[i]); + bool pulse = (timingData[i] > 0); + bool ignored = true; + + switch (RC6_Data.State) + { + + #region HeaderPulse + case RemoteDetectionState.HeaderPulse: + //Console.WriteLine("RC6 HeaderPulse: {0}", timingData[i]); + + if (pulse && (duration >= 2600) && (duration <= 3300)) + { + RC6_Data.State = RemoteDetectionState.HeaderSpace; + RC6_Data.Header = 0x000FC000; + RC6_Data.Bit = 14; + RC6_Data.HalfBit = 0; + RC6_Data.Code = 0; + RC6_Data.LongPulse = false; + RC6_Data.LongSpace = false; + RC6_Data.Toggle &= 0xFE; + ignored = false; + } + break; + #endregion HeaderPulse + + #region HeaderSpace + case RemoteDetectionState.HeaderSpace: + //Console.WriteLine("RC6 HeaderSpace: {0}", timingData[i]); + + if (!pulse && (duration >= 750) && (duration <= 1000)) + { + RC6_Data.State = RemoteDetectionState.PreData; + RC6_Data.Bit -= 2; + ignored = false; + } + break; + #endregion HeaderSpace + + #region PreData + case RemoteDetectionState.PreData: + //Console.WriteLine("RC6 PreData: {0}", timingData[i]); + + if (pulse) + { + if ((duration >= 300) && (duration <= 600)) + { + ignored = false; + if (RC6_Data.Bit != 0) RC6_Data.Header |= (uint)(1 << --RC6_Data.Bit); + } + else if ((duration >= 750) && (duration <= 1000)) + { + ignored = false; + if (RC6_Data.Bit != 0) RC6_Data.Header |= (uint)(1 << --RC6_Data.Bit); + if (RC6_Data.Bit != 0) RC6_Data.Header |= (uint)(1 << --RC6_Data.Bit); + } + else if ((duration >= 1200) && (duration <= 1600)) + { + ignored = false; + if (RC6_Data.Bit != 0) RC6_Data.Header |= (uint)(1 << --RC6_Data.Bit); + if (RC6_Data.Bit != 0) RC6_Data.Header |= (uint)(1 << --RC6_Data.Bit); + if (RC6_Data.Bit != 0) RC6_Data.Header |= (uint)(1 << --RC6_Data.Bit); + else + { + RC6_Data.HalfBit = 1; + RC6_Data.LongPulse = true; + } + } + else + { + //Console.WriteLine(string.Format("RC6 Error Bit {0} {1} {2}", RC6_Data.Bit, pulse ? "Pulse" : "Space", duration)); + } + } + else + { + if ((duration >= 300) && (duration <= 600)) + { + RC6_Data.Bit--; + ignored = false; + } + else if ((duration >= 750) && (duration <= 1000)) + { + ignored = false; + if (RC6_Data.Bit > 2) + RC6_Data.Bit -= 2; + else + RC6_Data.Bit = 0; + } + else if ((duration >= 1200) && (duration... [truncated message content] |