├── LICENSE ├── README.md ├── Samples ├── QuNeo Remix Decks.tsi ├── QuNeo Remix Decks.tsi.bin ├── Xone K2 Page 1.tsi ├── Xone K2 Page 1.tsi.bin ├── blank.tsi └── blank.tsi.bin └── Tools ├── Extract TSI Mapping.1sc └── TSI Mapping Template.bt /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Ivan Zlatev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## What is this? 2 | 3 | Documentation for the reverse-engineered .tsi file format used by Native Instrument's Traktor Pro 2.x for storing Controller Mappings 4 | 5 | ## Documentation 6 | 7 | All documentation is available here: https://github.com/ivanz/TraktorMappingFileFormat/wiki/ 8 | 9 | ## Contributing 10 | 11 | Please open an issue with any documentation adjustments/other. 12 | 13 | ## Tools and Samples 14 | 15 | All tools used to reverse-engineer the file format (useful for contributing back to this project) are available in the repository. 16 | 17 | ## Who am I? 18 | 19 | I am Ivan Zlatev and you can get in touch at: ivan AT ivanz.com 20 | 21 | You can also follow my blog here for any updates: http://ivanz.com 22 | -------------------------------------------------------------------------------- /Samples/QuNeo Remix Decks.tsi.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivanz/TraktorMappingFileFormat/df5f544d10e3293b72b829841e654da0db71c4b0/Samples/QuNeo Remix Decks.tsi.bin -------------------------------------------------------------------------------- /Samples/Xone K2 Page 1.tsi.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivanz/TraktorMappingFileFormat/df5f544d10e3293b72b829841e654da0db71c4b0/Samples/Xone K2 Page 1.tsi.bin -------------------------------------------------------------------------------- /Samples/blank.tsi.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ivanz/TraktorMappingFileFormat/df5f544d10e3293b72b829841e654da0db71c4b0/Samples/blank.tsi.bin -------------------------------------------------------------------------------- /Tools/Extract TSI Mapping.1sc: -------------------------------------------------------------------------------- 1 | //---------- 010 Editor v3.x Script File ------------------------------ 2 | // File: Extract TSI Mapping (based on Decode Base64) 3 | // Author: Ivan Zlatev (based on work by Bernhard Foltz, Munich, Germany) 4 | // Revision: 19.10.2014 (based on Decode Base64 revision 1 from 5 Jul 2009) 5 | // Purpose: When ran on a .tsi file - extracts the binary data in a new temporary tab 6 | // enabling the TSI Template to be run. 7 | //--------------------------------------------------------------------- 8 | 9 | const string title = "Extract TSI Mapping"; 10 | 11 | int64 adr, siz, out; 12 | int actfile, newfile, data, bits; 13 | ubyte b; 14 | string s; 15 | 16 | // At least, one file must be open 17 | if (FileCount() == 0) { 18 | MessageBox(idOk, title, "No file is open."); 19 | return -1; 20 | } 21 | 22 | string lookFor = " 0) { 40 | b = ReadUByte(adr); adr++; siz--; 41 | if ((b >= 'A') && (b <= 'Z')) { 42 | data = (data << 6) | (b - 'A'); bits += 6; 43 | } 44 | else if ((b >= 'a') && (b <= 'z')) { 45 | data = (data << 6) | (b - 'a' + 26); bits += 6; 46 | } 47 | else if ((b >= '0') && (b <= '9')) { 48 | data = (data << 6) | (b - '0' + 52); bits += 6; 49 | } 50 | else if ((b == '+') || (b == '-')) { 51 | data = (data << 6) | 62; bits += 6; 52 | } 53 | else if ((b == '/') || (b == '_')) { 54 | data = (data << 6) | 63; bits += 6; 55 | } 56 | else if (b > ' ') { 57 | siz = -1; 58 | break; 59 | } 60 | // write data 61 | if (bits >= 8) { 62 | bits -= 8; 63 | FileSelect(newfile); 64 | WriteUByte(out, data >> bits); out++; 65 | FileSelect(actfile); 66 | } 67 | } 68 | 69 | // new file ready 70 | FileSelect(newfile); 71 | SetCursorPos(FileSize()); 72 | -------------------------------------------------------------------------------- /Tools/TSI Mapping Template.bt: -------------------------------------------------------------------------------- 1 | //-------------------------------------- 2 | //--- 010 Editor v5.0.2 Binary Template 3 | // 4 | // File: Native Instruments Traktor Pro .TSI Controller Mapping File Template 5 | // Author: Ivan Zlatev 6 | // Revision: Refer to Git commit history for revision information 7 | // Purpose: Defines the data structure for the Traktor Pro .tsi file format used 8 | // for Controller Mapping 9 | //-------------------------------------- 10 | 11 | BigEndian(); 12 | 13 | enum DeviceTarget { 14 | Focus = 0, 15 | DeckA = 1, 16 | DeckB = 2, 17 | DeckC = 3, 18 | DeckD = 4 19 | }; 20 | 21 | enum MidiEncoderMode { 22 | _3Fh_41h = 0, 23 | _7Fh_01h = 1, 24 | }; 25 | 26 | enum MappingTargetDeck { 27 | DeviceTargetDeck = -1, 28 | AorFX1orRemixDeck1Slot1OrGlobal = 0, 29 | BorFX2orRemixDeck1Slot2 = 1, 30 | CorFX3orRemixDeck1Slot3 = 2, 31 | DorFX4orRemixDeck1Slot4 = 3, 32 | RemixDeck2Slot1 = 4, 33 | RemixDeck2Slot2 = 5, 34 | RemixDeck2Slot3 = 6, 35 | RemixDeck2Slot4 = 7, 36 | RemixDeck3Slot1 = 8, 37 | RemixDeck3Slot2 = 9, 38 | RemixDeck3Slot3 = 10, 39 | RemixDeck3Slot4 = 11, 40 | RemixDeck4Slot1 = 12, 41 | RemixDeck4Slot2 = 13, 42 | RemixDeck4Slot3 = 14, 43 | RemixDeck4Slot4 = 15, 44 | }; 45 | 46 | enum MappingInteractionMode { 47 | Toggle = 1, 48 | Hold = 2, 49 | Direct = 3, 50 | Relative = 4, 51 | Increment = 5, 52 | Decrement = 6, 53 | Reset = 7, 54 | Output = 8, 55 | }; 56 | 57 | enum MappingControllerType { 58 | Button = 0, 59 | FaderOrKnob = 1, 60 | Encoder = 2, 61 | LED = 65535, 62 | }; 63 | 64 | 65 | // Big endian values !! 66 | enum MappingResolution { 67 | Fine = 0x3C800000, 68 | Min = 0x3D800000, 69 | Default = 0x3D800000, 70 | Coarse = 0x3E000000, 71 | Switch = 0x3F000000, 72 | }; 73 | 74 | enum MappingType { 75 | In = 0, 76 | Out = 1, 77 | }; 78 | 79 | typedef struct FrameHeader { 80 | char Id[4]; 81 | // The total number of bytes of content that follow 82 | int Size; 83 | }; 84 | 85 | typedef struct DVST { 86 | FrameHeader Header; // DVST 87 | byte Content[Header.Size]; 88 | }; 89 | 90 | typedef struct DIOI { 91 | FrameHeader Header; // DIOI 92 | // Seems to be a constant 1 93 | int Unknown; 94 | }; 95 | 96 | 97 | typedef struct DeviceTargetInfo { 98 | FrameHeader Header; // DDIF 99 | DeviceTarget Target; 100 | }; 101 | 102 | typedef struct VersionInfo { 103 | FrameHeader Header; // DDIV 104 | int VersionLength; 105 | wchar_t Version[VersionLength]; 106 | int MappingFileRevision; 107 | }; 108 | 109 | typedef struct MappingFileComment { 110 | FrameHeader Header; // DDIC 111 | int CommentLength; 112 | wchar_t Comment[CommentLength]; 113 | }; 114 | 115 | typedef struct MidiNoteBinding { 116 | FrameHeader Header; // DCBM id 117 | int Id; 118 | int MidiNoteLength; 119 | wchar_t MidiNote[MidiNoteLength]; 120 | }; 121 | 122 | // The first DCBM entry provides the count 123 | // The following DCBM entries provide the data 124 | typedef struct MidiNoteBindingList { 125 | FrameHeader Header; // DCBM id 126 | int NumberOfBindings; 127 | MidiNoteBinding Bindings[NumberOfBindings] ; 128 | }; 129 | 130 | typedef struct MidiDefinition { 131 | FrameHeader Header; // DCDT 132 | int MidiNoteLength; 133 | wchar_t MidiNote[MidiNoteLength]; 134 | DWORD Unknown1; 135 | DWORD Unknown2; 136 | float Velocity; 137 | // Updated by Traktor Pro UI when changed 138 | MidiEncoderMode EncoderMode; 139 | // In the case of Native Instruments devices seems to identify the 140 | // control Id. However this control Id will be the same for e.g. both 141 | // left and right Shift keys (Kontrol S4). Otherwise 0xFFFFFFFF 142 | int ControlId; 143 | }; 144 | 145 | typedef struct MidiOutDefinitions { 146 | FrameHeader Header; // DDCO 147 | int NumberOfEntries; 148 | MidiDefinition Definitions[NumberOfEntries] ; 149 | }; 150 | 151 | typedef struct MidiInDefinitions { 152 | FrameHeader Header; // DDCI 153 | int NumberOfEntries; 154 | MidiDefinition Definitions[NumberOfEntries] ; 155 | }; 156 | 157 | typedef struct MidiDefinitionsContainer { 158 | FrameHeader Header; // DDDC 159 | MidiInDefinitions In; 160 | MidiOutDefinitions Out; 161 | }; 162 | 163 | typedef struct MappingSettings { 164 | FrameHeader Header; // CMAD 165 | // Seems to be always a constant 4 166 | DWORD Unknown1; 167 | MappingControllerType ControllerType; 168 | MappingInteractionMode InteractionMode; 169 | MappingTargetDeck Deck; 170 | int AutoRepeat; 171 | int Invert; 172 | int SoftTakeover; 173 | // 1% in the Traktor UI corresponds to 0.5f 174 | // Traktor sets this to 300% / 15f when 175 | // in Interaction mode is Direct 176 | float RotarySensitivity; 177 | float RotaryAcceleration; 178 | DWORD Unknown10; 179 | DWORD Unknown11; 180 | float SetValueTo; 181 | int CommentLength; 182 | wchar_t Comment[CommentLength]; 183 | // Traktor Control Id 184 | int ModifierOneId; 185 | DWORD Unknown15; 186 | int ModifierOneValue; 187 | int ModifierTwoId; 188 | DWORD Unknown18; 189 | int ModifierTwoValue; 190 | DWORD Unknown20; 191 | float LedMinControllerRange; 192 | DWORD Unknown22; 193 | float LedMaxControllerRange; 194 | int LedMinMidiRange; 195 | int LedMaxMidiRange; 196 | int LedInvert; 197 | int LedBlend; 198 | DWORD Unknown29; 199 | // this field is actually a float under the hood 200 | MappingResolution Resolution; 201 | DWORD Unknown30; 202 | }; 203 | 204 | typedef struct Mapping { 205 | FrameHeader Header; // CMAI 206 | int MidiNoteBindingId; 207 | MappingType Type; 208 | // Basically what UI Control this mapping is for 209 | int TraktorControlId; 210 | MappingSettings Settings; 211 | }; 212 | 213 | typedef struct MappingsList { 214 | FrameHeader Header; // CMAS 215 | int NumberOfMappings; 216 | Mapping Mappings[NumberOfMappings] ; 217 | }; 218 | 219 | typedef struct MappingsContainer { 220 | FrameHeader Header; // DDCB 221 | MappingsList List; 222 | MidiNoteBindingList MidiBindings; 223 | }; 224 | 225 | typedef struct DevicePorts { 226 | FrameHeader Header; // DDPT 227 | int InPortNameLength; 228 | wchar_t InPortName[InPortNameLength] ; 229 | int OutPortNameLength; 230 | wchar_t OutPortName[OutPortNameLength] ; 231 | }; 232 | 233 | typedef struct DeviceData 234 | { 235 | FrameHeader Header; // DDAT 236 | DeviceTargetInfo Target; 237 | VersionInfo Version; 238 | MappingFileComment Comment; 239 | DevicePorts Ports; 240 | MidiDefinitionsContainer MidiDefinitions; 241 | MappingsContainer Mappings; 242 | DVST Unknown; 243 | }; 244 | 245 | typedef struct Device { 246 | FrameHeader Header; // DEVI 247 | int NameLength; 248 | wchar_t Name[NameLength]; 249 | DeviceData Data; 250 | }; 251 | 252 | typedef struct DevicesList { 253 | FrameHeader Header; 254 | // Seems to be a constant 1 255 | int NumberOfDevices; 256 | Device Devices[NumberOfDevices] ; 257 | }; 258 | 259 | 260 | typedef struct DeviceMappingsContainer { 261 | FrameHeader Header; 262 | DIOI DIOI_Unknown; 263 | DevicesList Devices ; 264 | }; 265 | 266 | DeviceMappingsContainer tsi; 267 | --------------------------------------------------------------------------------