Auto-connection concepts / Pro Tools issue

Auto-connection concepts / Pro Tools issue

Postby nphuma » 22 Feb 2012, 13:04

So, I'm back experimenting and as previously announced I have a number of questions:

What I am trying to do is create a hybrid MIDI device and have that autoconnect itself to the default "MIDI" object. I'm fine with the first part. I can create the device and am able to send and receive data when I wire it up manually. However I seem to get stuck with the second part, mostly due to understanding basic concepts, I guess. Effectively I reached the point where your documentation is more a "to do" list ;-)

My guess would be that I need to query for remote devices, find the one I'm interested in, then query that for in- and outputs and connect myself. So I played around with those async "Find" routines and while I am in fact finding the remote device I have no real idea how to proceed from there onwards.

First of all: How about the IRemoteDevice* validity in the OnCHAI_RemoteDevice_Find_Return callback? It seems to go out of scope when that message returns and I can't seem to access it afterwards. If that is the case, am I expected to trigger In- and Output queries on that device from within the callback?

Second, when I do that (call FindFirstInputInformation_Async from the callback and FindNextInputInformation_Async from the OnRemoteDevice_XXXInputInfo_Return callback) I do get both a MID2CPInterface and a CP2MIDIInterface pointer. However I would somehow expect one of them to be an output and rather appear in OnRemoteDevice_XXXOutputInfo_Return, but I never get anything in the FindFirst / Next Output / XXXOutput sequence, both are retrieved in the input related sequence. Given that's still perfectly OK, how do I proceed from there in order to connect them to my local device?

Finally I'm afraid I found another problem in CopperLan (you'll start to hate me soon..). Namely there seems to be a conflict with Pro Tools on Windows. When CopperLan is installed, Pro Tools gets stuck and becomes unresponsive on opening or creating sessions. Uninstall CopperLan and everything is fine. I have reproduced that on Vista and Windows 7 systems, both 64bit. Of course I can't guarantee that it is not somehow related to something specific to those particular machines, but I would appreciate if you could take a look at this. After all it's about Pro Tools, so even if nobody really likes it, it will still be everywhere.

Thanks and regards

nils
nphuma
 
Posts: 7
Joined: 07 Feb 2012, 20:38

Re: Auto-connection concepts / Pro Tools issue

Postby CopperPhil » 22 Feb 2012, 17:56

Hi Nils,

Well I'm glad to read you with so much questions :-)

nphuma wrote:My guess would be that I need to query for remote devices, find the one I'm interested in, then query that for in- and outputs and connect myself. So I played around with those async "Find" routines and while I am in fact finding the remote device I have no real idea how to proceed from there onwards.


You are on the right way. The "Find*" async routines are used to enumerate the devices matching your requirements on the network. Usually, enumeration is done using FDO_None flag, meaning that it is done on root devices. FDO_NoHierarchy flag can be used to perform a flat search, but it is rarely used. The result of enumeration is a set of "Remote Devices" which are proxy objects allowing to remote control/get information about a distant device.

nphuma wrote:First of all: How about the IRemoteDevice* validity in the OnCHAI_RemoteDevice_Find_Return callback? It seems to go out of scope when that message returns and I can't seem to access it afterwards. If that is the case, am I expected to trigger In- and Output queries on that device from within the callback?


Just take care about one thing: IRemoteDevice inherit from IHookedObject. The object is dereferenced at the end of the async return handler, and so destroyed if no more hooked. So if you expect to keep a list of IRemoteDevice objects, you have to "Acquire" it at the moment you store it in your list to prevent destruction on async return handler exit. And of course, you have to "Release" it once you don't need it anymore.

So, you can trigger in/out exploration from within the callback, or later... but in any case, it is a good practice to keep alive the IRemoteDevice in an application list during the process, simply because you might need it again later.

I know I have to enhance the documentation, it's a looooong job. But your mail give me motivation to do it :-)

Here you can find this sentence: A hooked object is always Acquired before being passed as argument to an asynchronous return handler, and then Released on return of this handler. This is to ensure that the object will not be destroyed during the notification call. An application storing a pointer to a hooked object must acquire it and release it once useless.

nphuma wrote:Second, when I do that (call FindFirstInputInformation_Async from the callback and FindNextInputInformation_Async from the OnRemoteDevice_XXXInputInfo_Return callback) I do get both a MID2CPInterface and a CP2MIDIInterface pointer. However I would somehow expect one of them to be an output and rather appear in OnRemoteDevice_XXXOutputInfo_Return, but I never get anything in the FindFirst / Next Output / XXXOutput sequence, both are retrieved in the input related sequence. Given that's still perfectly OK, how do I proceed from there in order to connect them to my local device?


Calling Find*InputInformation_Async is used to enumerate inputs from a remote device. You can get input list from a CP2MIDI device, or a HybridMIDI device... not from a MIDI2CP device.

You can find some clue from here.

A MIDI2CP device is used to translate MIDI to CopperLan, so it has a set of 18 outputs (1 per MIDI channel, 1 for clock messaging, 1 for SysEx and not channel related messages).
A CP2MIDI device is doing the reverse job, it has 17 inputs (1 for each MIDI channel, and 1 for everything not channel related).
A HybridMIDI is a combination of both.

Knowing that, if you want to bind a virtual MIDI cable between both, and since the in/out structure is well-known, you can do it without having to enumerate them. The virtual MIDI cable patching is:
MIDI2CP:Out(0)->CP2MIDI:In(0) Clock
MIDI2CP:Out(1)->CP2MIDI:In(0) Sysex and no channel, sharing the same input than Clock on the target.
MIDI2CP:Out(2->17)->CP2MIDI:In(1->16) Channel to channel patching.

So to perform this, two cases:
- you are expecting to add destination to a remote device's output (related to a MIDI2CP or HybridMIDI device): you just have to call AddDestination on this remote device pointer, giving the output ID (from 0 to 17) and the target endpoint (made from the target device ID and the related input ID).
- you want to add a destination to a local device (you MIDI2CP application is self-connecting to the target device), just call AddDestination from the right output pointer (you can get it using GetOutputFromID on the local device)

Is it clear enough? feel free to call me again if I missed something in your request...

nphuma wrote:Finally I'm afraid I found another problem in CopperLan (you'll start to hate me soon..).....


No problem, you are just the first to report these issues ;-) It's a good point for us! We have tested CopperLan against a lot of systems and configurations, but it's impossible to cover any use case unfortunately.

I'll check if we can make a Pro-Tools debugging session. But in the meantime, I'm thinking about a potential issue with other program creating/handling MIDI ports. By default, CopperLan is configured to handle automatically MIDI ports. It means that these ports are hooked by CopperLan, and so becomes invalid for other applications. Windows does not allow multiple application to open the same MIDI port unfortunately... so if CopperLan is already handling a MIDI port, other application becomes unable to open it.

The CopperLan MIDI auto-handling behavior can be disabled through the Editor, entering in the "MIDI device" related to your computer, "MIDI Settings", "MIDI port auto-handling" parameter. Can you please try again ensuring that this parameter is off, then check that MIDI ports are off in the "MIDI to CP Interface" and "CP to MIDI interface". A reboot might be necessary depending on the MIDI port status and the Pro-Tools ability to handle it again or not.

Thanks again for your feedback and questions,

/Phil
CopperPhil
 
Posts: 480
Joined: 30 Mar 2011, 15:02
Location: Brussels

Re: Auto-connection concepts / Pro Tools issue

Postby nphuma » 23 Feb 2012, 11:44

Thanks for clarifying on IHookedObject. I was obviously focussed too much on the programming guide part of the docs and of course now see it all clearly in the doxygen files. Guess that's just the way it is with stupid users...

When it comes to autoconnection I seem to be one step further, but still feel like I'm pretty much poking around in the dark.
What I do get working is connecting the default MIDI object as a destination to my local device (which is a RootDevice with a SubHybridMIDIDevice in the moment). I'm not seeing data that I input in my application arrive anywhere, though (SendMIDIBlob seems to consume it fine, judged by what it returns in the &consumed parameter). Also I'm not sure if there is a way to specifically address the "Virtual MIDI Cable" slot or if I need to wire up all the other 18 slots in order to get alll eventual MIDI accross? And how would I specifically target one of the VMIDI ports?

The other way around does not seem to work out for me so far. That is: Calling AddDestination on the RemoteDevice returns 0 whatever I try (I assume that 0 indicates an error, but am not really sure about that: the error_code enum is empty in the doxygen docs. The seemingly successful connections in the other direction return 1). I suspect that my endpoint construction might be the culprit. Would I need to use the RootDevice's ID, the (Sub)MIDIDevice's, or something else? Could it be about pointer dereferencing (as AddDestination does not take a pointer to the endpoint)?

Anyway, it's probably just about getting used to the API and learning a bit. But if you'd find the time to put up some connection related samplecode I would sure appreciate it.

In terms of the Pro Tools problem: Yes, disabling port auto handling and switching off all the ports in both MIDI2CP and CP2MIDI settings seems to solve it. I am not entirely sure yet, but it does seem to come down to an M-Audio MIDISport 2*2 Aniversary interface causing the problem. Pro Tools' most advanced DAE wants me to reboot whenever it failed to launch and as I have a lot of MIDI interfaces connected it will need some time to nail it down to that. I'll try again when I'm otherwise to dizzy to do more than watching a computer reboot. It's worth noting though, that no other sequencer does have that problem. Cubase, Ableton Live, FL Studio, SAW Studio, Reason all seem to be fine with the ports active and auto handling on. A busy port usually also just triggers error notifications in Pro Tools instead of freezing it entirely.

Thanks again & regards

nils
nphuma
 
Posts: 7
Joined: 07 Feb 2012, 20:38

Re: Auto-connection concepts / Pro Tools issue

Postby CopperPhil » 23 Feb 2012, 20:17

nphuma wrote:...Also I'm not sure if there is a way to specifically address the "Virtual MIDI Cable" slot or if I need to wire up all the other 18 slots in order to get alll eventual MIDI accross? And how would I specifically target one of the VMIDI ports?


The "Virtual MIDI Cable" is an abstract notion. It is a way to ease the connection of a MIDI2CP to a CP2MIDI device at the end-user level. Basically it consists in wiring up the 18 outputs to the 17 inputs as I described in the previous message.

nphuma wrote:The other way around does not seem to work out for me so far. That is: Calling AddDestination on the RemoteDevice returns 0 whatever I try (I assume that 0 indicates an error, but am not really sure about that: the error_code enum is empty in the doxygen docs.


AddDestination return type is CPNS::Enums::Errors, and 0 is ERR_None (see on thispage, the header files are missing some Doxygen tags indeed). There is no fail/success feedback for this kind of operation. The local device to which the destination is added can notify the related application about success status, but a distant device adding a destination to another one just send a command over the network.

Anyway, you can check if the connection is added thanks to the CopperLan Manager, from the Overview or the Connection tabs.

nphuma wrote:The seemingly successful connections in the other direction return 1). I suspect that my endpoint construction might be the culprit. Would I need to use the RootDevice's ID, the (Sub)MIDIDevice's, or something else? Could it be about pointer dereferencing (as AddDestination does not take a pointer to the endpoint)?


The target endpoint must be pointiong to the target input. So if this target input is related to a sub-device (hybrid midi or CP2MIDI), the DeviceID part of this endpoint must point to this sub-device. A sub-device has the same DeviceID than its root device, except the ModuleID field (see here). So if you know the device tree structure of the target application, you can use GetDeviceID from the found root remote device and update the ModuleID to point to the good sub-device. If you don't know anything about the target application, you have to enumerate devices specifying the root device ID in order to get the list of sub-devices.

It may seem complicated, but it is just a question of habit...

nphuma wrote:Anyway, it's probably just about getting used to the API and learning a bit. But if you'd find the time to put up some connection related samplecode I would sure appreciate it.


Sure. Added to my to-do list, I'll do asap.

nphuma wrote:In terms of the Pro Tools problem: Yes, disabling port auto handling and switching off all the ports in both MIDI2CP and CP2MIDI settings seems to solve it....


Good news! Perhaps it would be better to ask the user if he wants CopperLan to handle MIDI ports automatically at the end of installation. I'll check that.
CopperPhil
 
Posts: 480
Joined: 30 Mar 2011, 15:02
Location: Brussels

Re: Auto-connection concepts / Pro Tools issue

Postby Luc Henrion » 24 Feb 2012, 10:25

Good news! Perhaps it would be better to ask the user if he wants CopperLan to handle MIDI ports automatically at the end of installation. I'll check that.


Yes please, this could maybe help me too with old machines full of MIDI interfaces of any kind ! ;)
Luc Henrion
 
Posts: 9
Joined: 19 Dec 2011, 12:42


Return to Generalities

cron