Sonntag, 20. Februar 2011

Looking for MIDI Network Connections iOS

My next project will include a combined MIDI/OSC controller for iPad as well as a SysEx Editor/Bank Manager for my DSI Evolver. Since we don't really want another 3rd party application to be involved with the MIDI data, I will make use of Network MIDI.
You get the Network session simply by accessing the default session and activating it. Like this:
MIDINetworkSession *session = [MIDINetworkSession defaultSession];
session.connectionPolicy = MIDINetworkConnectionPolicy_Anyone;
session.enabled=YES;
But now you still don't have any connections, so you will have to listen for them until your host has connected to your application. The best way to do this, is by using a thread:
[NSThread detachNewThreadSelector:@selector(waitForConnections:) toTarget:self withObject:session];
Now you will have to create the waitForConnections: method:
- (void) waitForConnections:(id) argument {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    MIDINetworkSession *session = (MIDINetworkSession *)argument;
    BOOL found = NO;

    while (!found) {
        NSSet *connections =[session connections];
        if ((cons = [connections count]) > 0) {

            found = YES;
        } else {
            [NSThread sleepForTimeInterval:1];
        }
    }

    [... do something with connections ....]
    [pool release];
}
To use Network MIDI on a PC, you will have to install rtpMIDI, works just like Network MIDI on the Mac. I will post more on handling the MIDI part when I get there later.

Total Rehash

I have turned to iOS programming and shall posting my notes mainly on this subject. I'll start out with a little tutorial on reading data from a SQLite Database. My objective is to read a list of points in a route containing geographical information. This is the Method for reading this data.
- (NSArray *) fetchBetriebstelle: (NVGeoStrecke *) strecke {
  NSMutableArray *resultList = [[NSMutableArray alloc] init];
  sqlite3 *database;
  if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
    NSString *query = [NSString stringWithFormat:@"select IDX,DS100,BTRST_MITTE,LAT,LNG from INF_GEO_STR_BTRST where STR_GKEY = %d order by 1",strecke.key];
    const char *sqlStatement = [query UTF8String]; // Setup the SQL Statement
    sqlite3_stmt *compiledStatement;

    if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {

      while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
      // Read the data from the result row
      NVGeoStrBetriebsstelle *btrst = [[NVGeoStrBetriebsstelle alloc] init];
      btrst.index = sqlite3_column_int(compiledStatement, 0);
      btrst.name = [NSString stringWithUTF8String: (char *)sqlite3_column_text(compiledStatement, 1)];
      btrst.latitude = sqlite3_column_double(compiledStatement, 3);
      btrst.longitude = sqlite3_column_double(compiledStatement, 4);

      [resultList addObject:btrst];
      [btrst release];
      }
    }
    sqlite3_finalize(compiledStatement);
  }
  sqlite3_close(database);
  NSArray *result = [NSArray arrayWithArray:resultList];
  [resultList release];
  return result;
}
The next job will be to create a MapOverlay in a MKMapView and connect the points to a Path.