Network MIDI - MobileSheets iPad to Mac

I finally got my iPad Pro (First version) to talk MIDI with GP on an M1 MacBook Pro. I was having trouble, moved from ForScore to MobileSheets and it didn’t solve it, but it has (mostly) better MIDI support. Note that I’m using Wi-Fi for now, and I have an Ethernet dongle for the iPad arriving Friday.

Step 0 could be to set fixed IP addresses on your Mac and iPad for the network that you will use. It might be over a wired IP connection or through a Wi-Fi router that is not connected to the Internet that you use for gigging. A fixed IP address is helpful when discovery fails.

Step 1 is to set up MIDI over IP on the Mac.

  • Open Audio MIDI Setup
  • Show the MIDI Studio window
  • Open MIDI Network Setup
  • Create (+) a Session in “My Sessions”
  • Change the name to represent the other end, so “iPad”, “MobileSheets”, or something like that.
  • Set it so that “Anyone” can connect.
  • Launch MobileSheets on the iPad. Hopefully, 'iPad" will show up in the directory. (It seems that iPad is the default name that can’t be changed on MobileSheets.)
  • Select iPad and connect it. (If it doesn’t show up, create a connection to the IP address and name it “iPad-IP”, then connect it.)
  • The only Participant should be the iPad.
  • Enable the session by checking the check box.

GigPerformer will now have access to a MIDI connection called “iPad” or “MobileSheets”, depending on what you called it.

Step 2

  • In MobileSheets on the iPad, go to a score, touch it, and you should see a gear/setup icon in the lower right. Click it.
  • Click MIDI Settings.
  • Click Configure MIDI Connections.
  • Select Wi-Fi. (Maybe I’ll get an Ethernet button when I get my dongle?)
  • Enable “Network Session 1” for both the input and output ports. If you get any errors, reboot everything, restart MobileSheets, and ensure that the connection is active on the Mac.
  • Go back to a score and select the marker? cigar? icon in the upper left.
  • Select the MIDI tab.
  • Click the + button to add a command.
  • Label it “PC”
  • Command Type: Program Change.
  • Inout and Output ports: Network Session 1.
  • Set the command to something unique for that score. Let’s start with 0 and repeat this process for a second score with command = 1.
  • Enable both Send and Receive and hit OK.
  • Go back to the score.

You might think that you can now go to GigPerformer and get things to quickly work, but you’d be wrong. You could set up a monitor, but you won’t see the program change when you select the scores. On to…

Step 3, GigPerformer.

  • Go to Options|Global MIDI
  • Enable the “iPad” network connection in the Program Change Control secrtion.
  • I enabled “Only accepte program changes messages” on channel 1.
  • Enable MIDI Song select to PC and use MIDI Channel 1.
  • Go to the Setlist option. Enable PC and Next/Prebious MIDI assignments switches to Setlist view automatically.
  • Set the MIDI Out Device to Network iPad on Channel 1.
  • Go to the MIDI Ports option window and make sure that your Network iPad connection is enable.
  • Go to the setlist.
  • Double-click a Song.
  • Enable Send program change number when song activates.
  • Set PC # to 1. Bank MSB and LSB stay at 0.
  • Repeat for a second song, setting its PC # to 2.

That’s it. You should now be able to select songs in MobileSheets or in GigPerformer and have the two programs and devices sync’d.

Mobile sheets has some limitations. The name is simply “iPad” and the connection is simply “Network Session 1”. Also, it doesn’t seem to implement the Bank MSB and LSB, which severely limits the number of songs available. Frankly, this seems weird, as the developer is sensitive to having a huge collection of scores and pages. I expect that he will address this before long.

Overall, I much prefer an iPad in front of me for performing. I had a setup that held a laptop, but it blocked much of my view and was clunky.

Also, separating GigPerformer from the score view makes some sense. I might have a ton of piano scores that all select PC1 for a song on GP called “Piano”. I might do the same for Rhodes and B3 organ. But I might also have specific songs with lots of Song Parts and Variations, but it keeps GP focused on sounds and MobileSheets to focus on presentation.

I will also use the mod wheel control to advance pages, but first, get the song selections to work.There are lots of presentation options for MobileSheets, so that’s a whole 'nother topic.

Hello JonFair,

I’m the developer of MobileSheets (Mike Zuber) and wanted to provide some information. When it comes to the name of the rtp session, I’m utilizing the core MIDI classes that Apple provides, and I believe they may be using the device name (or some other identifier in the OS settings). If you rename your device in the OS settings, that may change the name that shows up with the rtp session. Apple does not seem to provide developers any way to change the session name that I can find.

As far as “Network Session 1”, that’s just what Apple calls the input and output MIDI ports for the default RTP session. MobileSheets is just reporting the ports that are detected through Apple’s framework. I could map to this to a different name, but I’m not sure how much benefit that would really provide.

You mentioned Bank MSB and LSB, but I already support a patch change command where you can turn on/off MSB, LSB and Value as desired. Bank MSB and LSB aren’t standard MIDI commands though. I’m assuming you are actually just referring to two control change messages, as a patch change is two control change messages followed by a program change message. I’d definitely like to hear more about what you are needing, as MobileSheets supports all of the standard MIDI messages, and you can send any number of commands in a row if needed, so there shouldn’t be anything that isn’t supported.



Thanks for your response, Mike. I’m looking forward to learning more and more about optimiing MobileSheet.

The name thing is odd. My iPad is named “Jon’s iPad Pro (2)”, and with other programs, that’s the name that comes across. MobileSheets seems to be picking up a generic name. It’s not a big deal for me, but it could be confusing for users with multiple iPads.

Regarding “Network Session 1”, it’s odd that it’s using a generic name, rather than the name that I assigned the session on my laptop or the Bonjour name of my laptop. Again, with multiple devices, it could be confusing, but it works fine.

Thanks for clarifying a Patch Change vs. a Program Change. In GigPerformer, it always lists it as a Program Change, so that’s what I looked for.

I’ve now changed the songs in MobileSheets to use Patch Changes. Let’s look at the two cases…

  1. GigPerformer song selection to MobileSheets…
    This works as expected. I can set the MSB, LSB, and Program in both programs, I change the song in GigPerformer, and all three numbers need to be aligned. Perfect! Two million plus songs are now available (127127127).

  2. MobileSheets to GigPerformer…
    This isn’t working as I might expect. It seems that the LSB and MSB must be set to 0 in MobileSheets and GigPerformer selects the song, linking the Program message with the order of the songs in the current Set List. So, the limitation seems to be on the GigPerformer side.

The bottom line is that I can have over 128 songs in GigPerformer, and I can select them in GP, send all three bytes to MobileSheets, and select the exact song that I want. However, when selecting songs from MobileSheets, only the first 128 songs can select a song in Gig Performer. As soon as I try a song with a different bank number, GP ignores it.

There is a switch in GP’s General MIDI menu that allows mapping of the MSB and LSB to 0. I recommend setting it, because once you set GP to a different bank, sending Program changes alone no longer work. It seems that they are now going to a phantom Bank.

Manually selecting different Set Lists in GP is likely a good workaround. In GP, map the bank MSB and LSB to 0, so they are ignored. In GP, assign banks based on Set Lists. Do the same in MobileSheets. Rather than relying on the MSB/LSB to change banks in GP, select the appropriate Set List in GP manually.

I’m not at risk of having over 128 songs in GigPerformer yet. I will get more scores than that in MobileSheets quickly, but many would likely just select the GP songs “Piano”, “Rhodes”, “B3”, etc. But I do use specific Songs in GP when I have MIDI sequences embedded for one-man shows.

Anyway, I wish that Bank changes selected Set Lists in GP. That would make the song count virtually unlimited.

I just tested renaming my iPad under Settings->General->About->Name, and when I opened MobileSheets, the network session shows up as the new name I selected on my Mac Mini (I’m using MIDI Network Setup in MIDI studio, but you can also use rtpMIDI on Windows). So I do believe that renaming the iPad should change the session name.

Network Session 1 is the MIDI input/output port name that Apple assigns internally to the rtp MIDI session. It’s an arbitrary name as far as I can tell, and I doubt there is a way to rename it. That shouldn’t show up on any other device though, as the session name should be named after the iPad.

I can’t speak to the issues you are seeing with Gig Performer when it comes to the patch change message you are sending. To clarify, a patch select in MobileSheets is the following:

  1. A control change with 0, MSB
  2. A control change with 32 (0x20), LSB
  3. A program change with value

I’m not sure what GP is expecting, but hopefully someone will chime in on that.


Then you have something misconfigured somewhere. I know this works as I use it myself.
Have you opened the global MIDI monitor in Gig Performer so you can see exactly what is being received by GP when you switch songs?

What should I expect? Let’s say, I’m in the “All Songs” Set List and I have a huge number of songs in GP. I have chosen to start Song numbering from 0 and I have not forced the Bank MSB and LSB to 0. Does MSB=0, LSB=1, and Program=0 select Song #128?

To me, the mental models of Songs, SetLists, Banks, and Programs in GP and MS differ. It’s no surprise, as they were designed separately. Unfortunately, it makes organiing things challenging.

For instance, let’s say I have a list of Songs in GP and they are matched to patch changes in MobileSheets. Then I add a new song at the start of the Set List in GP. Now all of my program changes in MS are off by one. Manually changing the program number for every song in MS to match would be a lot of work.

I’d prefer if I could set “Come Together” as MSB=0; LSB=1, PC=5 in both programs, so they would always sync. Then I could shuffle my SetLists whenever I want and GP and MS would always be in sync, no matter where I selected the song. I think GP has it right for sending Patch Changes, but when receiving, it’s up to Set List order, which should be more fluid,

Or maybe I’m not getting something fundamental. That’s certainly a possibility!

One step at a time please.

You commented that MSB/LSB wasn’t working so before you go any further, you should confirm that MobileSheets is sending and GP is receiving those bank select messages. Use the global MIDI manager for that.

That is because, without explicit assignments to parts, GP automatically orders songs this way.

If you review the online user guide related to song parts, you will see that there is the ability to explicitly associate a program change and MSB/LSB values to each song part so that there is no automatic reordering of song parts to program changes

That’s great! I’ll check it out this evening.

I saw the program change selections for Song Parts, but I didn’t dig into it, because I just wanted to link the apps at the Song level. Can I assume that I can just assign a Patch Change to the first Song Part in each Song, and use that?

Having two-way synchronization between the programs will be great. I generally do the one-man band thing with MIDI sequences. My plan is to use the Mod Wheel control of MobileSheets to advance pages. Previously, I was viewing lyrics in GP, advancing pages with Song Parts. It will be great to separate the control of presentation from the control of sounds. Often, I want to see the next lyrics in advance of the next part.

Maybe I’ve shortchanged myself by not considering Song Parts. Let’s say I have a score with each page associated with a Song Part. Now, if I flip to a given page, I get the desired sounds. This would be cool for practicing. I see a problem though. If my MIDI sequence turns the page before the next part, and MobileSheets immediately sends a Patch Change, the change would come too early. I would want MobileSheets to send a Patch Change message when I do manual page turns, but not when the page is turned from a Mod Wheel message. I’m not sure that this is possible, but I can think of some workarounds.

Anyway, first things first. I’ll implement Patch Changes on the first Song Part of each Song and try it out. Thanks!

There is no such thing as a “song” without a songpart, just like there is no such thing as a rackspace without a variation.


This makes no sense — why exactly would you assume that one page of sheet music is tied to one song part — you might have 10 pages of sheet music with a single song part and/or you might need to change the song part in the middle of one page of sheet music.

This also makes no sense — why are you tying individual pages of sheet music to individual song parts?

Regarding tying scores to Song Parts, I’m generally using lyric sheets that I generate myself, so I could have the chorus on one page, verse on another, etc. Yeah, it wouldn’t make sense for reading 3rd party sheet music.

I was thinking that I might flip the pages on the iPad to the bridge and practice that section with the right sounds coming up automatically. And yeah, this is low value with many possible exceptions, so let’s avoid that path.

I’ll definitely use the Mod Wheel to flip pages. I’ll try it out tonight.

Great news. Everything is working perfectly, including using Pitch Bend for page indexing. (I wrote “Mod Wheel” in some posts above. My mistake.)

The only weirdness is from Logic, when setting Pitch Bend messages in the sequence. I’ve never been able to figure out how to make MIDI automation values be sample-and-hold, rather than ramps to the next value. I press “D” to edit in text, rather than using the mouse, and sometimes, I get a series of numbers in the MIDI Monitor. Also, it seems to default to zero, rather than-8191, so I end up on the last page at times. But this is a Logic and MIDI spec thing, rather than a GP or MS thing.

The last piece of the puzzle was learning that in GP, the Song sets the Patch Change to send and the Song Part defines the Patch Change to detect.

Now… back to music…

It defines an initial patch change to send.

But you can attach MIDI messages to individual song parts as well, so switching to a specific song part can also send out MIDI messages

1 Like