Coder Social home page Coder Social logo

shaduzlabs / cabl Goto Github PK

View Code? Open in Web Editor NEW
127.0 25.0 36.0 1.15 MB

Controller ABstraction Layer

License: MIT License

CMake 8.05% Shell 0.10% C++ 87.39% C 0.85% Objective-C 0.19% HTML 1.79% JavaScript 0.76% CSS 0.49% Python 0.38%
native-instruments ableton maschine komplete-kontrol traktor-kontrol push push-2 libusb hidapi cmake

cabl's Introduction

CABL / Controller ABstraction Layer


Build Status Build status Coverage Status

Supported platforms

  • OSX
  • Linux
  • Windows
  • Various embedded platforms (in progress)

Supported controllers

  • Ableton Push
  • Ableton Push2
  • Komplete Kontrol S25
  • Komplete Kontrol S49
  • Komplete Kontrol S61
  • Komplete Kontrol S88
  • Maschine Jam
  • Maschine Mk1
  • Maschine Mk2
  • Maschine Mikro Mk2
  • Traktor Kontrol F1 Mk2

Getting started

OSX

Make sure the following packages/applications are installed:

Then install libUSB (>=1.0.20), HIDAPI (>= 0.8.0) and RtMIDI (>=2.1.0) if needed:

brew install hidapi libusb rtmidi

If you want to build the python wrapper, you'll need to install Boost.python:

brew install boost --with-python
brew install boost-python

And if you want to build the documentation, you'll need to install Doxygen:

brew install doxygen

Clone this repository locally and create a build subfolder:

git clone https://github.com/shaduzlabs/cabl.git
cd cabl && mkdir build && cd build

Now launch CMake, build and (eventually) install:

cmake ..
make
sudo make install

Please have a look at the CMake appendix for more CMake options.

Linux

Make sure the following packages/applications are installed:

  • CMake (>=3.4)
  • Clang (>= 3.7) or GCC (>= 4.9)

Then install libUSB (>=1.0.20), HIDAPI (>= 0.8.0) and RtMIDI (>=2.1.0) if needed (depending on your linux distribution and dependency manager, the command below might look slightly different):

sudo apt-get install libusb-1.0-0-dev libhidapi-dev librtmidi-dev

If you want to build the python wrapper, you'll need to install Boost.python:

sudo apt-get install libboost-python-dev

And if you want to build the documentation, you'll need to install Doxygen:

sudo apt-get install doxygen

Clone this repository locally and create a build subfolder:

git clone https://github.com/shaduzlabs/cabl.git
cd cabl && mkdir build && cd build

Now launch CMake, build and (eventually) install:

cmake ..
make
sudo make install

Please have a look at the CMake appendix for more CMake options.

Windows

Make sure the following packages/applications are installed:

  • CMake (>=3.4)
  • Visual Studio 2015 or above

If you want to build the documentation, you'll need to install Doxygen.

Clone this repository locally and create a build subfolder:

git clone https://github.com/shaduzlabs/cabl.git
cd cabl
mkdir build
cd build

Now launch CMake:

cmake ..

If all worked fine, you shoould end up with several VS project files and a solution (cabl.sln).

Please have a look at the CMake appendix for more CMake options.

Appendix

CMake options

By default, CMake is configured to build only the static version of the library. You can override this setting using:

  • BUILD_STATIC_LIBS=[ON|OFF]
  • BUILD_SHARED_LIBS=[ON|OFF] For example, if you want to build both the shared and the static library, you'll need to write:
cmake -DBUILD_STATIC_LIBS=ON -DBUILD_SHARED_LIBS=ON ..

On Windows LibUSB, HIDAPI and RtMIDI are downloaded from the respective repositories and built locally in the build subfolder, so you don't need to have them installed on the system. If for some reason you want the same behavior on Linux or OSX, you can override CABL_FORCE_BUILD_DEPENDENCIES (default is OFF) and set it to ON.

cmake -DCABL_FORCE_BUILD_DEPENDENCIES=ON ..

cabl's People

Contributors

ni-vpacella avatar shaduzlabs avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cabl's Issues

Can this library be used to emulate the NI hardware?

I'm developing a new physical mixing and editing control surface, and I'd like to be able to connect to NKS plugins. I have a screen and will have 8 encoders and various buttons, so should be able to emulate the NI hardware. It would mean you can edit and mix and control NKS plugins, without having to have a keyboard next to the control surface. I currently use an S25, but it's cumbersome having to have it on my desk when I'm not composing.

I see lots of examples of people sending images to the screens on the hardware devices, but I'd like to display the images from the NKS plugins etc.

Any information would be greatly appreacited.

Missing RTMIDI_INCLUDE_DIRS

running this on the latest debian image for the raspberry pi 2:

installed libusb-1.0-0-dev libhidapi-dev librtmidi-dev
and did a git submodule install

pi@raspberrypi:~/cabl/build $ cmake ..

                            __       ___
                           /\ \     /\_ \
               ___     __  \ \ \____\//\ \
              /'___\ /'__`\ \ \ '__`\ \ \ \
             /\ \__//\ \L\.\_\ \ \L\ \ \_\ \_
             \ \____\ \__/.\_\\ \_,__/ /\____\
              \/____/\/__/\/_/ \/___/  \/____/
               Controller ABstraction Library
                                  v. 0.9.7-dev

[2018-10-27] cabl v. 0.9.7-dev - development version built on a local machine
-- Checking for LibUSB...
-- Found: libusb-1.0:
--  - Includes: /usr/include/libusb-1.0
--  - Libraries: /usr/lib/arm-linux-gnueabihf/libusb-1.0.so
-- Checking for HIDAPI...
-- Found: HIDAPI
--  - Includes: /usr/include/hidapi
--  - Libraries: /usr/lib/arm-linux-gnueabihf/libhidapi-libusb.so
-- Checking for RtMidi...
-- Found: RtMidi
--  - Includes: RTMIDI_INCLUDE_DIRS-NOTFOUND
--  - Libraries: /usr/lib/arm-linux-gnueabihf/librtmidi.so
-- Boost version: 1.62.0
-- Found the following Boost libraries:
--   python
-- Could NOT find Doxygen (missing:  DOXYGEN_EXECUTABLE)
CMake Warning at cmake/colors.cmake:29 (_message):
  Doxygen has not been found, the documentation will not be
  created.
Call Stack (most recent call first):
  CMakeLists.txt:184 (message)


BUILD_STATIC_LIBS is ON
-- Checking out external repository: lodepng
-- Configuring done
-- Generating done
-- Build files have been written to: /home/pi/cabl/build/lodepng/build
[ 12%] Performing update step for 'lodepng'
Current branch master is up to date.
[ 25%] Performing configure step for 'lodepng'

[ 37%] Performing build step for 'lodepng'

[ 50%] No install step for 'lodepng'
[ 62%] Completed 'lodepng'
[100%] Built target lodepng
-- lodepng path: /home/pi/cabl/build/lodepng/src/lodepng
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
/home/pi/cabl/RTMIDI_INCLUDE_DIRS
   used as include directory in directory /home/pi/cabl
   used as include directory in directory /home/pi/cabl

-- Configuring incomplete, errors occurred!
See also "/home/pi/cabl/build/CMakeFiles/CMakeOutput.log".

Include ideal python version in README

Hi, I had a lot of trouble initially building this on Mac OS X until I realized cmake was using Python 3.6. You may want to put Python 2.7 in the readme so people know what version to use.

Maschine MK1 problems

First off, thank you for the time and effort you put into this project!

I built this project on a raspberry pi and tried both master and develop. I also hooked up the Maschine MK1 both directly and through a powered hub to the raspberry pi.

The device-test is able to list my Maschine MK1, however immediately after connecting it fails to make any writes or reads and is stuck in an error loop.

Do you have any pointers on how I could fix this? Thanks a lot.

[MaschineMK1] tick: error in step #1 (read)
libusb: error [submit_bulk_transfer] submiturb failed error -1 errno=16
[DeviceHandleLibUSB] write: error=-1 - transfer size: 33 written: 0
[MaschineMK1] sendLeds: error writing first block of leds
[MaschineMK1] tick: error in step #2 (sendLeds)```
  

case-sensitive CoreMIDI error in DeviceTest

OSX 10.12
I got an error on building DeviceTest

ld: framework not found CoreMidi
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [examples/DeviceTest/device-test] Error 1
make[1]: *** [examples/DeviceTest/CMakeFiles/device-test.dir/all] Error 2
make: *** [all] Error 2

I have case-sensitive hard drive. To fix this, I rename CoreMidi to CoreMIDI.

target_link_libraries(${PROJECT_NAME} PUBLIC "-framework CoreAudio" "-framework CoreMidi" objc)

Update README.md, add git modules derectives

Maybe it a good idea add some help for git newbie and add command for git submodules. I'm talking about part where you say how to clone repository. Something like that:

git clone https://github.com/shaduzlabs/cabl.git
cd cabl
git submodule init
git submodule update
mkdir build && cd build

Cabl client interface

Hello,
And first of all, thanks for your work :-)

I own a Maschine MK1 controler, it's a very nice hardware and I would love to use it more.
I found out your nice reverse-enginieering and abstraction project, and I'm looking forward trying your lib.
I'm reading the code now, and would like to share some feedbacks and enhancement proposals (enhancements I may develop myself)

I see two uses-cases for cabl :

  1. Wanting to bind any controller like a gamepad (for example 4 buttons and 4 knobs), ignoring hardware labels

  2. Making a music software.

  • Labels on hardware are very convenient : "Volume" knob should control client volume on every device.
  • On key pressed, client wants to know what note it was.

As a reminder, here is the current abstraction interface :

Client.h

  virtual void buttonChanged(Device::Button button_, bool buttonState_, bool shiftPressed_);
  virtual void encoderChanged(unsigned encoder_, bool valueIncreased_, bool shiftPressed_);
  virtual void keyChanged(unsigned index_, double value_, bool shiftPressed);
  virtual void controlChanged(unsigned pot_, double value_, bool shiftPressed);

My remarks:

  1. First use case is impossible to implement properly :
  • because Client developer doesn't know which Device::Button is available on actual user hardware.
  • About knobs and key, client may choose to listen to knob 0. However, does abstraction guarantee that ids should be contiguous and starting at 0?
  1. About 2nd use case:
  • When pressing shift-Play, the client will observe Device::Button::Play, however shift-Play is labeled "Metronome" on Maschine MK1
  • There is an enum for button but not for encoder (Client cannot know changed encoder is the one labeled "MainVolume" on the device)
  • The Volume may be controlled by an encoder on some device and by a pot on others.

Proposed interface:

virtual  void  buttonChanged(  unsigned  button_,  bool    buttonState_,     bool  shiftPressed_, Device::Label label_ );
virtual  void  encoderChanged( unsigned  encoder_, bool    valueIncreased_,  bool  shiftPressed_, Device::Label label_ );
virtual  void  keyChanged(     unsigned  index_,   double  value_,           bool  shiftPressed_, Device::Label label_ );
virtual  void  controlChanged( unsigned  pot_,     double  value_,           bool  shiftPressed_, Device::Label label_ );

the button/knob parameters would be integers in range [0..NbOfButton[, [0..NbOfEncodor[, [0..NbOfControl[

Device::Label would be an enum with all common Labels. pressing shift would change label_ value (but not button id)

Key index_ could simply be value of a MIDI note. Device implementation should choose the best octave range, but we could required them to implement at least C4.

Unfortunately, this change is a serious interface break for legacy clients.

I hope I'm clear.
Let me know what you think about this analysis, if I'm missing something, if your plans are incompatible with this proposal, or if I should start coding :-)

MK2, shiftPressed in keyChanged always false

OSX 10.12, NI Maschine MKII

I have found bug: I press pad with shift button or without shift there is no difference. keyChanged always get false in shiftPressed. buttonChanged and encoderChanged work fine with shift button.

For test I had to modify DeviceTest.cpp example.

void DeviceTest::buttonChanged(Device::Button button_, bool buttonState_, bool shiftState_)
{
  std::string value = "Butt#" + std::to_string(static_cast<int>(button_)) + (shiftState_ ? " SHIFT" : "");
  device()->setButtonLed(
    button_, buttonState_ ? (shiftState_ ? kColor_Red : kColor_Yellow) : kColor_Black);

  device()->graphicDisplay(0)->black();
  device()->graphicDisplay(0)->putText(10, 10, value.c_str(), {0xff});
}

//--------------------------------------------------------------------------------------------------

void DeviceTest::encoderChanged(unsigned encoder_, bool valueIncreased_, bool shiftPressed_)
{
  std::string value = "Enc#" + std::to_string(static_cast<int>(encoder_)) + ( valueIncreased_ ? " increased" : " decreased" ) + (shiftPressed_ ? " SHIFT" : "");
  device()->textDisplay(0)->putText(value.c_str(), 0);

  device()->graphicDisplay(0)->black();
  device()->graphicDisplay(0)->putText(10, 10, value.c_str(), {0xff});

}

//--------------------------------------------------------------------------------------------------

void DeviceTest::keyChanged(unsigned index_, double value_, bool shiftPressed_)
{
  std::string value = "Pad#" + std::to_string(static_cast<int>(value_ * 0xff)) + (shiftPressed_ ? " SHIFT" : "");
  device()->setKeyLed(index_, {static_cast<uint8_t>(value_ * 0xff)});

  device()->graphicDisplay(0)->black();
  device()->graphicDisplay(0)->putText(10, 10, value.c_str(), {0xff});
}

Build error on develop branch

Hi there! First of all, thanks for taking the time to build this library! I started a similar project recently and your code helps a lot.

I have a Machine MK1 and I ran into the problem described on issue 10 when compiling the library from master. The test apps work fine if I rmmod snd-usb-caiaq first, but that's not ideal - especially considering I also have an Audio2 DJ that I plan to use in my project.

So I tried to compile the library again from develop, but it looks like unmidify is missing from this branch. It looks like a makefile problem, since unmidify is downloaded and compiled just fine on master, but I'm hardly an expert!

Here's the make output:

pi@pi ~/.../build(develop)$ make
Scanning dependencies of target cabl-static
[  0%] Building CXX object CMakeFiles/cabl-static.dir/src/client/Client.cpp.o
In file included from /home/pi/Code/cabl/src/devices/ableton/Push2.h:14:0,
                 from /home/pi/Code/cabl/src/client/Client.cpp:10:
/home/pi/Code/cabl/src/devices/generic/USBMidi.h:11:24: fatal error: unmidify.hpp: No such file or directory
 #include <unmidify.hpp>
                        ^
compilation terminated.
CMakeFiles/cabl-static.dir/build.make:62: recipe for target 'CMakeFiles/cabl-static.dir/src/client/Client.cpp.o' failed
make[2]: *** [CMakeFiles/cabl-static.dir/src/client/Client.cpp.o] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/cabl-static.dir/all' failed
make[1]: *** [CMakeFiles/cabl-static.dir/all] Error 2
Makefile:138: recipe for target 'all' failed
make: *** [all] Error 2

libusb: warning [darwin_transfer_status] transfer error: timed out

hey! awesome project. stoked to have found it after reading your blog posts.

I compiled & everything seems fine - the buttons work, the pads are lighting. Euklid looks really fun, but for some reason I can't hear anything.

It it looks like I keep getting this error in the terminal:

libusb: warning [darwin_transfer_status] transfer error: timed out

As the error implies, I'm on OSX, specifically 10.11. Anyhow, just out curiosity, if you know how to proceed, do tell, otherwise, thanks for the entertainment regardless.

[WIP] Support for Maschine MK3

This issue documents my findings about the Maschine MK3.

Basic Information from usb-devices

T:  Bus=02 Lev=02 Prnt=02 Port=05 Cnt=03 Dev#= 11 Spd=480 MxCh= 0
D:  Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=17cc ProdID=1600 Rev=01.41
S:  Manufacturer=Native Instruments
S:  Product=Maschine MK3
S:  SerialNumber=REMOVED
C:  #Ifs= 7 Cfg#= 1 Atr=80 MxPwr=480mA
I:  If#= 0 Alt= 0 #EPs= 0 Cls=01(audio) Sub=01 Prot=20 Driver=snd-usb-audio
I:  If#= 1 Alt= 1 #EPs= 1 Cls=01(audio) Sub=02 Prot=20 Driver=snd-usb-audio
I:  If#= 2 Alt= 0 #EPs= 0 Cls=01(audio) Sub=02 Prot=20 Driver=snd-usb-audio
I:  If#= 3 Alt= 0 #EPs= 2 Cls=01(audio) Sub=03 Prot=00 Driver=snd-usb-audio
I:  If#= 4 Alt= 0 #EPs= 2 Cls=03(HID  ) Sub=00 Prot=00 Driver=(none)
I:  If#= 5 Alt= 0 #EPs= 1 Cls=ff(vend.) Sub=bd Prot=00 Driver=(none)
I:  If#= 6 Alt= 0 #EPs= 0 Cls=fe(app. ) Sub=01 Prot=01 Driver=(none)

if#=5 is bulk data, maybe for the displays?
if#=6 seems to be for the firmware update.

Cant get demos to run on Windows 10. Works fine on Linux

Getting this on windows 10 when trying to run examples.

15:48:06: [LibUSB] enumerate
libusb: error [windows_get_device_list] program assertion failed - existing device should share parent
libusb: error [windows_get_device_list] program assertion failed - existing device should share parent
libusb: error [windows_get_device_list] program assertion failed - existing device should share parent
libusb: error [windows_get_device_list] program assertion failed - existing device should share parent
15:48:06: [LibUSB] enumerate: ITE Device(8595)(ITE Tech. Inc.)
libusb: warning [hid_open] could not open HID device in R/W mode (keyboard or mouse?) - trying without
libusb: error [hid_open] could not open device \.\USB#VID_046D&PID_C53F#6&2838F1DC&0&2#{A5DCBF10-6530-11D2-901F-00C04FB951ED} (interface 0): [2] The system cannot find the file specified.

Push 2 Display works, input doesn't

I have tested cabl with the maschine mk1 (which works great) and with the Ableton Push 2.
On the Push 2, I am able to draw to the display, but don't receive any data.

I already found out that the SysEx ID Request in DriverMidi.cpp was wrong and corrected it to:

 std::vector<unsigned char> sysExIdentity = {0xF0, 0x7E, 0x01, 0x06, 0x01, 0xF7};

After that, the MIDI driver successfully receives a device response, but still the controls don't work.

Here is a debug log with added info

16:40:42: Controller Abstraction Library v. 0.9.7
19:43:37: [LibUSB] initialization
17:00:44: [Client] Client
Type 'q' and hit ENTER to quit.
19:43:37: [HIDAPI] initialization (0)
19:43:37: [HIDAPI] enumerate
17:01:45: [DriverMIDI] initialization
17:01:45: [DriverMIDI] enumerate
17:01:45: [DriverMIDI] out: Midi Through:Midi Through Port-0 14:0 ->0
17:01:45: [DriverMIDI] in: Midi Through:Midi Through Port-0 14:0 ->0
[DriverMIDI] pending future: 1
17:01:45: [DriverMIDI] out: Ableton Push 2:Ableton Push 2 Live Port 20:0 ->1
17:01:45: [DriverMIDI] in: Ableton Push 2:Ableton Push 2 Live Port 20:0 ->1
[DriverMIDI] pending future: 2
17:01:45: [DriverMIDI] out: Ableton Push 2:Ableton Push 2 User Port 20:1 ->2
17:01:45: [DriverMIDI] in: Ableton Push 2:Ableton Push 2 User Port 20:1 ->2
[DriverMIDI] pending future: 3
17:01:45: [DriverMIDI] found device: 0:8477
17:01:45: [DriverMIDI] found device: 0:8477
17:01:45: [DriverMIDI] identity reply timeout on port #0
19:43:37: [LibUSB] enumerate
....
19:43:37: [LibUSB] enumerate: ()
19:43:37: [LibUSB] enumerate: Ableton Push 2(Ableton AG)
19:43:37: [LibUSB] enumerate: xHCI Host Controller(Linux 5.15.0-41-lowlatency xhci-hcd) with S/N "0000:00:14.0"
16:40:42: [Coordinator] scan: new device found via main driver
16:40:42: [Coordinator]: The devices list has changed
17:00:44: [Client] devicesListChanged : 1 devices
19:43:37: [LibUSB] connecting to 10626:6503:
19:43:37: [LibUSB] CONNECTED to 10626:6503:
Driver type is 2
Device handle is open
Creating device17:00:44: [Client] onInitDevice
Allocated 307200 bytes for display buffer
Got 0 Text Displays
Got 1 Display(s) with total resolution 960 x 160
- Display 0: 960 x 160

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.