I agree with Harry, assigning meaning to each event should be out of the scope of Ctlra. There is far too much variability between controllers for that to be useful, hence why no such system has been invented for MIDI DJ controllers and why device-specific mappings exist.

One nice thing about MIDI is that it is usually easy to know which LED corresponds to which input. If I want to light the LED for the button that sends the input [0x91, 0x51, 0x7f], then I can assume that I need to send output [0x91, 0x51, 0x7f] to turn the LED on and [0x91, 0x51, 0x00] to turn the LED off. Is there such a correspondence between the values used for input and output with Ctlra?

I am wondering how we could make the human-readable names in Ctlra's C enums accessible to Mixxx's JS environment...

On 07/09/2017 07:57 AM, Harry van Haaren wrote:
On Sun, Jul 9, 2017 at 1:23 PM, Daniel Schürmann <dasch...@mixxx.org <mailto:dasch...@mixxx.org>> wrote:

    Hi Harry,

     > At no point to I think Ctlra will *require* also using TCC. It
    just so happens that they complement each other well for my use-cases.

    That seams to be a good approach. If the architecture allows to put
    Ctlra drivers into runtime loaded object files, it does not matter
    which compiler is used and if it turns out that TCC is the best for
    our needs on a platform, fine.

    > That proposal looks really good. It basically means,  from a Ctlra POV, 
that Ctlra is plain old C code, and exposes
    generic events.

    No, not generic events. The Ctlra using apllications should receive
    a specific event.


By "generic event", what I mean is a specific event type, with a specific event ID. These two combined identify one specific control item on a physical controller device. For example, a specific button (eg Play) sends a button event when pressed / released, using this struct for metadata: https://github.com/openAVproductions/openAV-Ctlra/blob/master/ctlra/event.h#L63

Note that the name of the control is *not* included here for performance reasons. Passing strings around just isn't a good idea for performance. Ctlra provides functions to lookup the name of each event based on type/ID. I have "generic" applications (don't care about which HW controller is used) that provide fully labelled UIs showing all control names - so your use-case is covered here. (If there is an issue, we can resolve it at the Ctlra API layer, but AFAIK the API caters for the application's requirements).

    If you turn the gain Knob on a controller, the application should be
    able to now that this is the Knob labeled with "Gain" grouped for
    Deck A.


See above paragraph - names of events are provided, based on the labels physically printed on the hardware.

    This might be done by a generic event + a link into a manifest file,
    which may also include a photo of the controller. This metada of
    each event should be optimized to be translated into a OSC address,
    this should be a mandatory part of Crtra. So we need a document like
    this:
    https://github.com/fabb/SynOSCopy/wiki
    <https://github.com/fabb/SynOSCopy/wiki>


I see no value in *demanding* that Ctlra supports OSC, in the same way that Ctlra will not demand the use of TCC. Ctlra must be a standalone library (with only *essential* dependencies like libUSB). Any metadata should be directly related to the physical device capabilities. Mapping and adding semantic meaning to the controls is up to the application.

I do not wish to include images in Ctlra - it complicates things, and is generally just un-conventional. That said, I so see value in "visually showing" users what controls are available, and what thier labels are. This has already been discussed, and a POC implemented: https://github.com/openAVproductions/openAV-Ctlra/issues/7 (note to self, I still need to cleanup and publish the branch with the POC).

I feel the scope of Ctlra should not include the "semantic meaning" of controllers. This was discussed previously (there's one question at the end of the LAC talk asking exactly this), and it doesn't scale well, and only complicates things. So Ctlra will provide an Event per button press/release, with type/ID to identify the exact physical change. Interpreting the meaning of that event, and mapping it to application functionality is *not* in the scope of Ctlra.

     > The application can interpret those in whatever way it wants -
    OSC, JS/Mixxx, or however OpenAV stuff will end up doing this. It
    keeps Ctlra just generic events, and allows the application to solve
    the mapping problem in its own way. That sounds logical and a good
    abstraction, which is exactly what Ctlra aims for.

    Yes, that is right. Today in case of midi, the user has to figure
    out which midi key is doing what.  With a Ctlra enabled controller
    this issue should be gone. The mapping solution can for example show
    the photo of the controller, and highlight the place of action.
    But even without the photo, the user knows exactly how to enable a
    knob LED, using the OSC name-space as address.


The human-readable string that is provided by Ctlra library API enables the user to understand the event. For an example of the name lookup, please see here: https://github.com/openAVproductions/openAV-Ctlra/blob/master/examples/simple/simple.c#L51


    > In order to progress this idea, I'll post code up ASAP,  which makes the 
generic Ctlra events available in a callback as
    part of the CtlraController class. After that, the Mixxx/JS
    components must be designed / worked on to fully enable Ctlra in Mixxx.

    Thank you :-)

    I think for the OCS Plug and Play stuff we just need to rethink the
    API a bit.
    I would like to do something like this
    
https://github.com/mixxxdj/mixxx/blob/lv2_support2/src/effects/lv2/lv2manifest.cpp
    
<https://github.com/mixxxdj/mixxx/blob/lv2_support2/src/effects/lv2/lv2manifest.cpp>
    in Ctlra as well.
    (Sorry, I am not completely though the API so this might be wrong)


As above, I'm not liking the OSC semantic meaning side of things - Ctlra is a C library and provides events. Mapping (to OSC, or whatever) is up to the application. Or if there is value, somebody could create a OscApiForCtlra library - but personally I don't see that as having value at the moment.

    We need a kind of generic data point enumerator expression for every
    event, which is able to discover all controller features.


Ctlra API enables this already. The ctlra_dev_info_t struct has all names of all events, and the counts of each. In the POC implementation, the size of the controller, and control position / size are available as integer values in millimeters. This enables a GUI application to "mock up" the controller, no photos / pictures involved.

    Every data point should have a function for examine like
    ctlra_dev_get_osc_namespace() and ctlra_dev_get_picture_location()
    Will this work? Does this fit to the ctlra goals?


I feel the Ctlra API enables the events + physical device info already. Adding OSC namespaces etc above it is not it the scope of Ctlra, nor should it be in my opinion. (Due to not *demanding* applications use any particular form of mapping / interpreting events). Visually enabling controllers is achieved by providing physical layout info of the device, instead of using a photo - a much better solution IMO.

Thoughts / opinions? -Harry

    Am 09.07.2017 um 13:18 schrieb Harry van Haaren:

    On Sun, Jul 9, 2017 at 11:21 AM, Daniel Schürmann
    <dasch...@mixxx.org <mailto:dasch...@mixxx.org>> wrote:

        Hi Harry, Hi Be,

        here some comments:

        IMHO arguing about If C or JS is easier will not lead us ahead
        in this discussion.


    Good point - apologies for the rat-hole.

        > As noted above, we can take TCC off the table for Mixxx's
        use case. Personally I still love it - and it has radically
        changed how I think about programming in C - but perhaps its
        just not a good fit for Mixxx. I can work with that.

        I am afraid a mandatory TCC based Ctlra solution will prevent
        it from being successful.


    At no point to I think Ctlra will *require* also using TCC. It
    just so happens that they complement each other well for my use-cases.

        Only a solution that works nice Windows as well as on non X86
        based architectures will be accepted as a new standard.


    TCC supports a variety of targets; and despite no official
    releases, the git repo is pretty active:
    http://repo.or.cz/w/tinycc.git

        For me, the key is here to be modular. Similar to LV2 each
        driver Ctlra driver can be shipped with a source file and a
        meta-data file which should contain a recipe to turn the
        source file into a *.so or a dll. In a future advanced step,
        the hosts Ctlra library code should be responsible to read the
        recipe and do what it should be done to turn it into a binary.


    I'm not sure what the benefit is here - i see a pretty complex
    workflow, but no ultimate gain that TCC doesn't already provide.
    But I said I'd drop the TCC idea and discuss other options.

        > Lets find a better solution for novice / casual users who
        don't want to compile anything.

        The compile step itself is not the issue. If we look for
        example to OpenGL Shading Language, where we also have a
        compiler step no one noticed.


    Good point.

        >> Even if we have a ctlra controller in Mixxx, we need to
        adapt the signals to Mixxx Control Objects using xml or js files.

        > Why XML or JS? I see many more options, and just because we
        have existing infrastructure for a similar case doesn't mean
        its always the correct solution.

        Just because Mixxx is using it right now. It is IMHO not in
        the responds of Ctlra to convert controller events into
        application commands.


    OK - then lets investigate this option more. Keep in mind that my
    JS experience is limited, and that I'm not particularly familiar
    with QT/Mixxx's JS engine capabilities.
    I'll post a PR asap that exposes Ctlra events to Mixxx, and then
    see what kind of JS magic is required on top to expose that to the
    JS mapping scripts.

        > I'm still not convinced it is possible for any
        point-and-click system to fully map most controllers **in a
        maintainable way**. ...

        This is should be out of scope of Ctlra.


    Absolutely yes - this is outside the scope of Ctlra - at this
    point we are talking about the integration of Ctlra + Mixxx in
    particular. This was noted by a few developers at the LAC too,
    that device access is only a part of the problem. Providing a good
    mapping mechanism is the harder part. But we need step 1 (Ctlra
    device access) before step 2 (easy/powerful mappings).

        IDEA:

        Thinking of all of this again, I think this Ctlra project is a
        great chance to fix some issues, existing standards have.

        * Midi: Midi is that successfully, because it is defined up to
        the Application layer for a Midi-Keyboard. Reusing this for
        other types of controllers works, but pushes it down to the
        Presentation Layer.
        * OSC: OSC fails to define the Application layer. It is
        promoted to be a Midi successor, but it even has no standard
        way to even transport good old midi messages. There are
        approaches to fix this in some OSC namespaces, but this is
        somehow stucked.

        It would be grate If we could get back to the state of
        original Midi Plug-And-Play behaviour for Midi-Keyboard for
        all type of controllers using Ctlra. If we do this along with
        a OSC namespace for Ctlra, this will be a great benefit and
        probably a very successfully.


    Lets see!

        On a Midi-Keyborad you know exactly which phsical key is
        pressed an how just looking to the midi Message.
        This can be done for Ctlra as well, I we define a message like
        "Gain Knob Deck A 56 %" So a new controller will be instantly
        usable for Mixxx with a basic default mapping. This is
        probably not sufficient, but putting a new function on "Gain
        Knob Deck A" can be done by existing mapping solutions.


    Yes, simple "static" mapping schemes can be easily handled by
    mapping event IDs to ControlProxy objects. As Be pointed out, the
    difficult point is layering multiple functionalities over each
    other in a user-workable way.

        I have these Architectures in mind:

        OpenAV setup:

        HID-Controller
                 V
        Ctlra Driver
                 V
        Cltra Lib
                 V
        C Mapping
                 V
        OpenAV App


        Mixxx setup:

        HID-Controller
                 V
        Ctlra Driver
                 V
        Cltra Lib
                 V
        Controller Proxy
                 V
        XML / *js mapping
                 V
        Mixxx engine



        Gnereic OSC setup:

        HID-Controller
                 V
        Ctlra Driver
                 V
        Cltra Lib
                 V
        OSC Wrapper (process)
                 V
           UDP/TCP
                 V
        OSC to OSC mapper
                 V
        UDP/TCP
                 V
        OSC enabled DAW




        What do you think?


    That proposal looks really good. It basically means, from a Ctlra
    POV, that Ctlra is plain old C code, and exposes generic events.
    The application can interpret those in whatever way it wants -
    OSC, JS/Mixxx, or however OpenAV stuff will end up doing this. It
    keeps Ctlra just generic events, and allows the application to
    solve the mapping problem in its own way. That sounds logical and
    a good abstraction, which is exactly what Ctlra aims for.

    In order to progress this idea, I'll post code up ASAP, which
    makes the generic Ctlra events available in a callback as part of
    the CtlraController class. After that, the Mixxx/JS components
    must be designed / worked on to fully enable Ctlra in Mixxx.

    Thanks for all the input - we seem to be converging on a solution,
    great! -Harry

        Am 09.07.2017 um 06:52 schrieb Be:
        Hi Harry,
        I read the paper for the presentation at LAC 2017 that you
        linked on IRC:
        http://musinf.univ-st-etienne.fr/lac2017/pdfs/01_C_E_137795.pdf
        <http://musinf.univ-st-etienne.fr/lac2017/pdfs/01_C_E_137795.pdf>


        Going along with what I mentioned in my previous post, I do
        not think Ctlra should be aware of the "userdata". IMO that
        should be left to the application and its scripting environment.

        On 07/08/2017 08:36 PM, Be wrote:
        On 07/08/2017 06:51 PM, Harry van Haaren wrote:
            3. The programming language. It is a lot easier to find
        someone who
            knows JavaScript, or at least kinda knows JavaScript
        enough to get
            by for a small project, than it is to find someone who
        knows C. For
            people with minimal or no prior programming experience,
        higher level
            languages are much easier to learn.


        Surely anybody somewhat proficient in JS can figure out
        what this (link below) does?? Programming is programming -
        logical thinking. I don't think that the C code there is
        "harder" than achieving the same in JS. Keep in mind we're
        not asking people to do pointer-magic here - its basic
        arithmetic, and calling a functions.
        
https://github.com/openAVproductions/openAV-Ctlra/blob/master/examples/vegas_mode/z1.c#L45
        
<https://github.com/openAVproductions/openAV-Ctlra/blob/master/examples/vegas_mode/z1.c#L45>


        C is more difficult to learn than JavaScript. There are a
        lot of details in that code that you simply don't have to
        think or know about with JavaScript. To a novice developer
        who knows nothing about C, they'd have to answer these
        questions:

         > if(e->slider.id <http://slider.id> ==
        NI_KONTROL_Z1_SLIDER_LEFT_FADER) {

        What is the difference between "->" and "."?

         > uint32_t iter = (int)((d->volume+0.05) * 7.f);

        1. What is a uint32_t? Why should I use that instead of a
        different number type?
        2. What is that "(int)" doing?
        3. Why is there a ".f" after the "7"?

        That's just the tip of the iceberg of understanding a few
        lines of code. Fully mapping controllers requires
        considerably more complex logic than that.

            So, I think it would make more sense to expose Ctlra to
        Mixxx's
            existing JavaScript environment for controller mapping.
        There would
            only need to be two capabilities added for this to work:
            1. Scripts would be able to register JavaScript
        callback functions
            that would be called when particular Ctlra events are
        passed to Mixxx.
            2. Scripts would need to have a way to send output
        messages to
            Ctlra. There should be a way to freeze/unfreeze the
        sending of
            output messages so many outputs could be updated
        simultaneously in a
            single HID packet.
            I have written a proposal for how to do this with MIDI:
        
https://mixxx.org/wiki/doku.php/registering_midi_input_handlers_from_javascript
        
<https://mixxx.org/wiki/doku.php/registering_midi_input_handlers_from_javascript>

        
<https://mixxx.org/wiki/doku.php/registering_midi_input_handlers_from_javascript>
        
<https://mixxx.org/wiki/doku.php/registering_midi_input_handlers_from_javascript>

            It would be great if we could create JS APIs that are
        almost
            identical for MIDI and Ctlra.


        I'm still not sold on the idea of wrapping all of Ctlra up
        in JS callbacks and then exposing it to Mixxx. Its
        possible, but I fail to see why this should be the
        holy-grail of how mappings should work. I should probably
        do up a design-doc or video on how I think *eventually* the
        Ctlra / Mixxx UX for mapping a controller would look: and
        if I can figure out the technical parts, it will be pretty
        revolutionary in how it enables novice users to create
        unique mappings. Punch line is to present the functionality
        (multi-layered bindings) in a way that is easily consumed
        by "ordinary" humans, and provide a doc + video explaining
        it. Give me a few weeks - some POC Ctlra + Mixxx code
        first, then onwards to the exact mapping UX.

        I'm still not convinced it is possible for any
        point-and-click system to fully map most controllers *in a
        maintainable way*. Years ago, device specific hacks were
        added to Mixxx in C++ to make the XML system work with MIDI
        signals for jog wheels. Someone please correct me if I am
        wrong, but my understanding is that the JS engine was added
        to avoid the need for such compiled-in device specific
        hacks. Almost all mappings submitted for inclusion in Mixxx
        recently have been done mostly or entirely in JS. Traktor
        has an elaborate point-and-click mapping system and users
        complain how awful it is to work with (refer to
        https://djworx.com/what-do-you-want-from-traktor-pro/
        <https://djworx.com/what-do-you-want-from-traktor-pro/> for
        example).

        I have previously thought about designing a GUI that used
        tabs to organize different layers of functionality. But this
        would break down quickly for handling the interaction of
        multiple layers and create a mess even worse than Traktor's
        mapping GUI. For example, consider a cue button that uses
        the cue_default ControlObject normally but start_stop while
        a shift button is held. You could define a layer that the
        unshifted button belongs to and another layer that the
        shifted button belongs to. Okay, easy enough. Now you want
        to make that side of the controller able to be toggled
        between deck 1 & deck 3. How would you accomplish this? With
        a simple layering system, you could create 4 different layers:

        Deck 1 unshifted
        Deck 1 shifted
        Deck 3 unshifted
        Deck 3 shifted

        Then you'd need to copy & paste all those 4 layers for the
        other side of the controller with decks 2 & 4! It would be
        possible to hack support for toggling decks into Mixxx so
        the mapping could deal with a virtual deck and Mixxx would
        maintain the state of which deck is active, but that would
        only handle this specific use case. And you'd still need to
        copy & paste for the left & right sides of the controller.

        What if I want pushing a button to use the beatloop_activate
        ControlObject when no loop is active but use reloop_toggle
        when a loop is active? I'd need to create a layer for a loop
        being enabled and a layer for no loop enabled, then somehow
        tell Mixxx to switch between them when that state changes.
        Then I'd have to duplicate both those layers for deck 1 &
        deck 3. Now I want pressing that button to act differently
        when shift is pressed -- and act differently depending on
        whether a loop is active. When shift is pressed, I want to
        use reloop_toggle with no loop active and reloop_andstop
        with a loop active. With a GUI layering system, I'd need
        layers for:

        Deck 1, loop disabled, no shift
        Deck 1, loop disabled, shift
        Deck 1, loop enabled, no shift
        Deck 1, loop enabled, shift
        Deck 3, loop disabled, no shift
        Deck 3, loop disabled, shift
        Deck 3, loop enabled, no shift
        Deck 3, loop enabled, shift

        And again copy and paste for decks 2 & 4. Now there are 16
        layers for pushing this button! What if you wanted to remap
        it? Maintaining even this example would be a pain, and
        that's just one component of the controller. Programming an
        entire mapping this would would be awful.

        Also consider how you could implement
        https://mixxx.org/wiki/doku.php/standard_effects_mapping
        <https://mixxx.org/wiki/doku.php/standard_effects_mapping>
        for the Kontrol X1, S2, S4, and S5 with such a system.
        Again, you could hack all that logic into the C++ side of
        Mixxx like the deck toggling case, but then what would you
        do to implement something like the effects mapping for the
        Pioneer DDJ-SB2:
        https://mixxx.org/wiki/doku.php/pioneer_ddj-sb2#effects
        <https://mixxx.org/wiki/doku.php/pioneer_ddj-sb2#effects>
        (particularly the Mixxx 2.1 mapping).

        This video talks about the uselessness of visual diagramming
        languages like UML, and I think much of what is said about
        visual diagramming languages in this applies to programming
        with a GUI as well:
        https://www.youtube.com/watch?v=4_SvuUYQ5Fo
        <https://www.youtube.com/watch?v=4_SvuUYQ5Fo>

        That said, if you have revolutionary ideas for how to design
        a GUI for mapping controllers that could actually handle all
        the complexity above and not be a huge pain to work with,
        please share. I'd love to be proven wrong... but I think
        it's more likely that you'd waste time that could be better
        spent making Mixxx do other cool things or writing a new
        OpenAV application.


        Thanks for your input again - good points raised. -Harry


            On 07/06/2017 04:57 PM, Harry van Haaren wrote:

                Hi All,

                First of all - this is my first post to the
        Mixxx-devel list, so
                a brief intro is in order;
                I'm Harry van Haaren, developer of the OpenAV audio
        software,
                bit of a music/tech/linux head :)

                I've recently been working on improving controller
        support in
                Linux audio land, in particular
                what I call "modern USB HID" controller devices
        (think DJ
                controllers like Akai/NI/Abletons range).
                I've developed the Ctlra library as OpenAV, which
        provides
                access to these hardware devices
                on Linux. The library allows hotplug and various other
                "advanced" features like accessing
                screens on devices.

                I'd like to integrate Ctlra into Mixxx - to provide
        access to
                hardware currently not available
                to Linux users, and also to provide hotplug support
        to those
                controllers. I've created a blueprint
                on Launchpad[1], and written an introduction on
        Ctlra and how I
                propose to integrate it in Mixxx[2].
                Finally, there is a documentation page on what
        Ctlra itself
                achieves here[3], and the source is here[4].

                If you have an interest in hotplug of controllers,
        controller
                support or hardware on Linux,
                do have a read of the wiki page and others, and I'd
        appreciate
                your input on the ideas!

                Thanks for all your efforts on Mixxx so far,
        onwards and upwards!
                -Harry of OpenAV

                [1]
        https://blueprints.launchpad.net/mixxx/+spec/ctlra-controller-support
        <https://blueprints.launchpad.net/mixxx/+spec/ctlra-controller-support>

        <https://blueprints.launchpad.net/mixxx/+spec/ctlra-controller-support>
        <https://blueprints.launchpad.net/mixxx/+spec/ctlra-controller-support>
                [2]
        https://www.mixxx.org/wiki/doku.php/ctlra_support
        <https://www.mixxx.org/wiki/doku.php/ctlra_support>
        <https://www.mixxx.org/wiki/doku.php/ctlra_support>
        <https://www.mixxx.org/wiki/doku.php/ctlra_support>
                [3] http://openavproductions.com/doc/ctlra.html
        <http://openavproductions.com/doc/ctlra.html>
        <http://openavproductions.com/doc/ctlra.html>
        <http://openavproductions.com/doc/ctlra.html>
                [4]
        https://github.com/openAVproductions/openAV-ctlra
        <https://github.com/openAVproductions/openAV-ctlra>
        <https://github.com/openAVproductions/openAV-ctlra>
        <https://github.com/openAVproductions/openAV-ctlra>

                --
        http://www.openavproductions.com
        <http://www.openavproductions.com>
        <http://www.openavproductions.com>
        <http://www.openavproductions.com>


        
------------------------------------------------------------------------------

                Check out the vibrant tech community on one of the
        world's most
                engaging tech sites, Slashdot.org!
        http://sdm.link/slashdot



                _______________________________________________
                Get Mixxx, the #1 Free MP3 DJ Mixing software Today
        http://mixxx.org


                Mixxx-devel mailing list
        Mixxx-devel@lists.sourceforge.net
        <mailto:Mixxx-devel@lists.sourceforge.net>
        <mailto:Mixxx-devel@lists.sourceforge.net>
        <mailto:Mixxx-devel@lists.sourceforge.net>
        https://lists.sourceforge.net/lists/listinfo/mixxx-devel
        <https://lists.sourceforge.net/lists/listinfo/mixxx-devel>
        <https://lists.sourceforge.net/lists/listinfo/mixxx-devel>
        <https://lists.sourceforge.net/lists/listinfo/mixxx-devel>


        
------------------------------------------------------------------------------

            Check out the vibrant tech community on one of the
        world's most
            engaging tech sites, Slashdot.org!
        http://sdm.link/slashdot
            _______________________________________________
            Get Mixxx, the #1 Free MP3 DJ Mixing software Today
        http://mixxx.org


            Mixxx-devel mailing list
        Mixxx-devel@lists.sourceforge.net
        <mailto:Mixxx-devel@lists.sourceforge.net>
        <mailto:Mixxx-devel@lists.sourceforge.net>
        <mailto:Mixxx-devel@lists.sourceforge.net>
        https://lists.sourceforge.net/lists/listinfo/mixxx-devel
        <https://lists.sourceforge.net/lists/listinfo/mixxx-devel>
        <https://lists.sourceforge.net/lists/listinfo/mixxx-devel>
        <https://lists.sourceforge.net/lists/listinfo/mixxx-devel>




--
        http://www.openavproductions.com
        <http://www.openavproductions.com>

        
------------------------------------------------------------------------------

        Check out the vibrant tech community on one of the world's most
        engaging tech sites, Slashdot.org! http://sdm.link/slashdot
        _______________________________________________
        Get Mixxx, the #1 Free MP3 DJ Mixing software Today
        http://mixxx.org


        Mixxx-devel mailing list
        Mixxx-devel@lists.sourceforge.net
        <mailto:Mixxx-devel@lists.sourceforge.net>
        https://lists.sourceforge.net/lists/listinfo/mixxx-devel
        <https://lists.sourceforge.net/lists/listinfo/mixxx-devel>

        
------------------------------------------------------------------------------

        Check out the vibrant tech community on one of the world's most
        engaging tech sites, Slashdot.org! http://sdm.link/slashdot
        _______________________________________________
        Get Mixxx, the #1 Free MP3 DJ Mixing software Today
        http://mixxx.org


        Mixxx-devel mailing list
        Mixxx-devel@lists.sourceforge.net
        <mailto:Mixxx-devel@lists.sourceforge.net>
        https://lists.sourceforge.net/lists/listinfo/mixxx-devel
        <https://lists.sourceforge.net/lists/listinfo/mixxx-devel>



        
------------------------------------------------------------------------------
        Check out the vibrant tech community on one of the world's most
        engaging tech sites, Slashdot.org! http://sdm.link/slashdot
        _______________________________________________
        Get Mixxx, the #1 Free MP3 DJ Mixing software Today
        http://mixxx.org


        Mixxx-devel mailing list
        Mixxx-devel@lists.sourceforge.net
        <mailto:Mixxx-devel@lists.sourceforge.net>
        https://lists.sourceforge.net/lists/listinfo/mixxx-devel
        <https://lists.sourceforge.net/lists/listinfo/mixxx-devel>



--
    http://www.openavproductions.com <http://www.openavproductions.com>





--

http://www.openavproductions.com


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot



_______________________________________________
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


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
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

Reply via email to