Ableton / push-interface

The Ableton Push 2 MIDI and display interface manual.
647 stars 74 forks source link

Problems with section 3.2.6 of the MIDI and Display Interface Manual #15

Closed JackWitherell closed 7 years ago

JackWitherell commented 7 years ago

I've been working on making a program that can supply a customizable framework for a set of functions surrounding use of Ableton Push 2 outside of the program Ableton Live. I have a very small amount of experience with libraries outside of the C++ STL environment so I may sound quite casual in my interests.

I've been working on code to interface with the screen of the Ableton Push 2, and have found a bit of struggle in getting the code to work using the current libusb_fill_bulk_transfer mechanism. The issue I had previously was that if I tried making my program display a frame every 60th of a second, it would create a libusb_transfer object each and every time I wanted to output a frame to the program. This code was hard to work with as I had problems with libusb and the newest version of microsoft visual studio 2017 (deleting these pointer objects caused breaks in the program) and I opted for a libusb_bulk_transfer implementation instead.

instead of the code that is currently in 3.2.6 I'm currently doing this:

#define PUSH2_BULK_EP_OUT 0x01
#define TRANSFER_TIMEOUT  1000 // milliseconds

unsigned char buffer_to_be_transferred[2048]; //one line of blank pixels
int actual_length;
unsigned char frame_header[16] = {
        0xFF, 0xCC, 0xAA, 0x88,
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00 };

if (device_handle == nullptr) {
    std::cout<< "No device found!\n";
}
else { //print one frame
    libusb_bulk_transfer( //push out frame header
        device_handle,
        PUSH2_BULK_EP_OUT,
        frame_header,
        sizeof(frame_header),
        &actual_length,
        TRANSFER_TIMEOUT);
    for (int i = 0; i < 160; i++) { //print 160 lines of pixels
        libusb_bulk_transfer(
            device_handle,
            PUSH2_BULK_EP_OUT,
            buffer_to_be_transferred,
            2048,
            &actual_length,
            TRANSFER_TIMEOUT);
        }
    }
}

Doing this nullifies the need to create libusb_transfer objects and can reduce cleanup later.

If there's a deliberate reason why libusb_fill_bulk_transfer is being used, I would love to hear it from an education perspective. If the use of libusb_fill_bulk_transfer isn't necessary however I'd recommend having the example code changed for simplicity of future users.

rsu-ableton commented 7 years ago

The transfers are allocated and filled only once, on application startup. Then they are reused, i.e., in the transfer finished callback function - or later - they are resubmitted with new data. Typically we allocate 3 send buffers 16kbytes each.