Hey RJ, welcome back:)
On Wed, 29 May 2013 15:40:04 -0400
RJ Ryan <russelljryan-re5jqeeqqe8avxtiumw...@public.gmane.org> wrote:
> > So if this declarative table (which is obviously needed to standardize the
> > glue interface) was returned from script itself that'd be ok right? After
> > all Mixxx doesn't need it to be a disk file as long as it can retrieve a
> > standard data structure. In that case driver writers could choose whatever
> > storage they want if they're allergic to one file format or another.
> >
> > Switching to such an architecture just needs a standard Javascript
> > function that loads existing XMLs.
>
> This would work fine if all Mixxx needed to do was load a preset but it
> also has to be able to serialize presets. If the script returns the
> mappings from a standard function call then Mixxx would have no way to
> write an updated script with the user's modified mappings.
I don't have an up-to-date/comprehensive picture of the controller landscape,
in originality or popularity; I was thinking of a standardized declarative
layer as an entry point into Mixxx.
F.ex. I attached a (curated) snippet I wrote to decode a Logitech Rumblepad;
piping the raw, procedural input through a little state machine so the output
is declarative. Don't know how applicable that is in general, especially for
controllers that aren't read-only and give significant feedback to the user,
but it's easier to build logic on top of declarative input vs squaring
complexity by blending one state machine with another.
> > Are there other critical latency cases like resuming a cue to do a Roger
> > Sanchez style needle-drop mix? (good luck:)
>
> Well, there are lot of issues around wheels in general in Mixxx and our
> solution today kind of sucks. There's no standard way for a preset to
> provide options the user can tweak such as wheel sensitivities -- our
> answer is "just pop open the JS file in a text editor and change this
> number". Also, for wheels that act "normal" for whatever values of normal
> we define, we should provide a generalized non-script infrastructure for
> processing scratching and jog-wheeling that bypasses script and supports
> the user customizing it in the most common ways (sensitivity,
> touch-enabling, inertia, etc.)
Assuming Mixxx has a fixed tick() for controller input, a wheel is just an ID
with a signed delta right? Sensitivity & inertia would be a level above. Maybe
it's possible to create a UI library for the most common widgets, if the wiki
had a list of various controller widgets in categories or at least tags it'd
help get some perspective.
No doubt you'll have to make tough decisions about where to split
functionality. You can neither have a script-only nor a UI-only interface
that'd cover all uses, both extremes would freak out new users. IMHO the danger
is getting sucked into the quest for a silver bullet (like the iPod's
click-wheel), instead I'd try to take the same path as Flash which started
mostly UI and then nudged those who could/wanted to script. Some users will
inevitably complain and be much louder than happy ones... NI forums were not
exactly a yoga room.
I'll reply to your other points tomorrow (dead tired now) but looking up my a55
I'd say the more complex MIDI controllers make sense for DJ/producers on
software like Ableton Live with tons of raw samples/channels but little for
"crude" 2-track DJing. If Jean-Michel Jarre type "laser harp" / JazzMutant
wiz-bang visual interfaces aren't "so yesterday" yet, I bet they soon will
(Qbert vs iPod operator?)
My opinion's probably not relevant because I quickly had to drop most of
Traktor's gimmicks and use the main mixer when I was haplessly pushed into the
arena with "real" DJs who wanted to beatmatch for fun (I now have a 3/4
flamenco-house track up my sleeve:) or just had to transition with a resident
whose library was 20 bpm above mine. Also I'm not a big fan of butchering
awesome productions with flangers or reverb so don't care much for effects...
maybe after I never have a key clash.
I'd be a lot more interested in novel user interfaces to navigate the music
library, f.ex. instantaneously calling up a full-screen, high-contrast 2+1/2d
overlay to zoom around styles, moods, etc., with visual cues, stuff that helps
improvise when a crowd inevitably isn't what you had planed: "what drugs are
they on? where's my Shpongle crate?"
cheers,
-- p
#!/usr/bin/env lua
--[[
Rumblepad event reader
]]
local
buttonTab = {}
local
axisNames = {"lstick_x", "lstick_y", "rstick_x", "rstick_y", "hat_x", "hat_y"}
local
axisTab = {}
---- Init States ---------------------------------------------------------------
local
function InitStates()
for b = 1, 10 do
buttonTab[b] = 0
end
for a = 1, 7 do
axisTab[a] = 0
end
end
---- Get One event -------------------------------------------------------------
local
function GetOne(f)
--
-- [0; 1] timestamp
-- [2; 3] signature
-- [4; 5] word value (down/up for button, one axis value per axis movement)
-- [6] type (1=button, 2=axis)
-- [7] id
local frame = 8
local s = f:read(frame)
if (s == nil) then
return
end
local val, w2, id, typ
typ = s:byte(7)
id = s:byte(8)
if (typ == 1) then
id = id + 1
val = s:byte(5) + (s:byte(6) * 256)
buttonTab[id] = val
if (val == 1) then
-- new down
return id
else
-- ignore button up
return nil
end
elseif (typ == 2) then
local u_val = s:byte(5) + (s:byte(6) * 256)
-- two's complement
local val = (u_val > 32767) and (u_val - 2^16) or u_val
axisTab[id] = val
local axis_id = 101 + (id * 2)
if (val < -20000) then
--left or up
return axis_id
elseif (val > 20000) then
-- right or down
return axis_id + 1
else
-- ignore dead zone
return nil
end
end
end
---- Dump States ---------------------------------------------------------------
local
function DumpStates()
-- buttons
local but_s = "buttons: "
for i = 1, 10 do
local c = '_'
if (buttonTab[i] > 0) then
c = tostring(i)
end
but_s = but_s .. c .. ' '
end
local axis_s = "axis: "
for i = 1, 6, 2 do
axis_s = axis_s .. sprintf("(%05d, %05d) ", axisTab[i], axisTab[i + 1])
end
printf("%s %s", but_s, axis_s)
end
---- Main ----------------------------------------------------------------------
InitStates()
local f = io.open("/dev/input/js0", "rb")
assert(f)
while (true) do
local id = GetOne(f)
DumpStates()
-- snip
end
------------------------------------------------------------------------------
Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET
Get 100% visibility into your production application - at no cost.
Code-level diagnostics for performance bottlenecks with <2% overhead
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap1
_______________________________________________
Get Mixxx, the #1 Free MP3 DJ Mixing software Today
http://mixxx.org
Mixxx-devel mailing list
Mixxx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mixxx-devel