Skip to content

Commit a8ac32e

Browse files
authored
Merge pull request #398 from jclsn/traktor-mk2-blogpost
Add a Traktor MK2 blog post
2 parents 1c1b83b + 9ede66a commit a8ac32e

13 files changed

Lines changed: 255 additions & 2 deletions

content/images/avatars/jclsn.png

13.9 KB
Loading

content/images/news/serato-control-cd.svg

Lines changed: 2 additions & 0 deletions
Loading

content/images/news/traktor-mk2-signal-with-derivative.svg

Lines changed: 2 additions & 0 deletions
Loading

content/images/news/traktor-mk2-signal-with-readings.svg

Lines changed: 2 additions & 0 deletions
Loading
720 KB
Loading

content/images/news/traktor-mk2-signal-with-timecodes.svg

Lines changed: 2 additions & 0 deletions
Loading

content/images/news/traktor-mk2-signal-with-zero-crossings.svg

Lines changed: 2 additions & 0 deletions
Loading

content/images/news/traktor-mk2-signal.svg

Lines changed: 2 additions & 0 deletions
Loading
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
title: "How Does Timecode Vinyl Actually Work? (Pt. 3)"
2+
authors: Jan Claußen
3+
tags: traktor, timecode, dvs, vinyl control
4+
status: draft
5+
math: yes
6+
7+
Since its release in 2011, the **Traktor Control Vinyl MK2** has sparked
8+
curiosity among digital DJs and audio developers alike. Its timecode format
9+
stands apart from Serato’s, which we explored in the previous posts. With the
10+
MK2 system, Native Instruments introduced a more advanced timecode that boosts
11+
resolution and accuracy by applying advanced cryptographic techniques.
12+
13+
In this post, we’ll break down how it works at a basic level and how Mixxx is processing the signal.
14+
15+
---
16+
17+
## Recap: How Serato Timecode Works
18+
19+
Serato’s timecode is built around a
20+
[Linear Feedback Shift Register](https://en.wikipedia.org/wiki/Linear-feedback_shift_register),
21+
modulated onto a 1 kHz carrier using
22+
[amplitude modulation (AM)](https://en.wikipedia.org/wiki/Amplitude_modulation) - a legacy
23+
technique from radio transmission.
24+
25+
The demodulation process is relatively simple: when one stereo channel crosses
26+
the x-axis, the other hits a peak. If that peak exceeds a certain threshold,
27+
the system reads it as a **1**, if not, it’s a **0**.
28+
29+
![Serato Timecode Signal]({static}/images/news/serato-control-cd.svg)
30+
31+
We covered this in more detail in
32+
[DVS Internals Pt. 1]({filename}/news/2021-11-21-dvs-internals-pt1.md)
33+
and [Pt. 2]({filename}/news/2021-12-22-dvs-internals-pt2.md).
34+
35+
---
36+
37+
## The Traktor MK2 Signal
38+
39+
Below is a signal that resembles what you’ll find on the Traktor MK2
40+
Control vinyl/CD, which has been specifically generated for this blog post by
41+
using a [Raised-Cosine Filter](https://de.wikipedia.org/wiki/Raised-Cosine-Filter) to
42+
modulate a random sequence onto the carrier.
43+
44+
The carrier wave operates at **2500 Hz**, a significant increase from Serato’s
45+
**1000 Hz**.
46+
47+
> **Advantage:** The higher carrier frequency allows for 2.5× greater resolution.
48+
49+
![Offset-modulated Signal]({static}/images/news/traktor-mk2-signal.svg)
50+
51+
Upon inspection, this waveform clearly doesn’t use amplitude modulation - the
52+
amplitude remains constant. Instead, it appears to be **offset-modulated**,
53+
where the signal is shifted vertically from the x-axis. This is a non-standard
54+
technique not commonly used in typical modulation schemes.
55+
56+
On the original vinyl version (not shown here due to copyright), the offset
57+
can be so large that the signal floats entirely above the x-axis for multiple
58+
cycles - making zero-crossing detection impossible.
59+
60+
Even when that doesn’t happen, the offset causes the time interval $\Delta t$
61+
between zero-crossings to become irregular, introducing audible pitch flutter.
62+
63+
To decode the signal, we must solve:
64+
65+
1. How to filter the signal to enable pitch detection
66+
2. How to demodulate this non-standard modulation
67+
3. How to decipher the code that is modulated onto the carrier
68+
69+
---
70+
71+
## Pitch Detection
72+
73+
> **Note:** If you're unfamiliar with pitch detection in DVS systems, revisit
74+
> [DVS Internals Pt. 1]({filename}/news/2021-11-21-dvs-internals-pt1.md).
75+
76+
Our goal is to produce a signal that oscillates evenly around the x-axis. This
77+
filtered waveform can then be processed by the existing pitch detection algorithm.
78+
79+
A simple discrete derivative operation achieves this:
80+
81+
$$
82+
y[n] = x[n] - x[n-1] \tag{1}
83+
$$
84+
85+
$\text{where:}$<br>
86+
$\text{- x[n]: Input sample}$<br>
87+
$\text{- x[n-1]: Delayed input sample}$<br>
88+
$\text{- y[n]: Difference of both values}$<br>
89+
<br>
90+
91+
When applied to the offset-modulated signal, we get:
92+
93+
![Traktor MK2 signal with derivative]({static}/images/news/traktor-mk2-signal-with-derivative.svg)
94+
95+
The resulting waveform oscillates cleanly around zero, which is ideal for
96+
analysis. It also makes it easier to pinpoint the half-cycle peaks needed for
97+
bit detection.
98+
99+
---
100+
101+
## Demodulation Techniques
102+
103+
To extract bits from the signal, we detect the zero-crossings and sample the
104+
amplitude of the sinusoid at those moments.
105+
106+
![Traktor MK2 signal with
107+
zero-crossings]({static}/images/news/traktor-mk2-signal-with-zero-crossings.svg)
108+
109+
You may notice that the derivative’s zero-crossings don’t align perfectly with
110+
the original peaks. That’s due to a delay introduced by the filter. Smoothing
111+
the signal first, then compensating for the delay (e.g., by selecting
112+
$x[n-3]$), yields better results.
113+
114+
For greater accuracy, one could analyze the phase response $\phi(\omega)$,
115+
which shows how filter delay varies with input frequency - but for this use case,
116+
a fixed delay works well enough.
117+
118+
The filtered signal can cross the x-axis in two directions-positive to
119+
negative or vice versa. Based on the direction, we determine which half-cycle
120+
contains the encoded bit. In this example we only use the upper half-cycle for
121+
decoding, but you can also decode the signal from the lower half-cycle.
122+
123+
![Traktor MK2 signal with readings]({static}/images/news/traktor-mk2-signal-with-readings.svg)
124+
125+
Demodulation is then as simple as applying a threshold: amplitudes above it
126+
are **1**, and below it are **0**.
127+
128+
![Traktor MK2 signal with timecodes]({static}/images/news/traktor-mk2-signal-with-timecodes.svg)
129+
130+
On actual vinyl, the physical behavior of the needle causes the offset to
131+
decay over time, because the needle slowly drifts back to the middle. This decay complicates bit extraction.
132+
133+
To compensate, we analyze the **slope** between subsequent readings by
134+
reusing the derivative equation in $\text{(1)}$.
135+
136+
$$slope[n] = reading[n] - reading[n-1]$$
137+
138+
$\text{where:}$<br>
139+
$\text{- x[n]: Current reading}$<br>
140+
$\text{- x[n-1]: Last reading}$<br>
141+
$\text{- y[n]: Difference of both values}$<br>
142+
<br>
143+
144+
We then decode a positive slope to toggle the bit to **1** and a negative
145+
slope to toggle the bit to **0**.
146+
147+
![Traktor MK2 signal with indicated slope]({static}/images/news/traktor-mk2-signal-with-slope.png)
148+
149+
This method helps isolate the encoded signal from the floating zero line
150+
caused by mechanical drift.
151+
152+
---
153+
154+
## The Code
155+
156+
> **Note:** A deeper explanation of LFSRs can be found in [DVS Internals Pt. 2]({filename}/news/2021-12-22-dvs-internals-pt2.md)
157+
158+
Interestingly, the Traktor MK2 system also uses a [Linear Feedback Shift Register](https://en.wikipedia.org/wiki/Linear-feedback_shift_register) - but with different properties. While Serato’s LFSR has a
159+
**20-bit** length, Traktor’s uses a **110-bit** register with a minimum
160+
run length of two symbols. The generator polynomial of the the LFSR was found
161+
by using the [Berlekamp-Massey algorithm](https://en.wikipedia.org/wiki/Berlekamp%E2%80%93Massey_algorithm).
162+
163+
The number of unique states an LFSR can generate is:
164+
165+
$$n_{max} = 2^m -1$$
166+
167+
Hence for the Serato timecode
168+
169+
$$n_{serato} = 2^{20} -1 = 1\,048\,575$$
170+
171+
and for the Traktor MK2 timecode
172+
173+
$$n_{mk2} = 2^{110} -1 = 1.298 \cdot 10^{33} = 1\,298\,074\,214\,633\,706\,907\,132\,624\,082\,305\,023$$
174+
175+
That’s an astronomically high number-far beyond what’s required for this
176+
application.
177+
178+
But how many states are actually needed? With a 2500 Hz carrier, you get 2500 bits per second.<br>
179+
180+
For 12 minutes of timecode:
181+
182+
$$12 \text{ min} \cdot 60 = 720 \text{ s}$$
183+
$$720 \text{ s} \cdot 2500 \text{ states/s} = 1\,800\,000 \text{ states}$$
184+
185+
which exceeds the maximum state range of Serato’s 20-bit LFSR by far.
186+
187+
However, a downside appears: each 110-bit state must be stored in 128 bits (4
188+
× 32-bit integers).
189+
190+
So for the A-side with 12 minutes:
191+
192+
$$1\,800\,000 \text{ states} \cdot 128 \text{ bit} = 230\,400\,000 \text{ bit} = 28\,800\,000 \text{ byte} = 27.46 \text{ MB}$$
193+
194+
And for a 25-minute CD:
195+
196+
$$4\,500\,000 \text{ states} \cdot 128 \text{ bit} = 576\,000\,000 \text{ bit} = 72\,000\,000 \text{ byte} = 68.66 \text{ MB}$$
197+
198+
> **Disadvantage:** The memory footprint is large-even a single side of timecode can exceed 27 MB.
199+
200+
This makes storing a full lookup table impractical in production software.
201+
202+
It's important to point out that the current implementation is naive, because it treats the
203+
Traktor MK2 code as if it were Serato code. Since Mark Hills designed the xwax
204+
library, which is used by vinyl control in Mixxx, for exactly this style of
205+
timecode, changes would have to be made to make the decoder more modular.
206+
207+
Nonetheless, the current technique works and it represents the current state
208+
of the decoder in Mixxx.
209+
210+
---
211+
212+
## Conclusion
213+
214+
Fortunately, there are mathematical methods to reduce the memory requirements.
215+
This requires diving deeper into the crypthographic theory.
216+
217+
First tests show that this can possibly be achieved by applying a fixed tap
218+
pattern (e.g. every 5th bit) to a 110-bit LFSR window - a form of structured
219+
decimation or undersampling. This collapses the sequence into a 22-bit
220+
[Gold code](https://en.wikipedia.org/wiki/Gold_code), whose two sequences alternate.
221+
The implementation of this technique is far more complex and not completed
222+
yet.
223+
224+
We’ll explore those strategies in the next part of this series.

netlify.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,5 +48,5 @@
4848
[[headers]]
4949
for = "/news/*"
5050
[headers.values]
51-
# Additionally allow YouTube/Discourse frames and scripts
52-
Content-Security-Policy = "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'sha256-UPkidoMErzWw1gW/eY4LhAi9ZkPch3PP31d6KQoJ6Yc=' 'sha256-G40wI6OaLZXCtrb02xUq1H1kEVWjstzoQ0FXKwsWxPw=' https://mixxx.discourse.group/javascripts/embed.js *.discourse-cdn.com; frame-src 'self' https://www.youtube-nocookie.com https://mixxx.discourse.group ; img-src 'self' https://i.ytimg.com https://raw.githubusercontent.com/mixxxdj/ ; connect-src 'self' https://mixxx.discourse.group https://*.discourse-cdn.com"
51+
# Additionally allow YouTube/Discourse frames and scripts and MathJax
52+
Content-Security-Policy = "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'sha256-UPkidoMErzWw1gW/eY4LhAi9ZkPch3PP31d6KQoJ6Yc=' 'sha256-G40wI6OaLZXCtrb02xUq1H1kEVWjstzoQ0FXKwsWxPw=' 'sha256-1CldwzdEg2k1wTmf7s5RWVd7NMXI/7nxxjJM2C4DqII=' https://mixxx.discourse.group/javascripts/embed.js *.discourse-cdn.com; frame-src 'self' https://www.youtube-nocookie.com https://mixxx.discourse.group ; img-src 'self' https://i.ytimg.com ; connect-src 'self' https://mixxx.discourse.group https://*.discourse-cdn.com"

0 commit comments

Comments
 (0)