├── icon.xcf ├── offsets.txt ├── SharpOsc └── SharpOSC.dll ├── rbBeatDetect ├── icon.ico ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── App.config ├── packages.config ├── Program.cs ├── OscClient.cs ├── FileManager.cs ├── MemoryReader.cs ├── rbBeatDetect.csproj ├── VersionManager.cs ├── Menu.cs └── Menu.Designer.cs ├── RekordboxMemoryScanning.pdf ├── Kethsar_RekordboxReaderGuide_MIRROR.pdf ├── .gitignore ├── rbBeatDetect.sln ├── pyrekordbox_extractor.py ├── README.md └── offsets.json /icon.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palmarci/rbBeatDetect/HEAD/icon.xcf -------------------------------------------------------------------------------- /offsets.txt: -------------------------------------------------------------------------------- 1 | 6.5.1;0x03ff44a8;0x04006EB0;0x200,0x19C 2 | 6.6.4;0x03f72180;0x03F85360;0x30,0x19C 3 | -------------------------------------------------------------------------------- /SharpOsc/SharpOSC.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palmarci/rbBeatDetect/HEAD/SharpOsc/SharpOSC.dll -------------------------------------------------------------------------------- /rbBeatDetect/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palmarci/rbBeatDetect/HEAD/rbBeatDetect/icon.ico -------------------------------------------------------------------------------- /RekordboxMemoryScanning.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palmarci/rbBeatDetect/HEAD/RekordboxMemoryScanning.pdf -------------------------------------------------------------------------------- /Kethsar_RekordboxReaderGuide_MIRROR.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/palmarci/rbBeatDetect/HEAD/Kethsar_RekordboxReaderGuide_MIRROR.pdf -------------------------------------------------------------------------------- /rbBeatDetect/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | #Ignore thumbnails created by Windows 3 | Thumbs.db 4 | #Ignore files built by Visual Studio 5 | *.obj 6 | *.exe 7 | *.pdb 8 | *.user 9 | *.aps 10 | *.pch 11 | *.vspscc 12 | *_i.c 13 | *_p.c 14 | *.ncb 15 | *.suo 16 | *.tlb 17 | *.tlh 18 | *.bak 19 | *.cache 20 | *.ilk 21 | *.log 22 | [Bb]in 23 | [Dd]ebug*/ 24 | *.lib 25 | *.sbr 26 | obj/ 27 | [Rr]elease*/ 28 | _ReSharper*/ 29 | [Tt]est[Rr]esult* 30 | .vs/ 31 | #Nuget packages folder 32 | packages/ 33 | -------------------------------------------------------------------------------- /rbBeatDetect/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /rbBeatDetect/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /rbBeatDetect/Program.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Net; 8 | using System.Runtime.InteropServices; 9 | using System.Text; 10 | using System.Text.RegularExpressions; 11 | using System.Threading.Tasks; 12 | using System.Windows.Forms; 13 | using static rbBeatDetect.VersionManager; 14 | 15 | namespace rbBeatDetect 16 | { 17 | 18 | 19 | static class Program 20 | { 21 | 22 | [STAThread] 23 | 24 | static void Main() 25 | { 26 | try 27 | { 28 | 29 | FileManager.initialize(); 30 | Application.EnableVisualStyles(); 31 | Application.SetCompatibleTextRenderingDefault(false); 32 | Application.Run(new Menu()); 33 | } catch (Exception e) { //bit sketchy lol 34 | FileManager.log(e.ToString()); 35 | throw; 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /rbBeatDetect/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace rbBeatDetect.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rbBeatDetect/OscClient.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using SharpOSC; 8 | using System.Threading; 9 | 10 | namespace rbBeatDetect 11 | { 12 | public class OscClient 13 | { 14 | 15 | OscMessage onMsg; 16 | OscMessage offMsg; 17 | UDPSender sender; 18 | bool mimicHuman; 19 | int humanDelay; 20 | int delay; 21 | 22 | public OscClient(IPAddress Ip, int Port, string Path, bool MimicHuman, int HumanDelay, int Delay) 23 | { 24 | 25 | 26 | mimicHuman = MimicHuman; 27 | onMsg = new OscMessage($"/{Path}", 1.0f); 28 | offMsg = new OscMessage($"/{Path}", 0.0f); 29 | sender = new UDPSender(Ip.ToString(), Port); 30 | humanDelay = HumanDelay; 31 | delay = Delay; 32 | 33 | } 34 | 35 | public void sendMsg() 36 | { 37 | 38 | if (delay > 0) 39 | { 40 | Thread.Sleep(delay); 41 | } 42 | 43 | sender.Send(onMsg); 44 | 45 | if (mimicHuman) 46 | { 47 | Thread.Sleep(humanDelay); 48 | sender.Send(offMsg); 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /rbBeatDetect.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30621.155 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "rbBeatDetect", "rbBeatDetect\rbBeatDetect.csproj", "{AF8AB790-2874-449E-8C03-2FBE76879856}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Release|Any CPU = Release|Any CPU 13 | Release|x64 = Release|x64 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {AF8AB790-2874-449E-8C03-2FBE76879856}.Debug|Any CPU.ActiveCfg = Debug|x64 17 | {AF8AB790-2874-449E-8C03-2FBE76879856}.Debug|x64.ActiveCfg = Debug|x64 18 | {AF8AB790-2874-449E-8C03-2FBE76879856}.Debug|x64.Build.0 = Debug|x64 19 | {AF8AB790-2874-449E-8C03-2FBE76879856}.Release|Any CPU.ActiveCfg = Release|x64 20 | {AF8AB790-2874-449E-8C03-2FBE76879856}.Release|x64.ActiveCfg = Release|x64 21 | {AF8AB790-2874-449E-8C03-2FBE76879856}.Release|x64.Build.0 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | GlobalSection(ExtensibilityGlobals) = postSolution 27 | SolutionGuid = {F94F1922-A140-4C34-91A4-1E9DD06AD622} 28 | EndGlobalSection 29 | EndGlobal 30 | -------------------------------------------------------------------------------- /pyrekordbox_extractor.py: -------------------------------------------------------------------------------- 1 | from pyrekordbox import Rekordbox6Database, show_config 2 | from pyrekordbox.anlz import AnlzFile, is_anlz_file 3 | import os 4 | import sys 5 | import pyrekordbox 6 | 7 | def dump(obj): 8 | attrs = vars(obj) 9 | print(', '.join("%s: %s" % item for item in attrs.items())) 10 | 11 | def main(): 12 | print("rekordbox config:") 13 | show_config() 14 | app_dir = pyrekordbox.config.get_pioneer_app_dir() 15 | db = Rekordbox6Database() 16 | db_content = db.get_content() 17 | song = db_content[0] 18 | print("song info:") 19 | dump(song) 20 | 21 | 22 | dat_path = os.path.join(app_dir, "rekordbox", "share", song.AnalysisDataPath.strip("/").replace("/", "\\")) 23 | ext_path = dat_path.replace(".DAT", ".EXT") 24 | print(f"dat_path path: {dat_path}") 25 | print(f"ext_path path: {ext_path}") 26 | 27 | if not is_anlz_file(dat_path): 28 | raise Exception("dat file is not a valid anlz file") 29 | 30 | if not is_anlz_file(ext_path): 31 | raise Exception("ext file is not a valid anlz file") 32 | 33 | dat = AnlzFile.parse_file(dat_path) 34 | ext = AnlzFile.parse_file(ext_path) 35 | print(f"dat contents: {dat}") 36 | print(f"ext contents: {ext}") 37 | 38 | song_structure = ext.getall("PSSI")[0] 39 | print(f"mood: {song_structure.mood}, bank: {song_structure.bank}, entries: {song_structure.len_entries}") 40 | for i in song_structure.entries: 41 | print(f"index: {i.index}, start: {i.beat}, kind: {i.kind}") 42 | 43 | if __name__ == "__main__": 44 | main() -------------------------------------------------------------------------------- /rbBeatDetect/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("rbBeatDetect")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("rbBeatDetect")] 13 | [assembly: AssemblyCopyright("Copyright © 2022")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("af8ab790-2874-449e-8c03-2fbe76879856")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("2.2.0.0")] 36 | [assembly: AssemblyFileVersion("2.2.0.0")] 37 | -------------------------------------------------------------------------------- /rbBeatDetect/FileManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using static rbBeatDetect.VersionManager; 8 | 9 | namespace rbBeatDetect 10 | { 11 | class FileManager 12 | { 13 | 14 | public static String dataFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\rbBeatDetect\"; 15 | public static String offsetBackupPath = dataFolderPath + "offsets.bak"; 16 | public static String logFilePath = dataFolderPath + "log.txt"; 17 | 18 | public static void initialize() 19 | { 20 | if (!Directory.Exists(dataFolderPath)) 21 | { 22 | Directory.CreateDirectory(dataFolderPath); 23 | } 24 | 25 | if (File.Exists(logFilePath)) 26 | { 27 | File.Delete(logFilePath); 28 | } 29 | 30 | File.Create(logFilePath).Dispose(); 31 | log("program started at " + DateTime.Now); 32 | 33 | } 34 | 35 | public static void log(String msg) 36 | { 37 | Console.WriteLine(msg); 38 | StringBuilder sb = new StringBuilder(); 39 | sb.Append(msg + "\r\n"); 40 | File.AppendAllText(logFilePath, sb.ToString()); 41 | sb.Clear(); 42 | } 43 | 44 | public static string readBackupOffsets() 45 | { 46 | return File.ReadAllText(offsetBackupPath); 47 | 48 | } 49 | 50 | public static void writeBackupOffsets(string data) 51 | { 52 | 53 | using (StreamWriter sW = new StreamWriter(offsetBackupPath, false)) 54 | { 55 | sW.Write(data); 56 | } 57 | 58 | } 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # rbBeatDetect 3 | 4 | ![image](https://github.com/palmarci/rbBeatDetect/assets/20556689/9a423138-2347-4d83-8c1d-770344c1b812) 5 | 6 | ## What is this? 7 | This is a simple program to synchronize lights to rekordbox via OSC messages. The program scans the memory of the currently running rekordbox.exe and tracks the Master Deck's beat values. 8 | 9 | ## How to use this? 10 | 11 | 1. Make sure you have [.NET 4.7.2 ](https://dotnet.microsoft.com/en-us/download/dotnetframework/net472 " .NET 4.7.2 ") or newer installed. 12 | 2. Download the latest release from [this](https://github.com/palmarci/rbBeatDetect/releases "this") page. 13 | 3. Extract the contents to a directory and run the exe. 14 | 4. Run rekordbox and load a track to **every** deck. 15 | 5. Set the Master to a deck (any). 16 | 6. Run the program, configure your settings. 17 | 7. Check the "Running" box. 18 | 19 | ## FAQ 20 | - **What does the Mimic human keypress button do?** 21 | 22 | Some OSC clients (like QLC+) needs an ON and an OFF signal to register a keypress. This is exactly what this switch does. You can specify a delay (in ms) between those messages. 23 | 24 | - **What happens if I have no internet access on my computer?** 25 | 26 | The program won't be able to update the offsets on startup, so it will use the last cached version. I recommend trying this out for the first time with an internet connection. 27 | 28 | - **If I'm still running Windows 7?** 29 | 30 | The offset download may fail due to the obsolete SSL/TLS settings on your system. You can easily fix those problems following [this](https://stackoverflow.com/a/70674920/8921786) guide. 31 | 32 | ## How can i find the offsets? 33 | - [Guide](https://github.com/palmarci/rbBeatDetect/blob/main/RekordboxMemoryScanning.pdf) 34 | 35 | - [Offsets.json](https://raw.githubusercontent.com/palmarci/rbBeatDetect/main/offsets.json) 36 | 37 | - [other great source of information](https://github.com/Kethsar/RekordboxReader/blob/master/Finding%20Rekordbox%20Pointers.md) 38 | 39 | (do NOT use the offsets.txt file, its for the older versions only!) 40 | -------------------------------------------------------------------------------- /rbBeatDetect/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace rbBeatDetect.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("rbBeatDetect.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /offsets.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "version": { 4 | "mainVer": 6, 5 | "subVer": 5, 6 | "patchVer": 1 7 | }, 8 | "deckPointer": 67060904, 9 | "deckOffsets": [ 10 | [ 11 | 240, 12 | 40, 13 | 0 14 | ], 15 | [ 16 | 248, 17 | 40, 18 | 0 19 | ], 20 | [ 21 | 256, 22 | 40, 23 | 0 24 | ], 25 | [ 26 | 264, 27 | 40, 28 | 0 29 | ] 30 | ], 31 | "masterPointer": 67137200, 32 | "masterOffsets": [ 33 | 512, 34 | 412 35 | ], 36 | "endOffset": 9308 37 | }, 38 | { 39 | "version": { 40 | "mainVer": 6, 41 | "subVer": 6, 42 | "patchVer": 4 43 | }, 44 | "deckPointer": 66527616, 45 | "deckOffsets": [ 46 | [ 47 | 240, 48 | 40, 49 | 0 50 | ], 51 | [ 52 | 248, 53 | 40, 54 | 0 55 | ], 56 | [ 57 | 256, 58 | 40, 59 | 0 60 | ], 61 | [ 62 | 264, 63 | 40, 64 | 0 65 | ] 66 | ], 67 | "masterPointer": 66605920, 68 | "masterOffsets": [ 69 | 48, 70 | 412 71 | ], 72 | "endOffset": 9308 73 | }, 74 | { 75 | "version": { 76 | "mainVer": 6, 77 | "subVer": 7, 78 | "patchVer": 3 79 | }, 80 | "deckPointer": 70477616, 81 | "deckOffsets": [ 82 | [ 83 | 240, 84 | 40, 85 | 24 86 | ], 87 | [ 88 | 248, 89 | 40, 90 | 24 91 | ], 92 | [ 93 | 256, 94 | 40, 95 | 24 96 | ], 97 | [ 98 | 264, 99 | 40, 100 | 24 101 | ] 102 | ], 103 | "masterPointer": 70157680, 104 | "masterOffsets": [ 105 | 32, 106 | 640, 107 | 3560 108 | ], 109 | "endOffset": 9308 110 | }, 111 | { 112 | "version": { 113 | "mainVer": 6, 114 | "subVer": 6, 115 | "patchVer": 11 116 | }, 117 | "deckPointer": 69653808, 118 | "deckOffsets": [ 119 | [ 120 | 1872, 121 | 328, 122 | 8 123 | ], 124 | [ 125 | 1872, 126 | 336, 127 | 8 128 | ], 129 | [ 130 | 1880, 131 | 328, 132 | 8 133 | ], 134 | [ 135 | 1880, 136 | 336, 137 | 8 138 | ] 139 | ], 140 | "masterPointer": 69576472, 141 | "masterOffsets": [ 142 | 32, 143 | 640, 144 | 3560 145 | ], 146 | "endOffset": 9308 147 | } 148 | ] 149 | -------------------------------------------------------------------------------- /rbBeatDetect/MemoryReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Net; 6 | using System.Runtime.InteropServices; 7 | using System.Text; 8 | using System.Threading; 9 | using System.Threading.Tasks; 10 | using static rbBeatDetect.VersionManager; 11 | 12 | namespace rbBeatDetect 13 | { 14 | public class MemoryReader 15 | { 16 | 17 | private int maxErrors = 25; 18 | 19 | 20 | private readonly int PROCESS_WM_READ = 0x10; 21 | 22 | private IntPtr currentHandle = IntPtr.Zero; 23 | private IntPtr moduleBase = IntPtr.Zero; 24 | 25 | public Int64 masterAddress = 0; 26 | public List deckAdresses = new List { 0, 0, 0, 0 }; 27 | public int masterDeck = 0; 28 | public int currentBeatNr = 0; 29 | public bool isCrashed = false; 30 | private OscClient osc; 31 | private int errorCount = 0; 32 | 33 | [DllImport("kernel32.dll")] 34 | private static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId); 35 | 36 | [DllImport("kernel32.dll")] 37 | private static extern bool ReadProcessMemory(int hProcess, Int64 lpBaseAddress, byte[] lpBuffer, int dwSize, ref int lpNumberOfBytesRead); 38 | 39 | public MemoryReader(OffsetData offsetData, OscClient oscClient) 40 | { 41 | Process process = Process.GetProcessesByName("rekordbox")[0]; 42 | currentHandle = OpenProcess(PROCESS_WM_READ, false, process.Id); 43 | FileManager.log("current handle = " + currentHandle); 44 | isCrashed = false; 45 | 46 | foreach (ProcessModule m in process.Modules) 47 | { 48 | if (m.ModuleName == "rekordbox.exe") 49 | { 50 | moduleBase = m.BaseAddress; 51 | FileManager.log("modulebase = 0x" + moduleBase.ToString("X")); 52 | break; 53 | } 54 | } 55 | 56 | masterAddress = FindDMAAddy(IntPtr.Add(moduleBase, offsetData.masterPointer), offsetData.masterOffsets.ToArray()); 57 | deckAdresses[0] = FindDMAAddy(IntPtr.Add(moduleBase, offsetData.deckPointer), offsetData.deckOffsets[0].ToArray()) + offsetData.endOffset; 58 | deckAdresses[1] = FindDMAAddy(IntPtr.Add(moduleBase, offsetData.deckPointer), offsetData.deckOffsets[1].ToArray()) + offsetData.endOffset; 59 | deckAdresses[2] = FindDMAAddy(IntPtr.Add(moduleBase, offsetData.deckPointer), offsetData.deckOffsets[2].ToArray()) + offsetData.endOffset; 60 | deckAdresses[3] = FindDMAAddy(IntPtr.Add(moduleBase, offsetData.deckPointer), offsetData.deckOffsets[3].ToArray()) + offsetData.endOffset; 61 | FileManager.log("master address: " + masterAddress.ToString()); 62 | FileManager.log("0 deck addresses: " + deckAdresses[0]); 63 | 64 | 65 | //todo: rekordbox v5 compatibilty (0xb0, 0x158, +0x1C9C deck offset (???)) 66 | 67 | this.osc = oscClient; 68 | 69 | } 70 | 71 | private Int64 FindDMAAddy(IntPtr ptr, int[] offsets) 72 | { 73 | var buffer = new byte[IntPtr.Size]; 74 | 75 | foreach (int i in offsets) 76 | { 77 | int read = 0; 78 | ReadProcessMemory(currentHandle.ToInt32(), ptr.ToInt64(), buffer, buffer.Length, ref read); 79 | ptr = (IntPtr.Size == 4) ? IntPtr.Add(new IntPtr(BitConverter.ToInt32(buffer, 0)), i) : ptr = IntPtr.Add(new IntPtr(BitConverter.ToInt64(buffer, 0)), i); 80 | } 81 | return ptr.ToInt64(); 82 | } 83 | 84 | private int readByteFromMemory(Int64 offset) 85 | { 86 | byte[] buffer = new byte[1]; 87 | int bytesRead = 0; 88 | ReadProcessMemory((int)currentHandle, offset, buffer, buffer.Length, ref bytesRead); 89 | return Convert.ToInt32(buffer[0]); 90 | 91 | } 92 | 93 | public void run() 94 | { 95 | int lastBeat = -1; 96 | 97 | while (true) 98 | { 99 | if (errorCount > maxErrors) 100 | { 101 | FileManager.log("too many errors, self crashing..."); 102 | isCrashed = true; 103 | return; 104 | } 105 | 106 | masterDeck = readByteFromMemory(masterAddress) + 1; 107 | 108 | if (masterDeck < 1 || masterDeck > 4) 109 | { 110 | errorCount += 1; 111 | FileManager.log("read error! masterdeck is out of valid range"); 112 | 113 | } 114 | else 115 | { 116 | currentBeatNr = readByteFromMemory(deckAdresses[masterDeck - 1]); 117 | 118 | } 119 | 120 | if (currentBeatNr > 4 || currentBeatNr < 1) 121 | { 122 | errorCount += 1; 123 | FileManager.log("read error! beat number is out of valid range"); 124 | 125 | } 126 | 127 | if (lastBeat != currentBeatNr) 128 | { 129 | lastBeat = currentBeatNr; 130 | new Thread(() => { 131 | Thread.CurrentThread.IsBackground = true; 132 | osc.sendMsg(); 133 | }).Start(); 134 | 135 | } 136 | 137 | Thread.Sleep(1); 138 | } 139 | } 140 | 141 | } 142 | } -------------------------------------------------------------------------------- /rbBeatDetect/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /rbBeatDetect/rbBeatDetect.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {AF8AB790-2874-449E-8C03-2FBE76879856} 8 | WinExe 9 | rbBeatDetect 10 | rbBeatDetect 11 | v4.7.2 12 | 512 13 | true 14 | true 15 | 16 | 17 | icon.ico 18 | 19 | 20 | true 21 | 22 | 23 | true 24 | bin\x64\Debug\ 25 | DEBUG;TRACE 26 | full 27 | x64 28 | 7.3 29 | prompt 30 | MinimumRecommendedRules.ruleset 31 | true 32 | 33 | 34 | bin\x64\Release\ 35 | TRACE 36 | true 37 | pdbonly 38 | x64 39 | 7.3 40 | prompt 41 | MinimumRecommendedRules.ruleset 42 | true 43 | 44 | 45 | 46 | ..\packages\Microsoft.Bcl.AsyncInterfaces.7.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll 47 | 48 | 49 | ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll 50 | 51 | 52 | ..\SharpOsc\SharpOSC.dll 53 | 54 | 55 | 56 | ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll 57 | 58 | 59 | 60 | ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll 61 | 62 | 63 | 64 | ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll 65 | 66 | 67 | ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll 68 | 69 | 70 | ..\packages\System.Text.Encodings.Web.7.0.0\lib\net462\System.Text.Encodings.Web.dll 71 | 72 | 73 | ..\packages\System.Text.Json.7.0.3\lib\net462\System.Text.Json.dll 74 | 75 | 76 | ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll 77 | 78 | 79 | ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | Form 95 | 96 | 97 | Menu.cs 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | Menu.cs 106 | 107 | 108 | ResXFileCodeGenerator 109 | Resources.Designer.cs 110 | Designer 111 | 112 | 113 | True 114 | Resources.resx 115 | 116 | 117 | 118 | SettingsSingleFileGenerator 119 | Settings.Designer.cs 120 | 121 | 122 | True 123 | Settings.settings 124 | True 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /rbBeatDetect/VersionManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Net; 7 | using System.Text; 8 | using System.Text.RegularExpressions; 9 | using System.Threading.Tasks; 10 | using Newtonsoft.Json; 11 | using Newtonsoft.Json.Linq; 12 | 13 | 14 | namespace rbBeatDetect 15 | { 16 | public class VersionManager 17 | { 18 | private string onlineOffsetPath = "https://raw.githubusercontent.com/palmarci/rbBeatDetect/main/offsets.json"; 19 | 20 | public List parseOffsets(string text) { 21 | List data = JsonConvert.DeserializeObject>(text); 22 | return data; 23 | } 24 | 25 | public static bool IsValidJson(string jsonString) 26 | { 27 | try 28 | { 29 | JToken.Parse(jsonString); 30 | return true; 31 | } 32 | catch (Exception) 33 | { 34 | return false; 35 | } 36 | } 37 | 38 | //tries to download from github repo, if it fails: reads from backup file 39 | public string getOffsetText() 40 | { 41 | 42 | try 43 | { 44 | var resp = ""; 45 | HttpWebRequest request = (HttpWebRequest)WebRequest.Create(onlineOffsetPath); 46 | request.AutomaticDecompression = DecompressionMethods.GZip; 47 | 48 | using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) 49 | using (Stream stream = response.GetResponseStream()) 50 | using (StreamReader reader = new StreamReader(stream)) 51 | { 52 | resp = reader.ReadToEnd(); 53 | } 54 | 55 | 56 | if (!IsValidJson(resp)) 57 | { 58 | throw new Exception("Invalid JSON from github repo"); 59 | } 60 | else 61 | { 62 | var minified = Regex.Replace(resp, "(\"(?:[^\"\\\\]|\\\\.)*\")|\\s+", "$1"); //lol 63 | FileManager.log("got ok json data, writing it to backup: {" + minified + "}"); 64 | FileManager.writeBackupOffsets(resp); 65 | return resp; 66 | 67 | } 68 | 69 | } 70 | catch (Exception e) 71 | { 72 | FileManager.log($"error downloading offsets: {e.ToString()}, \r\ntrying to read from backup"); 73 | 74 | try 75 | { 76 | return FileManager.readBackupOffsets(); 77 | 78 | } 79 | catch (Exception e2) 80 | { 81 | FileManager.log($"failed reading backup file: {e2.ToString()}"); 82 | } 83 | 84 | return null; 85 | } 86 | 87 | } 88 | public AppVersion getLatestOnlineVersion() //not used currently, but interesting 89 | { 90 | try 91 | { 92 | var url = "https://rekordbox.com/hidden2/rb6_release/apl/check_updater.php"; 93 | 94 | var request = System.Net.WebRequest.Create(url); 95 | request.Method = "POST"; 96 | 97 | 98 | var postData = "UP_NAME=rekordbox4&UP_VER=6.6.0&UP_LANG=en&OS_TYPE=Windows&OS_VERSION=10-64-64"; 99 | byte[] byteArray = Encoding.UTF8.GetBytes(postData); 100 | 101 | request.ContentType = "application/x-www-form-urlencoded"; 102 | request.ContentLength = byteArray.Length; 103 | 104 | var reqStream = request.GetRequestStream(); 105 | reqStream.Write(byteArray, 0, byteArray.Length); 106 | 107 | var response = request.GetResponse(); 108 | 109 | var respStream = response.GetResponseStream(); 110 | 111 | var reader = new StreamReader(respStream); 112 | string data = reader.ReadToEnd(); 113 | FileManager.log("got data from rekordbox.com: " + data); 114 | 115 | if (data.Contains("STATUS=0")) 116 | { 117 | Regex word = new Regex(@"UP_VER=([0-9]\.[0-9]\.[0-9]);"); 118 | Match m = word.Match(data); 119 | string finalVersion = m.Groups[1].Value; 120 | 121 | if (finalVersion.Length == 5) 122 | { 123 | return new AppVersion(finalVersion); 124 | 125 | } 126 | else 127 | { 128 | FileManager.log("latest version length mismatch"); 129 | } 130 | 131 | } 132 | else 133 | { 134 | FileManager.log("server responded with an error"); 135 | 136 | } 137 | 138 | return null; 139 | 140 | } catch ( Exception ) 141 | { 142 | return null; 143 | } 144 | } 145 | private int extractNumbers(String InputString) 146 | { 147 | String Result = ""; 148 | string Numbers = "0123456789"; 149 | int i = 0; 150 | 151 | for (i = 0; i < InputString.Length; i++) 152 | { 153 | if (Numbers.Contains(InputString.ElementAt(i))) 154 | { 155 | Result += InputString.ElementAt(i); 156 | } 157 | } 158 | return Convert.ToInt32(Result); 159 | } 160 | public AppVersion getRunningVersion(string path) 161 | { 162 | 163 | FileManager.log("got running path: " + path); 164 | 165 | FileVersionInfo fileInfo = FileVersionInfo.GetVersionInfo(path); 166 | var version = fileInfo.FileVersion.Split('.'); 167 | 168 | return new AppVersion(extractNumbers(version[0]), extractNumbers(version[1]), extractNumbers(version[2])); 169 | 170 | 171 | } 172 | public class AppVersion 173 | { 174 | public AppVersion() 175 | { 176 | 177 | } 178 | 179 | public AppVersion(int m, int s, int p) 180 | { 181 | mainVer = m; 182 | subVer = s; 183 | patchVer = p; 184 | } 185 | 186 | public AppVersion(string str) 187 | { 188 | var splits = str.Split('.'); 189 | mainVer = Convert.ToInt32(splits[0]); 190 | subVer = Convert.ToInt32(splits[1]); 191 | patchVer = Convert.ToInt32(splits[2]); 192 | } 193 | 194 | public int mainVer; 195 | public int subVer; 196 | public int patchVer; 197 | 198 | public override bool Equals(object obj) 199 | { 200 | return obj is AppVersion version && 201 | mainVer == version.mainVer && 202 | subVer == version.subVer && 203 | patchVer == version.patchVer; 204 | } 205 | 206 | public override string ToString() 207 | { 208 | return mainVer + "." + subVer + "." + patchVer; 209 | } 210 | 211 | } 212 | public class OffsetData 213 | { 214 | public AppVersion version; 215 | public int deckPointer; 216 | public int[][] deckOffsets; 217 | public int masterPointer; 218 | public int[] masterOffsets; 219 | public int endOffset; 220 | 221 | public OffsetData() 222 | { 223 | 224 | } 225 | 226 | public OffsetData(string version, int deckPointer, int[][] deckOffsets, int masterPointer, int[] masterOffsets, int endOffset) 227 | { 228 | this.version = new AppVersion(version); 229 | this.deckPointer = deckPointer; 230 | this.deckOffsets = deckOffsets; 231 | this.masterPointer = masterPointer; 232 | this.masterOffsets = masterOffsets; 233 | this.endOffset = endOffset; 234 | } 235 | 236 | 237 | 238 | public override string ToString() 239 | { 240 | string str = "v" + version.ToString() + ", deck pointer: " + this.deckPointer + ", master pointer:" + this.masterPointer + ", master offsets: ("; 241 | foreach (int i in masterOffsets) 242 | { 243 | str += i + ", "; 244 | } 245 | 246 | str += "), endOffset: " + this.endOffset; 247 | return str; 248 | } 249 | } 250 | 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /rbBeatDetect/Menu.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Data; 5 | using System.Diagnostics; 6 | using System.Drawing; 7 | using System.IO; 8 | using System.Linq; 9 | using System.Net; 10 | using System.Text; 11 | using System.Text.RegularExpressions; 12 | using System.Threading; 13 | using System.Threading.Tasks; 14 | using System.Timers; 15 | using System.Windows.Forms; 16 | using static rbBeatDetect.VersionManager; 17 | 18 | namespace rbBeatDetect 19 | { 20 | 21 | public partial class Menu : Form 22 | { 23 | public Menu() 24 | { 25 | InitializeComponent(); 26 | } 27 | 28 | VersionManager versionManager = new VersionManager(); 29 | List supportedOffsets = new List(); 30 | VersionManager.AppVersion runningVersion = null; 31 | 32 | Thread memoryThread = null; 33 | MemoryReader memoryReader = null; 34 | 35 | 36 | private void setBeatColor(int beatNumber) 37 | { 38 | if (beatNumber == 1) 39 | { 40 | beat1.BackColor = Color.Orange; 41 | beat2.BackColor = Color.White; 42 | beat3.BackColor = Color.White; 43 | beat4.BackColor = Color.White; 44 | 45 | } 46 | else if (beatNumber == 2) 47 | { 48 | beat1.BackColor = Color.White; 49 | beat2.BackColor = Color.Orange; 50 | beat3.BackColor = Color.White; 51 | beat4.BackColor = Color.White; 52 | } 53 | else if (beatNumber == 3) 54 | { 55 | beat1.BackColor = Color.White; 56 | beat2.BackColor = Color.White; 57 | beat3.BackColor = Color.Orange; 58 | beat4.BackColor = Color.White; 59 | } 60 | else if (beatNumber == 4) 61 | { 62 | beat1.BackColor = Color.White; 63 | beat2.BackColor = Color.White; 64 | beat3.BackColor = Color.White; 65 | beat4.BackColor = Color.Orange; 66 | } 67 | else 68 | { 69 | beat1.BackColor = Color.White; 70 | beat2.BackColor = Color.White; 71 | beat3.BackColor = Color.White; 72 | beat4.BackColor = Color.White; 73 | 74 | } 75 | } 76 | 77 | private void Form1_Load(object sender, EventArgs e) 78 | { 79 | masterDeckHelper.Visible = false; 80 | masterDeckLabel.Visible = false; 81 | 82 | System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly(); 83 | System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location); 84 | string version = fvi.FileVersion; 85 | 86 | titleLabel.Text += " v" + version.Replace(".0", ""); 87 | errorLabel.Text = ""; 88 | 89 | string offsetText = versionManager.getOffsetText(); 90 | 91 | if (offsetText != null) { 92 | supportedOffsets = versionManager.parseOffsets(offsetText); 93 | } 94 | 95 | if (supportedOffsets == null || supportedOffsets.Count > 0) 96 | { 97 | errorLabel.Text = "Failed downloading the offsets and could not read the local backup!\r\nPlease check your internet connection!\r\n"; 98 | supportedVersionsHelper.Enabled = false; 99 | 100 | } 101 | else 102 | { 103 | foreach (var ver in supportedOffsets) 104 | { 105 | 106 | versionsBox.Items.Add(ver.version.ToString()); 107 | 108 | } 109 | 110 | } 111 | 112 | runningVersionLabel.Text = "..."; 113 | runningCheckbox.Enabled = false; 114 | 115 | rbVersionCheckTimer.Start(); 116 | 117 | } 118 | 119 | private void turnOffMemoryReader() 120 | { 121 | setBeatColor(0); 122 | masterDeckLabel.Text = "???"; 123 | updateGuiTimer.Stop(); 124 | memoryThread?.Abort(); 125 | memoryReader = null; 126 | runningCheckbox.Checked = false; 127 | masterDeckHelper.Visible = false; 128 | masterDeckLabel.Visible = false; 129 | oscGroup.Enabled = true; 130 | 131 | } 132 | 133 | private OscClient setupOscClient() 134 | { 135 | IPAddress parsedIp; 136 | if (!IPAddress.TryParse(oscIpAddr.Text, out parsedIp)) 137 | { 138 | FileManager.log("Failed parsing ip"); 139 | errorLabel.Text = "Failed parsing the IP address."; 140 | return null; 141 | } 142 | 143 | var Path = oscPath.Text; 144 | if (Path[0] == '/') 145 | { 146 | Path = Path.Remove(0, 1); 147 | } 148 | 149 | Path = Path.Replace(" ", ""); 150 | 151 | int port; 152 | if (!int.TryParse(oscPortBox.Text, out port)) 153 | { 154 | FileManager.log("port parsing failed"); 155 | errorLabel.Text = "Failed parsing the port number."; 156 | return null; 157 | } 158 | 159 | return new OscClient(parsedIp, port, Path, oscMimicHuman.Checked, Convert.ToInt32(oscHumanDelay.Value), Convert.ToInt32(oscDelay.Value)); 160 | 161 | } 162 | 163 | private void runningCheckbox_CheckedChanged(object sender, EventArgs e) 164 | { 165 | 166 | if (runningCheckbox.Checked == true) 167 | { 168 | 169 | errorLabel.Text = ""; 170 | 171 | var oscClient = setupOscClient(); 172 | 173 | if (oscClient == null) 174 | { 175 | turnOffMemoryReader(); 176 | return; 177 | } 178 | 179 | oscGroup.Enabled = false; 180 | 181 | foreach (var data in supportedOffsets) 182 | { 183 | if (data.version.Equals(runningVersion)) 184 | { 185 | memoryReader = new MemoryReader(data, oscClient); 186 | } 187 | } 188 | 189 | if (memoryReader == null) 190 | { 191 | errorLabel.Text = "The current version is not (yet) supported!"; 192 | turnOffMemoryReader(); 193 | return; 194 | } 195 | 196 | memoryThread = new Thread(memoryReader.run); 197 | memoryThread.IsBackground = true; 198 | memoryThread.Start(); 199 | 200 | updateGuiTimer.Start(); 201 | masterDeckLabel.Visible = true; 202 | masterDeckHelper.Visible = true; 203 | 204 | } 205 | else 206 | { 207 | turnOffMemoryReader(); 208 | } 209 | 210 | } 211 | 212 | private void rbCheckTimer_Tick(object sender, EventArgs e) 213 | { 214 | { 215 | Process[] pname = Process.GetProcessesByName("rekordbox"); 216 | if (pname.Length != 0) 217 | { 218 | if (runningVersion == null) 219 | { 220 | FileManager.log("checking for rb.exe..."); 221 | 222 | try 223 | { 224 | var path = pname.First().MainModule.FileName; 225 | var result = versionManager.getRunningVersion(path); 226 | if (result == null) 227 | { 228 | runningCheckbox.Checked = false; 229 | runningCheckbox.Enabled = false; 230 | runningVersionLabel.Text = "FAIL"; 231 | 232 | } 233 | else 234 | { 235 | runningCheckbox.Enabled = true; 236 | runningVersionLabel.Text = result.ToString(); 237 | runningVersionLabel.ForeColor = Color.Green; 238 | 239 | runningVersion = result; 240 | 241 | } 242 | } 243 | catch (Exception ex) 244 | { 245 | FileManager.log("exception while getting rekordbox.exe version: " + ex.Message); 246 | } 247 | 248 | } 249 | } 250 | else 251 | { 252 | runningCheckbox.Checked = false; 253 | runningCheckbox.Enabled = false; 254 | runningVersionLabel.ForeColor = Color.Red; 255 | runningVersionLabel.Text = "rekordbox is not running..."; 256 | runningVersion = null; 257 | } 258 | 259 | } 260 | } 261 | 262 | private void updateGuiTimer_Tick(object sender, EventArgs e) 263 | { 264 | masterDeckLabel.Text = $"{memoryReader.masterDeck}"; 265 | setBeatColor(memoryReader.currentBeatNr); 266 | 267 | if (memoryReader.isCrashed) 268 | { 269 | errorLabel.Text = "Memory reader crashed!\r\nDid you set the Master Deck?\r\nDid you load a track to EVERY deck?"; 270 | turnOffMemoryReader(); 271 | } 272 | } 273 | 274 | private void oscMimicHuman_CheckedChanged(object sender, EventArgs e) 275 | { 276 | if (oscMimicHuman.Checked == true) 277 | { 278 | oscHumanDelay.Enabled = true; 279 | 280 | } 281 | else 282 | { 283 | oscHumanDelay.Enabled = false; 284 | } 285 | } 286 | 287 | private void selfSponsor_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) 288 | { 289 | System.Diagnostics.Process.Start("https://github.com/palmarci/rbBeatDetect"); 290 | } 291 | 292 | private void oscDelay_ValueChanged(object sender, EventArgs e) 293 | { 294 | if (oscDelay.Value > 500) 295 | { 296 | oscDelay.Value = 500; 297 | } 298 | } 299 | 300 | private void oscHumanDelay_ValueChanged(object sender, EventArgs e) 301 | { 302 | if (oscHumanDelay.Value > 500) 303 | { 304 | oscHumanDelay.Value = 500; 305 | } 306 | } 307 | 308 | } 309 | 310 | } 311 | -------------------------------------------------------------------------------- /rbBeatDetect/Menu.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace rbBeatDetect 2 | { 3 | partial class Menu 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Menu)); 33 | this.errorLabel = new System.Windows.Forms.Label(); 34 | this.titleLabel = new System.Windows.Forms.Label(); 35 | this.beat1 = new System.Windows.Forms.Button(); 36 | this.beat2 = new System.Windows.Forms.Button(); 37 | this.beat3 = new System.Windows.Forms.Button(); 38 | this.beat4 = new System.Windows.Forms.Button(); 39 | this.masterDeckHelper = new System.Windows.Forms.Label(); 40 | this.masterDeckLabel = new System.Windows.Forms.Label(); 41 | this.oscGroup = new System.Windows.Forms.GroupBox(); 42 | this.label1 = new System.Windows.Forms.Label(); 43 | this.oscHumanDelay = new System.Windows.Forms.NumericUpDown(); 44 | this.oscDelayHelper = new System.Windows.Forms.Label(); 45 | this.oscDelay = new System.Windows.Forms.NumericUpDown(); 46 | this.oscMimicHuman = new System.Windows.Forms.CheckBox(); 47 | this.oscPortBox = new System.Windows.Forms.TextBox(); 48 | this.oscPath = new System.Windows.Forms.TextBox(); 49 | this.oscIpAddr = new System.Windows.Forms.TextBox(); 50 | this.oscPathHelper = new System.Windows.Forms.Label(); 51 | this.oscPortHelper = new System.Windows.Forms.Label(); 52 | this.oscAddressHelper = new System.Windows.Forms.Label(); 53 | this.stats = new System.Windows.Forms.GroupBox(); 54 | this.runningCheckbox = new System.Windows.Forms.CheckBox(); 55 | this.verBox = new System.Windows.Forms.GroupBox(); 56 | this.versionsBox = new System.Windows.Forms.ListBox(); 57 | this.supportedVersionsHelper = new System.Windows.Forms.Label(); 58 | this.runningVersionLabel = new System.Windows.Forms.Label(); 59 | this.runningVersionHelper = new System.Windows.Forms.Label(); 60 | this.rbVersionCheckTimer = new System.Windows.Forms.Timer(this.components); 61 | this.updateGuiTimer = new System.Windows.Forms.Timer(this.components); 62 | this.selfSponsor = new System.Windows.Forms.LinkLabel(); 63 | this.oscGroup.SuspendLayout(); 64 | ((System.ComponentModel.ISupportInitialize)(this.oscHumanDelay)).BeginInit(); 65 | ((System.ComponentModel.ISupportInitialize)(this.oscDelay)).BeginInit(); 66 | this.stats.SuspendLayout(); 67 | this.verBox.SuspendLayout(); 68 | this.SuspendLayout(); 69 | // 70 | // errorLabel 71 | // 72 | this.errorLabel.ForeColor = System.Drawing.Color.Red; 73 | this.errorLabel.Location = new System.Drawing.Point(152, 428); 74 | this.errorLabel.Name = "errorLabel"; 75 | this.errorLabel.Size = new System.Drawing.Size(280, 55); 76 | this.errorLabel.TabIndex = 2; 77 | this.errorLabel.Text = "[placeholder]"; 78 | this.errorLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; 79 | // 80 | // titleLabel 81 | // 82 | this.titleLabel.Font = new System.Drawing.Font("Microsoft Sans Serif", 15.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238))); 83 | this.titleLabel.Location = new System.Drawing.Point(12, 9); 84 | this.titleLabel.Name = "titleLabel"; 85 | this.titleLabel.Size = new System.Drawing.Size(566, 25); 86 | this.titleLabel.TabIndex = 11; 87 | this.titleLabel.Text = "rbBeatDetect GUI"; 88 | this.titleLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter; 89 | // 90 | // beat1 91 | // 92 | this.beat1.BackColor = System.Drawing.Color.White; 93 | this.beat1.Enabled = false; 94 | this.beat1.Location = new System.Drawing.Point(68, 42); 95 | this.beat1.Name = "beat1"; 96 | this.beat1.Size = new System.Drawing.Size(33, 21); 97 | this.beat1.TabIndex = 13; 98 | this.beat1.UseVisualStyleBackColor = false; 99 | // 100 | // beat2 101 | // 102 | this.beat2.BackColor = System.Drawing.Color.White; 103 | this.beat2.Enabled = false; 104 | this.beat2.Location = new System.Drawing.Point(101, 42); 105 | this.beat2.Name = "beat2"; 106 | this.beat2.Size = new System.Drawing.Size(33, 21); 107 | this.beat2.TabIndex = 14; 108 | this.beat2.UseVisualStyleBackColor = false; 109 | // 110 | // beat3 111 | // 112 | this.beat3.BackColor = System.Drawing.Color.White; 113 | this.beat3.Enabled = false; 114 | this.beat3.Location = new System.Drawing.Point(134, 42); 115 | this.beat3.Name = "beat3"; 116 | this.beat3.Size = new System.Drawing.Size(33, 21); 117 | this.beat3.TabIndex = 15; 118 | this.beat3.UseVisualStyleBackColor = false; 119 | // 120 | // beat4 121 | // 122 | this.beat4.BackColor = System.Drawing.Color.White; 123 | this.beat4.Enabled = false; 124 | this.beat4.Location = new System.Drawing.Point(167, 42); 125 | this.beat4.Name = "beat4"; 126 | this.beat4.Size = new System.Drawing.Size(33, 21); 127 | this.beat4.TabIndex = 16; 128 | this.beat4.UseVisualStyleBackColor = false; 129 | // 130 | // masterDeckHelper 131 | // 132 | this.masterDeckHelper.AutoSize = true; 133 | this.masterDeckHelper.Location = new System.Drawing.Point(82, 79); 134 | this.masterDeckHelper.Name = "masterDeckHelper"; 135 | this.masterDeckHelper.Size = new System.Drawing.Size(71, 13); 136 | this.masterDeckHelper.TabIndex = 17; 137 | this.masterDeckHelper.Text = "Master Deck:"; 138 | // 139 | // masterDeckLabel 140 | // 141 | this.masterDeckLabel.AutoSize = true; 142 | this.masterDeckLabel.Location = new System.Drawing.Point(159, 79); 143 | this.masterDeckLabel.Name = "masterDeckLabel"; 144 | this.masterDeckLabel.Size = new System.Drawing.Size(68, 13); 145 | this.masterDeckLabel.TabIndex = 18; 146 | this.masterDeckLabel.Text = "[placeholder]"; 147 | // 148 | // oscGroup 149 | // 150 | this.oscGroup.Controls.Add(this.label1); 151 | this.oscGroup.Controls.Add(this.oscHumanDelay); 152 | this.oscGroup.Controls.Add(this.oscDelayHelper); 153 | this.oscGroup.Controls.Add(this.oscDelay); 154 | this.oscGroup.Controls.Add(this.oscMimicHuman); 155 | this.oscGroup.Controls.Add(this.oscPortBox); 156 | this.oscGroup.Controls.Add(this.oscPath); 157 | this.oscGroup.Controls.Add(this.oscIpAddr); 158 | this.oscGroup.Controls.Add(this.oscPathHelper); 159 | this.oscGroup.Controls.Add(this.oscPortHelper); 160 | this.oscGroup.Controls.Add(this.oscAddressHelper); 161 | this.oscGroup.Location = new System.Drawing.Point(301, 55); 162 | this.oscGroup.Name = "oscGroup"; 163 | this.oscGroup.Size = new System.Drawing.Size(277, 226); 164 | this.oscGroup.TabIndex = 20; 165 | this.oscGroup.TabStop = false; 166 | this.oscGroup.Text = "OSC Settings"; 167 | // 168 | // label1 169 | // 170 | this.label1.AutoSize = true; 171 | this.label1.Location = new System.Drawing.Point(63, 164); 172 | this.label1.Name = "label1"; 173 | this.label1.Size = new System.Drawing.Size(70, 13); 174 | this.label1.TabIndex = 20; 175 | this.label1.Text = "Delay (in ms):"; 176 | // 177 | // oscHumanDelay 178 | // 179 | this.oscHumanDelay.Enabled = false; 180 | this.oscHumanDelay.Location = new System.Drawing.Point(138, 162); 181 | this.oscHumanDelay.Maximum = new decimal(new int[] { 182 | 500, 183 | 0, 184 | 0, 185 | 0}); 186 | this.oscHumanDelay.Name = "oscHumanDelay"; 187 | this.oscHumanDelay.Size = new System.Drawing.Size(58, 20); 188 | this.oscHumanDelay.TabIndex = 29; 189 | this.oscHumanDelay.Value = new decimal(new int[] { 190 | 25, 191 | 0, 192 | 0, 193 | 0}); 194 | this.oscHumanDelay.ValueChanged += new System.EventHandler(this.oscHumanDelay_ValueChanged); 195 | // 196 | // oscDelayHelper 197 | // 198 | this.oscDelayHelper.AutoSize = true; 199 | this.oscDelayHelper.Location = new System.Drawing.Point(6, 104); 200 | this.oscDelayHelper.Name = "oscDelayHelper"; 201 | this.oscDelayHelper.Size = new System.Drawing.Size(79, 13); 202 | this.oscDelayHelper.TabIndex = 28; 203 | this.oscDelayHelper.Text = "OSC Pre-delay:"; 204 | // 205 | // oscDelay 206 | // 207 | this.oscDelay.Location = new System.Drawing.Point(103, 102); 208 | this.oscDelay.Maximum = new decimal(new int[] { 209 | 500, 210 | 0, 211 | 0, 212 | 0}); 213 | this.oscDelay.Name = "oscDelay"; 214 | this.oscDelay.Size = new System.Drawing.Size(58, 20); 215 | this.oscDelay.TabIndex = 27; 216 | this.oscDelay.ValueChanged += new System.EventHandler(this.oscDelay_ValueChanged); 217 | // 218 | // oscMimicHuman 219 | // 220 | this.oscMimicHuman.AutoSize = true; 221 | this.oscMimicHuman.Location = new System.Drawing.Point(72, 137); 222 | this.oscMimicHuman.Name = "oscMimicHuman"; 223 | this.oscMimicHuman.Size = new System.Drawing.Size(133, 17); 224 | this.oscMimicHuman.TabIndex = 26; 225 | this.oscMimicHuman.Text = "Mimic human keypress"; 226 | this.oscMimicHuman.UseVisualStyleBackColor = true; 227 | this.oscMimicHuman.CheckedChanged += new System.EventHandler(this.oscMimicHuman_CheckedChanged); 228 | // 229 | // oscPortBox 230 | // 231 | this.oscPortBox.Location = new System.Drawing.Point(103, 51); 232 | this.oscPortBox.Name = "oscPortBox"; 233 | this.oscPortBox.Size = new System.Drawing.Size(152, 20); 234 | this.oscPortBox.TabIndex = 25; 235 | this.oscPortBox.Text = "7700"; 236 | // 237 | // oscPath 238 | // 239 | this.oscPath.Location = new System.Drawing.Point(103, 76); 240 | this.oscPath.Name = "oscPath"; 241 | this.oscPath.Size = new System.Drawing.Size(152, 20); 242 | this.oscPath.TabIndex = 24; 243 | this.oscPath.Text = "/beat"; 244 | // 245 | // oscIpAddr 246 | // 247 | this.oscIpAddr.Location = new System.Drawing.Point(103, 28); 248 | this.oscIpAddr.Name = "oscIpAddr"; 249 | this.oscIpAddr.Size = new System.Drawing.Size(152, 20); 250 | this.oscIpAddr.TabIndex = 23; 251 | this.oscIpAddr.Text = "127.0.0.1"; 252 | // 253 | // oscPathHelper 254 | // 255 | this.oscPathHelper.AutoSize = true; 256 | this.oscPathHelper.Location = new System.Drawing.Point(6, 79); 257 | this.oscPathHelper.Name = "oscPathHelper"; 258 | this.oscPathHelper.Size = new System.Drawing.Size(57, 13); 259 | this.oscPathHelper.TabIndex = 22; 260 | this.oscPathHelper.Text = "OSC Path:"; 261 | // 262 | // oscPortHelper 263 | // 264 | this.oscPortHelper.AutoSize = true; 265 | this.oscPortHelper.Location = new System.Drawing.Point(6, 54); 266 | this.oscPortHelper.Name = "oscPortHelper"; 267 | this.oscPortHelper.Size = new System.Drawing.Size(29, 13); 268 | this.oscPortHelper.TabIndex = 21; 269 | this.oscPortHelper.Text = "Port:"; 270 | // 271 | // oscAddressHelper 272 | // 273 | this.oscAddressHelper.AutoSize = true; 274 | this.oscAddressHelper.Location = new System.Drawing.Point(6, 31); 275 | this.oscAddressHelper.Name = "oscAddressHelper"; 276 | this.oscAddressHelper.Size = new System.Drawing.Size(91, 13); 277 | this.oscAddressHelper.TabIndex = 20; 278 | this.oscAddressHelper.Text = "Network Address:"; 279 | // 280 | // stats 281 | // 282 | this.stats.Controls.Add(this.runningCheckbox); 283 | this.stats.Controls.Add(this.beat3); 284 | this.stats.Controls.Add(this.beat1); 285 | this.stats.Controls.Add(this.masterDeckLabel); 286 | this.stats.Controls.Add(this.beat2); 287 | this.stats.Controls.Add(this.masterDeckHelper); 288 | this.stats.Controls.Add(this.beat4); 289 | this.stats.Location = new System.Drawing.Point(152, 312); 290 | this.stats.Name = "stats"; 291 | this.stats.Size = new System.Drawing.Size(280, 113); 292 | this.stats.TabIndex = 21; 293 | this.stats.TabStop = false; 294 | this.stats.Text = "Stats"; 295 | // 296 | // runningCheckbox 297 | // 298 | this.runningCheckbox.AutoSize = true; 299 | this.runningCheckbox.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(238))); 300 | this.runningCheckbox.Location = new System.Drawing.Point(103, 19); 301 | this.runningCheckbox.Name = "runningCheckbox"; 302 | this.runningCheckbox.Size = new System.Drawing.Size(73, 17); 303 | this.runningCheckbox.TabIndex = 19; 304 | this.runningCheckbox.Text = "Running"; 305 | this.runningCheckbox.UseVisualStyleBackColor = true; 306 | this.runningCheckbox.CheckedChanged += new System.EventHandler(this.runningCheckbox_CheckedChanged); 307 | // 308 | // verBox 309 | // 310 | this.verBox.Controls.Add(this.versionsBox); 311 | this.verBox.Controls.Add(this.supportedVersionsHelper); 312 | this.verBox.Controls.Add(this.runningVersionLabel); 313 | this.verBox.Controls.Add(this.runningVersionHelper); 314 | this.verBox.Location = new System.Drawing.Point(12, 55); 315 | this.verBox.Name = "verBox"; 316 | this.verBox.Size = new System.Drawing.Size(266, 226); 317 | this.verBox.TabIndex = 23; 318 | this.verBox.TabStop = false; 319 | this.verBox.Text = "Version Settings"; 320 | // 321 | // versionsBox 322 | // 323 | this.versionsBox.Enabled = false; 324 | this.versionsBox.FormattingEnabled = true; 325 | this.versionsBox.Location = new System.Drawing.Point(125, 54); 326 | this.versionsBox.Name = "versionsBox"; 327 | this.versionsBox.Size = new System.Drawing.Size(120, 121); 328 | this.versionsBox.TabIndex = 31; 329 | // 330 | // supportedVersionsHelper 331 | // 332 | this.supportedVersionsHelper.AutoSize = true; 333 | this.supportedVersionsHelper.Location = new System.Drawing.Point(16, 54); 334 | this.supportedVersionsHelper.Name = "supportedVersionsHelper"; 335 | this.supportedVersionsHelper.Size = new System.Drawing.Size(102, 13); 336 | this.supportedVersionsHelper.TabIndex = 29; 337 | this.supportedVersionsHelper.Text = "Supported Versions:"; 338 | // 339 | // runningVersionLabel 340 | // 341 | this.runningVersionLabel.AutoSize = true; 342 | this.runningVersionLabel.Location = new System.Drawing.Point(121, 28); 343 | this.runningVersionLabel.Name = "runningVersionLabel"; 344 | this.runningVersionLabel.Size = new System.Drawing.Size(68, 13); 345 | this.runningVersionLabel.TabIndex = 28; 346 | this.runningVersionLabel.Text = "[placeholder]"; 347 | // 348 | // runningVersionHelper 349 | // 350 | this.runningVersionHelper.AutoSize = true; 351 | this.runningVersionHelper.Location = new System.Drawing.Point(16, 28); 352 | this.runningVersionHelper.Name = "runningVersionHelper"; 353 | this.runningVersionHelper.Size = new System.Drawing.Size(87, 13); 354 | this.runningVersionHelper.TabIndex = 27; 355 | this.runningVersionHelper.Text = "Running version:"; 356 | // 357 | // rbVersionCheckTimer 358 | // 359 | this.rbVersionCheckTimer.Interval = 1000; 360 | this.rbVersionCheckTimer.Tick += new System.EventHandler(this.rbCheckTimer_Tick); 361 | // 362 | // updateGuiTimer 363 | // 364 | this.updateGuiTimer.Interval = 50; 365 | this.updateGuiTimer.Tick += new System.EventHandler(this.updateGuiTimer_Tick); 366 | // 367 | // selfSponsor 368 | // 369 | this.selfSponsor.AutoSize = true; 370 | this.selfSponsor.Location = new System.Drawing.Point(252, 502); 371 | this.selfSponsor.Name = "selfSponsor"; 372 | this.selfSponsor.Size = new System.Drawing.Size(82, 13); 373 | this.selfSponsor.TabIndex = 25; 374 | this.selfSponsor.TabStop = true; 375 | this.selfSponsor.Text = "Project Website"; 376 | this.selfSponsor.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.selfSponsor_LinkClicked); 377 | // 378 | // Menu 379 | // 380 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 381 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 382 | this.ClientSize = new System.Drawing.Size(598, 524); 383 | this.Controls.Add(this.selfSponsor); 384 | this.Controls.Add(this.verBox); 385 | this.Controls.Add(this.stats); 386 | this.Controls.Add(this.oscGroup); 387 | this.Controls.Add(this.titleLabel); 388 | this.Controls.Add(this.errorLabel); 389 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; 390 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 391 | this.Name = "Menu"; 392 | this.Text = "rbBeatDetect GUI"; 393 | this.Load += new System.EventHandler(this.Form1_Load); 394 | this.oscGroup.ResumeLayout(false); 395 | this.oscGroup.PerformLayout(); 396 | ((System.ComponentModel.ISupportInitialize)(this.oscHumanDelay)).EndInit(); 397 | ((System.ComponentModel.ISupportInitialize)(this.oscDelay)).EndInit(); 398 | this.stats.ResumeLayout(false); 399 | this.stats.PerformLayout(); 400 | this.verBox.ResumeLayout(false); 401 | this.verBox.PerformLayout(); 402 | this.ResumeLayout(false); 403 | this.PerformLayout(); 404 | 405 | } 406 | 407 | #endregion 408 | private System.Windows.Forms.Label errorLabel; 409 | private System.Windows.Forms.Label titleLabel; 410 | private System.Windows.Forms.Button beat1; 411 | private System.Windows.Forms.Button beat2; 412 | private System.Windows.Forms.Button beat3; 413 | private System.Windows.Forms.Button beat4; 414 | private System.Windows.Forms.Label masterDeckHelper; 415 | private System.Windows.Forms.Label masterDeckLabel; 416 | private System.Windows.Forms.GroupBox oscGroup; 417 | private System.Windows.Forms.Label oscAddressHelper; 418 | private System.Windows.Forms.TextBox oscPortBox; 419 | private System.Windows.Forms.TextBox oscPath; 420 | private System.Windows.Forms.TextBox oscIpAddr; 421 | private System.Windows.Forms.Label oscPathHelper; 422 | private System.Windows.Forms.Label oscPortHelper; 423 | private System.Windows.Forms.GroupBox stats; 424 | private System.Windows.Forms.CheckBox runningCheckbox; 425 | private System.Windows.Forms.GroupBox verBox; 426 | private System.Windows.Forms.Label supportedVersionsHelper; 427 | private System.Windows.Forms.Label runningVersionLabel; 428 | private System.Windows.Forms.Label runningVersionHelper; 429 | private System.Windows.Forms.Timer rbVersionCheckTimer; 430 | private System.Windows.Forms.Timer updateGuiTimer; 431 | private System.Windows.Forms.NumericUpDown oscDelay; 432 | private System.Windows.Forms.CheckBox oscMimicHuman; 433 | private System.Windows.Forms.Label oscDelayHelper; 434 | private System.Windows.Forms.NumericUpDown oscHumanDelay; 435 | private System.Windows.Forms.LinkLabel selfSponsor; 436 | private System.Windows.Forms.Label label1; 437 | private System.Windows.Forms.ListBox versionsBox; 438 | } 439 | } 440 | 441 | --------------------------------------------------------------------------------