Merge lp:~mixxxdevelopers/mixxx/fixes_scratch into lp:~mixxxdevelopers/mixxx/trunk
- fixes_scratch
- Merge into trunk
Proposed by
Albert Santoni
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Merge reported by: | Albert Santoni | ||||||||
Merged at revision: | not available | ||||||||
Proposed branch: | lp:~mixxxdevelopers/mixxx/fixes_scratch | ||||||||
Merge into: | lp:~mixxxdevelopers/mixxx/trunk | ||||||||
Diff against target: |
533 lines (+130/-93) 5 files modified
mixxx/res/midi/Stanton-SCS3d-scripts.js (+56/-55) mixxx/res/midi/midi-mappings-scripts.js (+38/-18) mixxx/src/controlvaluedelegate.cpp (+1/-0) mixxx/src/engine/ratecontrol.cpp (+33/-19) mixxx/src/engine/ratecontrol.h (+2/-1) |
||||||||
To merge this branch: | bzr merge lp:~mixxxdevelopers/mixxx/fixes_scratch | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Albert Santoni | Approve | ||
Review via email:
|
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message

Albert Santoni (gamegod) wrote : | # |
- 2363. By Sean M. Pappalardo
-
- Added new behavior flag to common scripts so old behavior can still work seamlessly, SCS.3d script uses new (This flag will be removed after the deprecation period)
- Fixed variable naming errors in common scripts!
- Added line breaks to long print lines
Revision history for this message

Albert Santoni (gamegod) wrote : | # |
Changes to the engine are minimal. Approving...
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'mixxx/res/midi/Stanton-SCS3d-scripts.js' |
2 | --- mixxx/res/midi/Stanton-SCS3d-scripts.js 2010-03-06 21:46:14 +0000 |
3 | +++ mixxx/res/midi/Stanton-SCS3d-scripts.js 2010-04-29 07:06:29 +0000 |
4 | @@ -23,9 +23,8 @@ |
5 | StantonSCS3d.deckChangeWait = 1000; // Time in milliseconds to hold the DECK button down to avoid changing decks (multi deck mode) |
6 | |
7 | // These values are heavily latency-dependent. They're preset for 10ms and will need tuning for other latencies. (For 2ms, try 0.885, 0.15, and 1.5.) |
8 | -StantonSCS3d.scratching = { "slippage":0.8, // Slipperiness of the virtual slipmat when scratching with the circle (higher=slower response, 0<n<1) |
9 | - "sensitivity":0.2, // How much the audio moves for a given circle arc (higher=faster response, 0<n<1) |
10 | - "stoppedMultiplier":1.7 }; // Correction for when the deck is stopped (set higher for higher latencies) |
11 | +StantonSCS3d.scratching = { "slippage":0.7, // Slipperiness of the virtual slipmat when scratching with the circle (higher=slower response, 0<n<1) |
12 | + "sensitivity":0.2 }; // How much the audio moves for a given circle arc (higher=faster response, 0<n<1) |
13 | |
14 | // ---------- Other global variables ---------- |
15 | StantonSCS3d.debug = false; // Enable/disable debugging messages to the console |
16 | @@ -47,7 +46,7 @@ |
17 | StantonSCS3d.surface = { "C1":0x00, "S5":0x01, "S3":0x02, "S3+S5":0x03, "Buttons":0x04 }; |
18 | StantonSCS3d.sysex = [0xF0, 0x00, 0x01, 0x60]; // Preamble for all SysEx messages for this device |
19 | // Variables used in the scratching alpha-beta filter: (revtime = 1.8 to start) |
20 | -StantonSCS3d.scratch = { "revtime":1.8, "alpha":0.1, "beta":1.0, "touching":false }; |
21 | +StantonSCS3d.scratch = { "revtime":4.0, "alpha":0.1, "beta":1.0, "touching":false }; |
22 | StantonSCS3d.trackDuration = [0,0]; // Duration of the song on each deck (used for vinyl LEDs) |
23 | StantonSCS3d.lastLight = [-1,-1]; // Last circle LED values |
24 | StantonSCS3d.lastLoop = 0; // Last-used loop LED |
25 | @@ -667,11 +666,8 @@ |
26 | case "vinyl": |
27 | case "vinyl2": |
28 | // So we don't get stuck at some strange speed when switching from a scratching mode |
29 | - engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch", 0); |
30 | - if (StantonSCS3d.scratch["wasPlaying"]) { // to avoid getting stuck stopped |
31 | - engine.setValue("[Channel"+StantonSCS3d.deck+"]","play",1); |
32 | - StantonSCS3d.scratch["wasPlaying"] = false; |
33 | - } |
34 | + engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2_enable", 0); |
35 | + engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2", 0); |
36 | break; |
37 | case "loop2": |
38 | case "loop3": |
39 | @@ -855,11 +851,9 @@ |
40 | StantonSCS3d.modifier["deck"]=0; // Clear button modifier flag |
41 | StantonSCS3d.connectSurfaceSignals(channel,true); // Disconnect surface signals & turn off surface LEDs |
42 | StantonSCS3d.mode_store["[Channel"+StantonSCS3d.deck+"]"] = StantonSCS3d.state["deckPrev"]; |
43 | - engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch", 0); // To avoid getting stuck at a weird speed |
44 | - if (StantonSCS3d.scratch["wasPlaying"]) { // to avoid the deck stopping |
45 | - engine.setValue("[Channel"+StantonSCS3d.deck+"]","play",1); |
46 | - StantonSCS3d.scratch["wasPlaying"] = false; |
47 | - } |
48 | + // To avoid getting stuck at a weird speed |
49 | + engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2_enable", 0); |
50 | + engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2", 0); |
51 | var newMode; |
52 | // In default multiple-deck mode, |
53 | // If the button's been held down for longer than the specified time, stay on the current deck. |
54 | @@ -960,12 +954,12 @@ |
55 | if (currentMode=="vinyl2" && StantonSCS3d.vinyl2ScratchMethod=="pp") { |
56 | var group = "[Channel"+StantonSCS3d.deck+"]"; |
57 | var jogValue = (value-64); |
58 | - if (engine.getValue(group,"play")==1 && engine.getValue(group,"reverse")==1) jogValue= -(jogValue); |
59 | + if (engine.getValue(group,"reverse")==1) jogValue= -(jogValue); |
60 | |
61 | - var multiplier = StantonSCS3d.scratching["sensitivity"] * (engine.getValue(group,"play") ? 1 : StantonSCS3d.scratching["stoppedMultiplier"] ); |
62 | + var multiplier = StantonSCS3d.scratching["sensitivity"]/2; |
63 | // if (StantonSCS3d.debug) print("do scratching VALUE:" + value + " jogValue: " + jogValue ); |
64 | multiplier = multiplier * 0.5; // Reduce sensitivity of the slider since it's lower res |
65 | - engine.setValue(group,"scratch", (engine.getValue(group,"scratch") + (jogValue * multiplier)).toFixed(2)); |
66 | + engine.setValue(group,"scratch2", (engine.getValue(group,"scratch2") + (jogValue * multiplier)).toFixed(2)); |
67 | } |
68 | } |
69 | |
70 | @@ -996,12 +990,12 @@ |
71 | var byte1 = 0xB0 + channel; |
72 | midi.sendShortMsg(byte1,0x01,add); //S4 LEDs |
73 | if (!StantonSCS3d.VUMeters || StantonSCS3d.deck!=1) midi.sendShortMsg(byte1,0x0C,add); //S3 LEDs |
74 | - if (!StantonSCS3d.VUMeters || StantonSCS3d.deck!=2)midi.sendShortMsg(byte1,0x0E,add); //S5 LEDs |
75 | + if (!StantonSCS3d.VUMeters || StantonSCS3d.deck!=2) midi.sendShortMsg(byte1,0x0E,add); //S5 LEDs |
76 | |
77 | if (currentMode=="vinyl" || StantonSCS3d.vinyl2ScratchMethod == "a-b") { // this is only for the alpha-beta filter implementation |
78 | // Call global scratch slider function |
79 | var newScratchValue = scratch.slider(StantonSCS3d.deck, value, StantonSCS3d.scratch["revtime"], StantonSCS3d.scratch["alpha"], StantonSCS3d.scratch["beta"]); |
80 | - engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch",newScratchValue); |
81 | + engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2",newScratchValue); |
82 | } |
83 | break; |
84 | case "loop2": |
85 | @@ -1081,13 +1075,12 @@ |
86 | switch (currentMode) { |
87 | // case "vinyl": |
88 | case "vinyl2": |
89 | - if (StantonSCS3d.vinyl2ScratchMethod == "a-b") scratch.enable(StantonSCS3d.deck); |
90 | + if (StantonSCS3d.vinyl2ScratchMethod == "a-b") scratch.enable(StantonSCS3d.deck, true); |
91 | else { |
92 | StantonSCS3d.scratch["touching"] = true; |
93 | + engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2_enable", 1); |
94 | if (engine.getValue("[Channel"+StantonSCS3d.deck+"]","play")==1) { |
95 | - engine.setValue("[Channel"+StantonSCS3d.deck+"]","play",0); |
96 | - engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch",(1+engine.getValue("[Channel"+StantonSCS3d.deck+"]","scratch"))); // So it ramps down when you touch |
97 | - StantonSCS3d.scratch["wasPlaying"] = true; |
98 | + engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2",(1+engine.getValue("[Channel"+StantonSCS3d.deck+"]","scratch2"))); // So it ramps down when you touch |
99 | } |
100 | } |
101 | break; |
102 | @@ -1098,7 +1091,9 @@ |
103 | case "vinyl": break; |
104 | case "vinyl2": |
105 | if (StantonSCS3d.vinyl2ScratchMethod == "a-b") scratch.disable(StantonSCS3d.deck); |
106 | - else StantonSCS3d.scratch["touching"] = false; |
107 | + else { |
108 | + StantonSCS3d.scratch["touching"] = false; |
109 | + } |
110 | break; |
111 | default: midi.sendShortMsg(byte1,0x62,0x00); // Turn off C1 lights |
112 | break; |
113 | @@ -1143,13 +1138,14 @@ |
114 | switch (currentMode) { |
115 | case "vinyl": // Store scratch info the point it was touched |
116 | case "vinyl2": |
117 | - if (currentMode=="vinyl" || StantonSCS3d.vinyl2ScratchMethod == "a-b") scratch.enable(StantonSCS3d.deck); |
118 | + if (currentMode=="vinyl" || StantonSCS3d.vinyl2ScratchMethod == "a-b") scratch.enable(StantonSCS3d.deck, true); |
119 | else { |
120 | StantonSCS3d.scratch["touching"] = true; |
121 | + engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2_enable", 1); |
122 | if (engine.getValue("[Channel"+StantonSCS3d.deck+"]","play")==1) { |
123 | - engine.setValue("[Channel"+StantonSCS3d.deck+"]","play",0); |
124 | - engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch",(1+engine.getValue("[Channel"+StantonSCS3d.deck+"]","scratch"))); // So it ramps down when you touch |
125 | - StantonSCS3d.scratch["wasPlaying"] = true; |
126 | + // So it ramps down when you touch |
127 | + engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2", |
128 | + (1+engine.getValue("[Channel"+StantonSCS3d.deck+"]","scratch2"))); |
129 | } |
130 | } |
131 | break; |
132 | @@ -1179,7 +1175,9 @@ |
133 | case "vinyl": // Reset the triggers |
134 | case "vinyl2": |
135 | if (currentMode=="vinyl" || StantonSCS3d.vinyl2ScratchMethod == "a-b") scratch.disable(StantonSCS3d.deck); |
136 | - else StantonSCS3d.scratch["touching"] = false; |
137 | + else { |
138 | + StantonSCS3d.scratch["touching"] = false; |
139 | + } |
140 | var byte1a = 0xB0 + channel; |
141 | midi.sendShortMsg(byte1a,0x01,0x00); //S4 LEDs off |
142 | if (!StantonSCS3d.VUMeters || StantonSCS3d.deck!=1) midi.sendShortMsg(byte1a,0x0C,0x00); //S3 LEDs off |
143 | @@ -1305,7 +1303,6 @@ |
144 | var currentMode = StantonSCS3d.mode_store["[Channel"+StantonSCS3d.deck+"]"]; |
145 | switch (currentMode) { |
146 | case "vinyl": |
147 | -// if (currentMode=="deck") return; // ignore if the cross-fader is being adjusted |
148 | var newValue=(value-64); |
149 | // print("C1="+value+", jog="+newValue); |
150 | engine.setValue("[Channel"+StantonSCS3d.deck+"]","jog",newValue); |
151 | @@ -1316,12 +1313,11 @@ |
152 | var jogValue = (value-64); |
153 | if (engine.getValue(group,"play")==1 && engine.getValue(group,"reverse")==1) jogValue= -(jogValue); |
154 | |
155 | - var multiplier = StantonSCS3d.scratching["sensitivity"] * (engine.getValue(group,"play") ? 1 : StantonSCS3d.scratching["stoppedMultiplier"] ); |
156 | + var multiplier = StantonSCS3d.scratching["sensitivity"]; |
157 | // if (StantonSCS3d.debug) print("do scratching VALUE:" + value + " jogValue: " + jogValue ); |
158 | - engine.setValue(group,"scratch", (engine.getValue(group,"scratch") + (jogValue * multiplier)).toFixed(2)); |
159 | + engine.setValue(group,"scratch2", (engine.getValue(group,"scratch2") + (jogValue * multiplier)).toFixed(2)); |
160 | break; |
161 | case "vinyl3": |
162 | -// if (currentMode=="deck") return; // ignore if the cross-fader is being adjusted |
163 | if ((value-64)>0) { |
164 | engine.setValue("[Playlist]","SelectNextTrack",1); |
165 | } |
166 | @@ -1339,7 +1335,7 @@ |
167 | // // Slower response for jog wheel |
168 | // var newValue = scratch.wheel(StantonSCS3d.deck, value, 1.8, StantonSCS3d.scratch["alpha"], 1.0); |
169 | // print("StantonSCS3d: newValue="+newValue); |
170 | -// engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch",newValue); |
171 | +// engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2",newValue); |
172 | break; |
173 | case "vinyl2": |
174 | if (StantonSCS3d.vinyl2ScratchMethod != "a-b") break; // this is only for the alpha-beta filter implementation |
175 | @@ -1349,7 +1345,7 @@ |
176 | // Call global scratch wheel function |
177 | var newScratchValue = scratch.wheel(StantonSCS3d.deck, value, StantonSCS3d.scratch["revtime"], StantonSCS3d.scratch["alpha"], StantonSCS3d.scratch["beta"]); |
178 | |
179 | - engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch",newScratchValue); |
180 | + engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2",newScratchValue); |
181 | break; |
182 | default: |
183 | // Light the LEDs |
184 | @@ -1688,7 +1684,8 @@ |
185 | } |
186 | |
187 | // Revolution time of the imaginary record in seconds |
188 | - var revtime = StantonSCS3d.scratch["revtime"]; |
189 | + var revtime = 1.8; // 1.8s at 33 1/3 RPM |
190 | +// var revtime = StantonSCS3d.scratch["revtime"]; |
191 | if (StantonSCS3d.spinningLights==2) revtime = StantonSCS3d.scratch["revtime"]/2; // Use this for two lights |
192 | var currentTrackPos = value * StantonSCS3d.trackDuration[StantonSCS3d.deck]; |
193 | |
194 | @@ -1710,34 +1707,38 @@ |
195 | StantonSCS3d.wheelDecay = function (value) { |
196 | |
197 | if (StantonSCS3d.mode_store["[Channel"+StantonSCS3d.deck+"]"]=="vinyl2") { // Only in Vinyl2 mode |
198 | - var scratch = engine.getValue("[Channel"+StantonSCS3d.deck+"]","scratch"); |
199 | - var jogDecayRate = StantonSCS3d.scratching["slippage"] * (engine.getValue("[Channel"+StantonSCS3d.deck+"]","play") ? 1 : 1.1 ); |
200 | + var scratch = engine.getValue("[Channel"+StantonSCS3d.deck+"]","scratch2"); |
201 | + var jogDecayRate = StantonSCS3d.scratching["slippage"] * 1.1; // 0.2 |
202 | |
203 | - if (StantonSCS3d.debug) print("Scratch deck"+StantonSCS3d.deck+": " + scratch + ", Jog decay rate="+jogDecayRate); |
204 | +// if (StantonSCS3d.debug) print("Scratch deck"+StantonSCS3d.deck+": " + scratch + ", Jog decay rate="+jogDecayRate); |
205 | |
206 | // If it was playing, ramp back to playback speed |
207 | - if (StantonSCS3d.scratch["wasPlaying"] && !StantonSCS3d.scratch["touching"]) { |
208 | + if (engine.getValue("[Channel"+StantonSCS3d.deck+"]","play")==1 && !StantonSCS3d.scratch["touching"]) { |
209 | var rate = engine.getValue("[Channel"+StantonSCS3d.deck+"]","rate") * engine.getValue("[Channel"+StantonSCS3d.deck+"]","rateRange"); |
210 | var convergeTo = 1+rate; |
211 | - //jogDecayRate = StantonSCS3d.scratching["slippage"] * 0.2; |
212 | if (scratch != convergeTo) { // Thanks to jusics on IRC for help with this part |
213 | - if (Math.abs(scratch-convergeTo) > jogDecayRate*0.001) { |
214 | - engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch", (convergeTo + (scratch-convergeTo) * jogDecayRate).toFixed(5)); |
215 | - //engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch", (scratch + (convergeTo - scratch) / jogDecayRate).toFixed(5)); |
216 | + if (Math.abs(scratch-convergeTo) > jogDecayRate*0.001) { |
217 | + engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2", |
218 | + (convergeTo + (scratch-convergeTo) * jogDecayRate).toFixed(5)); |
219 | + //engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2", (scratch + (convergeTo - scratch) / jogDecayRate).toFixed(5)); |
220 | } else { |
221 | - // Once "scratch" has gotten close enough to the play speed, just resume normal playback |
222 | - engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch", 0); |
223 | - engine.setValue("[Channel"+StantonSCS3d.deck+"]","play",1); |
224 | - StantonSCS3d.scratch["wasPlaying"] = false; |
225 | + // Once "scratch2" has gotten close enough to the play speed, just resume normal playback |
226 | + engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2", 0); |
227 | + engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2_enable", 0); |
228 | } |
229 | } |
230 | - } else |
231 | - if (scratch != 0) { // For regular scratching when stopped or if playing (and ramp down...touch functions set scratch=1 and play=0) |
232 | - if (Math.abs(scratch) > jogDecayRate*0.001) { |
233 | - engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch", (scratch * jogDecayRate).toFixed(4)); |
234 | - } else { |
235 | - engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch", 0); |
236 | - } |
237 | + } |
238 | + else if (scratch != 0) { |
239 | + // For regular scratching when stopped or if playing and ramp down |
240 | + if (Math.abs(scratch) > jogDecayRate*0.001) { |
241 | + var value=(scratch * jogDecayRate).toFixed(5); |
242 | + engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2", value); |
243 | + if (StantonSCS3d.debug) print("Scratch deck"+StantonSCS3d.deck+": " + value + ", Jog decay rate="+jogDecayRate); |
244 | + } else { |
245 | + engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2", 0); |
246 | + if (!StantonSCS3d.scratch["touching"]) engine.setValue("[Channel"+StantonSCS3d.deck+"]","scratch2_enable", 0); |
247 | + if (StantonSCS3d.debug) print("Scratch deck"+StantonSCS3d.deck+": 0, Jog decay rate="+jogDecayRate); |
248 | + } |
249 | } |
250 | } |
251 | } |
252 | |
253 | === modified file 'mixxx/res/midi/midi-mappings-scripts.js' |
254 | --- mixxx/res/midi/midi-mappings-scripts.js 2010-03-20 02:33:20 +0000 |
255 | +++ mixxx/res/midi/midi-mappings-scripts.js 2010-04-29 07:06:29 +0000 |
256 | @@ -33,7 +33,7 @@ |
257 | msecs = Math.round(msecs * 100 / 1000); |
258 | if (msecs==100) msecs=99; |
259 | |
260 | - print("secs="+secs+", msecs="+msecs); |
261 | +// print("secs="+secs+", msecs="+msecs); |
262 | |
263 | return (m < 10 ? "0" + m : m) |
264 | + ":" |
265 | @@ -43,8 +43,10 @@ |
266 | } |
267 | |
268 | function script() {} |
269 | -script.debug = function (channel, control, value, status) { |
270 | - print("Script.Debug --- channel: " + channel.toString(16) + " control: " + control.toString(16) + " value: " + value.toString(16) + " status: " + status.toString(16)); |
271 | +script.debug = function (channel, control, value, status, group) { |
272 | + print("Script.Debug --- channel: " + channel.toString(16) + |
273 | + " control: " + control.toString(16) + " value: " + value.toString(16) + |
274 | + " status: " + status.toString(16) + " group: " + group); |
275 | } |
276 | |
277 | // Used to control a generic Mixxx control setting (low..high) from an absolute control (0..127) |
278 | @@ -64,7 +66,9 @@ |
279 | script.absoluteEQ = function (group, key, value) { |
280 | if (value<=64) engine.setValue(group, key, value/64); |
281 | else engine.setValue(group, key, 1+(value-63)/(21+1/3)); |
282 | - print ("MIDI Script: script.absoluteEQ is deprecated. Use script.absoluteNonLin(value,0,1,4) instead and set the MixxxControl to its return value."); |
283 | + print ("MIDI Script: script.absoluteEQ is deprecated. " + |
284 | + "Use script.absoluteNonLin(value,0,1,4) instead and set the " + |
285 | + "MixxxControl to its return value."); |
286 | } |
287 | |
288 | /* -------- ------------------------------------------------------ |
289 | @@ -134,7 +138,9 @@ |
290 | // See full details here: http://mixxx.org/wiki/doku.php/midi_scripting#available_common_functions |
291 | |
292 | // ---------- Variables ---------- |
293 | -scratch.variables = { "time":0.0, "trackPos":0.0, "initialTrackPos":-1.0, "initialControlValue":0, "scratch":0.0, "prevControlValue":0, "wrapCount":0 }; |
294 | +scratch.variables = { "time":0.0, "trackPos":0.0, "initialTrackPos":-1.0, |
295 | + "initialControlValue":0, "scratch":0.0, |
296 | + "prevControlValue":0, "wrapCount":0 }; |
297 | |
298 | // ---------- Functions ---------- |
299 | |
300 | @@ -146,19 +152,18 @@ |
301 | Input: Currently-controlled Mixxx deck |
302 | Output: - |
303 | -------- ------------------------------------------------------ */ |
304 | -scratch.enable = function (currentDeck) { |
305 | +scratch.enable = function (currentDeck,newBehavior) { |
306 | // Store scratch info at the point it was touched |
307 | // Current position in seconds: |
308 | - scratch.variables["initialTrackPos"] = scratch.variables["trackPos"] = engine.getValue("[Channel"+currentDeck+"]","playposition") * engine.getValue("[Channel"+currentDeck+"]","duration"); |
309 | + scratch.variables["initialTrackPos"] = scratch.variables["trackPos"] = engine.getValue("[Channel"+currentDeck+"]","visual_playposition") * engine.getValue("[Channel"+currentDeck+"]","duration"); |
310 | |
311 | scratch.variables["time"] = new Date()/1000; // Current time in seconds |
312 | + if (newBehavior) engine.setValue("[Channel"+currentDeck+"]","scratch2_enable", 1); |
313 | |
314 | - // Stop the deck motion. This means we have to pause it if playing |
315 | + // If the deck is playing, slow it to a stop |
316 | if (engine.getValue("[Channel"+currentDeck+"]","play") > 0) { |
317 | - scratch.variables["play"]=true; |
318 | -// engine.setValue("[Channel"+currentDeck+"]","play",0); // pause playback |
319 | + // TODO: ramp down |
320 | } |
321 | - else scratch.variables["play"]=false; |
322 | |
323 | // print("MIDI Script: Scratch initial: time=" + scratch.variables["time"] + "s, track=" + scratch.variables["trackPos"] + "s"); |
324 | return; |
325 | @@ -172,6 +177,10 @@ |
326 | Output: - |
327 | -------- ------------------------------------------------------ */ |
328 | scratch.disable = function (currentDeck) { |
329 | + // If the deck is playing, ramp it up to the play speed |
330 | + if (engine.getValue("[Channel"+currentDeck+"]","play") > 0) { |
331 | + //TODO: ramp up |
332 | + } |
333 | // Reset the triggers |
334 | scratch.variables["trackPos"] = 0.0; |
335 | scratch.variables["initialTrackPos"] = -1.0; |
336 | @@ -181,8 +190,9 @@ |
337 | scratch.variables["time"] = 0.0; |
338 | scratch.variables["scratch"] = 0.0; |
339 | // print("MIDI Script: Scratch values CLEARED"); |
340 | - engine.setValue("[Channel"+currentDeck+"]","scratch",0.0); // disable scratching |
341 | - if (scratch.variables["play"]) engine.setValue("[Channel"+currentDeck+"]","play",1); // resume playback |
342 | + engine.setValue("[Channel"+currentDeck+"]","scratch2_enable", 0); // disable scratching |
343 | + engine.setValue("[Channel"+currentDeck+"]","scratch2",0); |
344 | + engine.setValue("[Channel"+currentDeck+"]","scratch",0); // Deprecated |
345 | } |
346 | |
347 | /* -------- ------------------------------------------------------ |
348 | @@ -201,8 +211,13 @@ |
349 | // If the slider start value hasn't been set yet, set it |
350 | if (scratch.variables["initialControlValue"] == 0) { |
351 | scratch.variables["initialControlValue"] = sliderValue; |
352 | + if (engine.getValue("[Channel"+currentDeck+"]","play") > 0) { |
353 | + scratch.variables["scratch"] = 1; |
354 | + engine.setValue("[Channel"+currentDeck+"]","scratch2", 1); |
355 | + } |
356 | +// engine.setValue("[Channel"+currentDeck+"]","scratch2_enable", 1); |
357 | // print("Initial slider="+scratch.variables["initialControlValue"]); |
358 | - } |
359 | + } |
360 | return scratch.filter(currentDeck, sliderValue, revtime, alpha, beta); |
361 | } |
362 | |
363 | @@ -222,8 +237,13 @@ |
364 | // If the wheel start value hasn't been set yet, set it |
365 | if (scratch.variables["initialControlValue"] == 0) { |
366 | scratch.variables["initialControlValue"] = scratch.variables["prevControlValue"] = wheelValue; |
367 | + if (engine.getValue("[Channel"+currentDeck+"]","play") > 0) { |
368 | + scratch.variables["scratch"] = 1; |
369 | + engine.setValue("[Channel"+currentDeck+"]","scratch2", 1); |
370 | + } |
371 | +// engine.setValue("[Channel"+currentDeck+"]","scratch2_enable", 1); |
372 | // print("Initial wheel="+scratch.variables["initialControlValue"]); |
373 | - } |
374 | + } |
375 | |
376 | // Take wrap around into account |
377 | if (wheelValue>=0 && wheelValue<10 && scratch.variables["prevControlValue"]>117 && scratch.variables["prevControlValue"]<=127) scratch.variables["wrapCount"]+=1; |
378 | @@ -244,7 +264,7 @@ |
379 | // ideal position = (initial_p + (y - x) / 128 * 1.8) |
380 | var ideal_p = scratch.variables["initialTrackPos"] + (controlValue - scratch.variables["initialControlValue"]) / 128 * revtime; |
381 | |
382 | - var currentTrackPos = engine.getValue("[Channel"+currentDeck+"]","playposition") * engine.getValue("[Channel"+currentDeck+"]","duration"); |
383 | + var currentTrackPos = engine.getValue("[Channel"+currentDeck+"]","visual_playposition") * engine.getValue("[Channel"+currentDeck+"]","duration"); |
384 | var newTime = new Date()/1000; |
385 | var dt = newTime - scratch.variables["time"]; |
386 | scratch.variables["time"] = newTime; |
387 | @@ -259,13 +279,13 @@ |
388 | // scratch.variables["trackPos"] += rx * alpha; // Don't need this result so why waste the CPU time? |
389 | |
390 | // v += rx * BETA / dt; |
391 | - // scratch.variables["scratch"] += rx * (beta / dt); // This doesn't work |
392 | +// scratch.variables["scratch"] += rx * beta / dt; // This doesn't work |
393 | scratch.variables["scratch"] = rx * beta; |
394 | |
395 | // print("MIDI Script: Ideal position="+ideal_p+", Predicted position="+predicted_p + ", New scratch val=" + scratch.variables["scratch"]); |
396 | |
397 | // var newPos = scratch.variables["trackPos"]/engine.getValue("[Channel"+currentDeck+"]","duration"); |
398 | -// engine.setValue("[Channel"+currentDeck+"]","playposition",newPos); |
399 | +// engine.setValue("[Channel"+currentDeck+"]","visual_playposition",newPos); |
400 | // engine.setValue("[Channel"+currentDeck+"]","scratch",scratch.variables["scratch"]); |
401 | |
402 | return scratch.variables["scratch"]; |
403 | |
404 | === modified file 'mixxx/src/controlvaluedelegate.cpp' |
405 | --- mixxx/src/controlvaluedelegate.cpp 2009-09-01 15:33:21 +0000 |
406 | +++ mixxx/src/controlvaluedelegate.cpp 2010-04-29 07:06:29 +0000 |
407 | @@ -47,6 +47,7 @@ |
408 | m_channelControlValues.append("rate_perm_up_small"); |
409 | m_channelControlValues.append("rateRange"); |
410 | m_channelControlValues.append("scratch"); |
411 | + m_channelControlValues.append("scratch_enable"); |
412 | m_channelControlValues.append("transform"); |
413 | m_channelControlValues.append("volume"); |
414 | m_channelControlValues.append("wheel"); |
415 | |
416 | === modified file 'mixxx/src/engine/ratecontrol.cpp' |
417 | --- mixxx/src/engine/ratecontrol.cpp 2010-03-20 21:14:06 +0000 |
418 | +++ mixxx/src/engine/ratecontrol.cpp 2010-04-29 07:06:29 +0000 |
419 | @@ -116,7 +116,13 @@ |
420 | // Scratch controller, this is an accumulator which is useful for |
421 | // controllers that return individiual +1 or -1s, these get added up and |
422 | // cleared when we read |
423 | - m_pScratch = new ControlTTRotary(ConfigKey(_group, "scratch")); |
424 | + m_pScratch = new ControlTTRotary(ConfigKey(_group, "scratch2")); |
425 | + m_pOldScratch = new ControlTTRotary(ConfigKey(_group, "scratch")); // Deprecated |
426 | + |
427 | + // Scratch enable toggle |
428 | + m_pScratchToggle = new ControlPushButton(ConfigKey(_group, "scratch2_enable")); |
429 | + m_pScratchToggle->set(0); |
430 | + m_pScratchToggle->setToggleButton(true); |
431 | |
432 | m_pJog = new ControlObject(ConfigKey(_group, "jog")); |
433 | m_pJogFilter = new Rotary(); |
434 | @@ -156,6 +162,7 @@ |
435 | |
436 | delete m_pWheel; |
437 | delete m_pScratch; |
438 | + delete m_pOldScratch; |
439 | delete m_pJog; |
440 | delete m_pJogFilter; |
441 | } |
442 | @@ -309,20 +316,6 @@ |
443 | m_pRateDir->get(); |
444 | } |
445 | |
446 | -double RateControl::getScratchFactor() { |
447 | - double scratchFactor = m_pScratch->get(); |
448 | - if(!isnan(scratchFactor) && scratchFactor != 0.0f) { |
449 | - if (scratchFactor < 0.) { |
450 | - scratchFactor = scratchFactor - 1.0f; |
451 | - } else if (scratchFactor > 0.) { |
452 | - scratchFactor = scratchFactor + 1.0f; |
453 | - } |
454 | - } else { |
455 | - scratchFactor = 1.0f; |
456 | - } |
457 | - return scratchFactor; |
458 | -} |
459 | - |
460 | double RateControl::getWheelFactor() { |
461 | // Calculate wheel (experimental formula) |
462 | return 40 * m_pWheel->get(); |
463 | @@ -350,17 +343,27 @@ |
464 | double RateControl::calculateRate(double baserate, bool paused) { |
465 | double rate = 0.0; |
466 | double wheelFactor = getWheelFactor(); |
467 | - double scratchFactor = getScratchFactor(); |
468 | double jogFactor = getJogFactor(); |
469 | bool searching = m_pRateSearch->get() != 0.; |
470 | + bool scratchEnable = m_pScratchToggle->get() != 0; |
471 | + double scratchFactor = m_pScratch->get(); |
472 | + double oldScratchFactor = m_pOldScratch->get(); // Deprecated |
473 | + // Don't trust values from m_pScratch |
474 | + if(isnan(scratchFactor)) { |
475 | + scratchFactor = 0.0; |
476 | + } |
477 | + if(isnan(oldScratchFactor)) { |
478 | + oldScratchFactor = 0.0; |
479 | + } |
480 | |
481 | if (searching) { |
482 | // If searching is in progress, it overrides the playback rate. |
483 | rate = m_pRateSearch->get(); |
484 | } else if (paused) { |
485 | // Stopped. Wheel, jog and scratch controller all scrub through audio. |
486 | - // Scratch is centered around 1.0, so subtract 1.0 |
487 | - rate = scratchFactor - 1.0f + jogFactor + wheelFactor/10.; |
488 | + // New scratch behavior overrides old |
489 | + if (scratchEnable) rate = scratchFactor + jogFactor + wheelFactor/10.; |
490 | + else rate = oldScratchFactor + jogFactor + wheelFactor/10.; // Just remove oldScratchFactor in future |
491 | } else { |
492 | // The buffer is playing, so calculate the buffer rate. |
493 | |
494 | @@ -372,7 +375,18 @@ |
495 | |
496 | rate = 1. + getRawRate() + getTempRate(); |
497 | rate += wheelFactor/10.; |
498 | - rate *= scratchFactor; |
499 | + |
500 | + // New scratch behavior - overrides playback speed (and old behavior) |
501 | + if (scratchEnable) rate *= scratchFactor; |
502 | + // Deprecated old scratch behavior |
503 | + else { |
504 | + if (oldScratchFactor < 0.) { |
505 | + rate *= (oldScratchFactor-1.); |
506 | + } else if (oldScratchFactor > 0.) { |
507 | + rate *= (oldScratchFactor+1.); |
508 | + } |
509 | + } |
510 | + |
511 | rate += jogFactor; |
512 | |
513 | // If we are reversing, flip the rate. |
514 | |
515 | === modified file 'mixxx/src/engine/ratecontrol.h' |
516 | --- mixxx/src/engine/ratecontrol.h 2010-01-05 03:57:34 +0000 |
517 | +++ mixxx/src/engine/ratecontrol.h 2010-04-29 07:06:29 +0000 |
518 | @@ -66,7 +66,6 @@ |
519 | private: |
520 | double getJogFactor(); |
521 | double getWheelFactor(); |
522 | - double getScratchFactor(); |
523 | |
524 | /** Set rate change of the temporary pitch rate */ |
525 | void setRateTemp(double v); |
526 | @@ -95,6 +94,8 @@ |
527 | |
528 | ControlTTRotary* m_pWheel; |
529 | ControlTTRotary* m_pScratch; |
530 | + ControlTTRotary* m_pOldScratch; |
531 | + ControlPushButton* m_pScratchToggle; |
532 | ControlObject* m_pJog; |
533 | Rotary* m_pJogFilter; |
534 |
Needs testing with SCS.3d and vinyl control.