コード例 #1
0
ファイル: message_format.c プロジェクト: jpommerening/midikit
/**
 * @brief Detect the format of message stored in a buffer.
 * Determine the message format used in a stream of bytes.
 * @public @memberof MIDIMessageFormat
 * @param buffer The message as it would appear on a MIDI cable.
 * @return a pointer to the correct message format if the format could be detected.
 * @return a NULL pointer if the format could not be detected.
 */
struct MIDIMessageFormat * MIDIMessageFormatDetect( void * buffer ) {
  static struct MIDIMessageFormat * formats[] = {
    &_note_off_on,
    &_polyphonic_key_pressure,
    &_control_change,
    &_program_change,
    &_channel_pressure,
    &_pitch_wheel_change,
    &_system_exclusive,
    &_time_code_quarter_frame,
    &_song_position_pointer,
    &_song_select,
    &_tune_request,
    &_real_time
  };
  int i;
  MIDIPrecondReturn( buffer != NULL, EFAULT, NULL );
  for( i=0; i<N_ELEM(formats); i++ ) {
    MIDIAssert( formats[i] != NULL && formats[i]->test != NULL );
    if( (formats[i]->test)( buffer ) ) {
      return formats[i];
    }
  }
  return NULL;
}
コード例 #2
0
ファイル: event.c プロジェクト: jitendarKumar/midikit
/**
 * @brief Destroy a MIDIEvent instance.
 * Free all resources occupied by the event and release all referenced objects.
 * @public @memberof MIDIEvent
 * @param event The event.
 */
void MIDIEventDestroy( struct MIDIEvent * event ) {
  MIDIPrecondReturn( event != NULL, EFAULT, (void)0 );
  if( event->message != NULL ) {
    free( event->message );
  }
  free( event );
}
コード例 #3
0
ファイル: cfintegration.c プロジェクト: VishalChandla/midikit
struct CFMIDIRunloop * CFMIDIRunloopCreate( CFRunLoopRef runloop ) {
  struct CFMIDIRunloop * cf_runloop = malloc( sizeof( struct CFMIDIRunloop ) );
  MIDIPrecondReturn( cf_runloop != NULL, ENOMEM, NULL );
  
  cf_runloop->refs    = 1;
  cf_runloop->runloop = runloop;
  
  cf_runloop->timer_context.version = 0;
  cf_runloop->timer_context.info = cf_runloop;
  cf_runloop->timer_context.release = &_cf_release_callback;
  cf_runloop->timer_context.retain  = &_cf_retain_callback;
  cf_runloop->timer_context.copyDescription = NULL;

  cf_runloop->socket_context.version = 0;
  cf_runloop->socket_context.info = cf_runloop;
  cf_runloop->socket_context.release = &_cf_release_callback;
  cf_runloop->socket_context.retain  = &_cf_retain_callback;
  cf_runloop->socket_context.copyDescription = NULL;

  cf_runloop->delegate.info = cf_runloop;
  cf_runloop->delegate.schedule_read    = &_cf_runloop_schedule_read;
  cf_runloop->delegate.schedule_write   = &_cf_runloop_schedule_write;
  cf_runloop->delegate.schedule_timeout = &_cf_runloop_schedule_timeout;
  cf_runloop->delegate.clear_read    = &_cf_runloop_clear_read;
  cf_runloop->delegate.clear_write   = &_cf_runloop_clear_write;
  cf_runloop->delegate.clear_timeout = &_cf_runloop_clear_timeout;
  return cf_runloop;
}
コード例 #4
0
ファイル: port.c プロジェクト: jitendarKumar/midikit
/**
 * @brief Release a MIDIPort instance.
 * Decrement the reference counter of a port. If the reference count
 * reached zero, destroy the port. Before decrementing the reference
 * count check for invalidated connected ports and remove them to
 * break retain cycles.
 * @public @memberof MIDIPort
 * @param port The port.
 */
void MIDIPortRelease( struct MIDIPort * port ) {
  MIDIPrecondReturn( port != NULL, EFAULT, (void)0 );
  if( port->refs > 1 ) {
    MIDIListApply( port->ports, port, &_port_apply_check );
  }
  MIDILogLocation( DEVELOP, "Release port %s [%p] (%i -> %i)\n", port->name, port, port->refs, port->refs -1 );
  if( ! --port->refs ) {
    MIDIPortDestroy( port );
  }
}
コード例 #5
0
ファイル: driver.c プロジェクト: mgsx-dev/midikit
/**
 * @brief Initialize a MIDIDriver instance.
 * @public @memberof MIDIDriver
 * @param name The name to identify the driver.
 * @param rate The sampling rate to use.
 */
void MIDIDriverInit( struct MIDIDriver * driver, char * name, MIDISamplingRate rate ) {
    MIDIPrecondReturn( driver != NULL, EFAULT, (void)0 );

    driver->refs  = 1;
    driver->rls   = NULL;
    driver->port  = MIDIPortCreate( name, MIDI_PORT_IN | MIDI_PORT_OUT, driver, &_port_receive );
    driver->clock = MIDIClockProvide( rate );

    driver->send    = NULL;
    driver->destroy = NULL;
}
コード例 #6
0
ファイル: port.c プロジェクト: jitendarKumar/midikit
/**
 * @brief Destroy a MIDIPort instance.
 * Free all resources occupied by the port and release connected ports.
 * @public @memberof MIDIPort
 * @param port The port.
 */
void MIDIPortDestroy( struct MIDIPort * port ) {
  MIDIPrecondReturn( port != NULL, EFAULT, (void)0 );
  MIDIListRelease( port->ports );
  /* If we get problems with with access to freed ports we could
   * enable this temporarily ..
   * port->ports = NULL;
   * MIDIPrecondReturn( port->valid == 0, ECANCELED, (void)0 ); */
  MIDILogLocation( DEVELOP, "Destroy port %s [%p]\n", port->name, port );
  free( port->name );
  free( port );
}
コード例 #7
0
ファイル: cfintegration.c プロジェクト: VishalChandla/midikit
struct CFMIDIRunLoopSource * CFMIDIRunLoopSourceCreate( struct MIDIRunloopSource * source ) {
  int i, create;
  CFRunLoopTimerContext timer_context;
  CFSocketContext       socket_context;
  CFOptionFlags         socket_cb_types;
  CFSocketRef           socket;
  struct CFMIDIRunLoopSource * cf = malloc( sizeof(struct CFMIDIRunLoopSource)
                                          + sizeof(CFRunLoopSourceRef)*(source->nfds-1) );
  MIDIPrecondReturn( cf != NULL, ENOMEM, NULL );
  
  timer_context.version = 0;
  timer_context.info = source;
  timer_context.release = NULL;
  timer_context.retain  = NULL;
  timer_context.copyDescription = NULL;

  socket_context.version = 0;
  socket_context.info = source;
  socket_context.release = NULL;
  socket_context.retain  = NULL;
  socket_context.copyDescription = NULL;
  
  cf->length = source->nfds;

  if( source->timeout.tv_sec > 0 || source->timeout.tv_nsec > 0 ) {
    cf->cfrlt = CFRunLoopTimerCreate( NULL, CFAbsoluteTimeGetCurrent(),
      (double) source->timeout.tv_sec + 0.000000001 * (double) source->timeout.tv_nsec,
      0, 1, &_cf_timer_callback, &timer_context );
  } else {
    cf->cfrlt = NULL;
  }

  for( i=0; i<cf->length; i++ ) {
    create = 0;
    socket_cb_types = kCFSocketNoCallBack;
    if( FD_ISSET(i, &(source->readfds)) ) {
      socket_cb_types |= kCFSocketReadCallBack;
      create = 1;
    }
    if( FD_ISSET(i, &(source->writefds)) ) {
      socket_cb_types |= kCFSocketWriteCallBack;
      create = 1;
    }
    if( create ) {
      socket       = CFSocketCreateWithNative( NULL, i, socket_cb_types, &_cf_socket_callback, &socket_context );
      cf->cfrls[i] = CFSocketCreateRunLoopSource( NULL, socket, 1 );
      CFRelease( socket );
    } else {
      cf->cfrls[i] = NULL;
    }
  }
  return cf;
}
コード例 #8
0
ファイル: port.c プロジェクト: jitendarKumar/midikit
/**
 * @brief Create a MIDIPort instance.
 * Allocate space and initialize a MIDIPort instance.
 * @public @memberof MIDIPort
 * @param name    The name of the MIDIPort.
 * @param mode    The communication mode flags.
 * @param target  The target for receiving messages.
 * @param receive The callback for incoming messages.
 * @return a pointer to the created port structure on success.
 * @return a @c NULL pointer if the port could not created.
 */
struct MIDIPort * MIDIPortCreate( char * name, int mode, void * target,
                                  int (*receive)( void *, void *, struct MIDITypeSpec *, void * ) ) {
  MIDIPrecondReturn( name != NULL, EINVAL, NULL );
  if( mode & MIDI_PORT_IN ) {
    MIDIPrecondReturn( target != NULL, EINVAL, NULL );
    MIDIPrecondReturn( receive != NULL, EINVAL, NULL );
  }
  struct MIDIPort * port = malloc( sizeof( struct MIDIPort ) );
  size_t namelen;
  MIDIPrecondReturn( port != NULL, ENOMEM, NULL );

  namelen = strlen( name ) + 1;
  if( namelen > 128 ) namelen = 128;

  port->refs    = 1;
  port->mode    = mode;
  port->name    = malloc( namelen );
  port->target  = target;
  port->receive = receive;

  if( port->name == NULL ) {
    free( port );
    return NULL;
  }
  
  port->ports   = MIDIListCreate( MIDIPortType );
  if( port->ports == NULL ) {
    /* probably ENOMEM, in that case, error code is already set by MIDIList */
    free (port->name);
    free( port );
    return NULL;
  }

  port->intercept = NULL;
  port->observer  = NULL;

  strncpy( port->name, name, namelen );

  return port;
}
コード例 #9
0
ファイル: cfintegration.c プロジェクト: VishalChandla/midikit
/**
 * @brief Destroy a CFMIDIRunLoopSource instance.
 * Free all resources occupied by the runloop soruce and release all referenced objects.
 * @public @memberof CFMIDIRunLoopSource
 * @param source The runloop source.
 */
void CFMIDIRunLoopSourceDestroy( struct CFMIDIRunLoopSource * source ) {
  int i;
  MIDIPrecondReturn( source != NULL, EFAULT, (void)0 );
  if( source->cfrlt != NULL ) {
    CFRunLoopTimerInvalidate( source->cfrlt );
    CFRelease( source->cfrlt );
  }
  for( i=0; i<source->length; i++ ) {
    if( source->cfrls[i] != NULL ) {
      CFRunLoopSourceInvalidate( source->cfrls[i] );
      CFRelease( source->cfrls[i] );
    }
  }
  free( source );
}
コード例 #10
0
ファイル: driver.c プロジェクト: mgsx-dev/midikit
/**
 * @brief Destroy a MIDIDriver instance.
 * Free all resources occupied by the driver and release all referenced objects.
 * @public @memberof MIDIDriver
 * @param driver The driver.
 */
void MIDIDriverDestroy( struct MIDIDriver * driver ) {
    MIDIPrecondReturn( driver != NULL, EFAULT, (void)0 );
    if( driver->destroy != NULL ) {
        (*driver->destroy)( driver );
    }
    if( driver->clock != NULL ) {
        MIDIClockRelease( driver->clock );
    }
    if( driver->rls != NULL ) {
        MIDIRunloopSourceInvalidate( driver->rls );
        MIDIRunloopSourceRelease( driver->rls );
    }
    MIDIPortInvalidate( driver->port );
    MIDIPortRelease( driver->port );
    free( driver );
}
コード例 #11
0
ファイル: coremidi.c プロジェクト: Ewald123/midikit
/**
 * @brief Create a MIDIDriverCoreMIDI instance.
 * Allocate space and initialize an MIDIDriverCoreMIDI instance.
 * @public @memberof MIDIDriverCoreMIDI
 * @return a pointer to the created driver structure on success.
 * @return a @c NULL pointer if the driver could not created.
 */
struct MIDIDriverCoreMIDI * MIDIDriverCoreMIDICreate( char * name, MIDIClientRef client ) {
  struct MIDIDriverCoreMIDI * driver;
  CFStringRef in_name, out_name;
  
  driver = malloc( sizeof( struct MIDIDriverCoreMIDI ) );
  MIDIPrecondReturn( driver != NULL, ENOMEM, NULL );
  MIDIDriverInit( &(driver->base), name, COREMIDI_CLOCK_RATE );

  driver->client = client; 
  in_name  = CFStringCreateWithFormat( NULL, NULL, CFSTR("MIDIKit %s input"), name );
  out_name = CFStringCreateWithFormat( NULL, NULL, CFSTR("MIDIKit %s input"), name );
  
  MIDIInputPortCreate( client, in_name, &_coremidi_readproc, driver, &(driver->cm_in_port) );
  MIDIOutputPortCreate( client, out_name, &(driver->cm_out_port) );

  return driver;
}
コード例 #12
0
ファイル: applemidi.c プロジェクト: rajnish11062/midikit
/**
 * @brief Create a MIDIDriverAppleMIDI instance.
 * Allocate space and initialize an MIDIDriverAppleMIDI instance.
 * @public @memberof MIDIDriverAppleMIDI
 * @return a pointer to the created driver structure on success.
 * @return a @c NULL pointer if the driver could not created.
 */
struct MIDIDriverAppleMIDI * MIDIDriverAppleMIDICreate( char * name, unsigned short port ) {
  struct MIDIDriverAppleMIDI * driver;
  MIDITimestamp timestamp;
  int ret = 0;

  driver = malloc( sizeof( struct MIDIDriverAppleMIDI ) );
  MIDIPrecondReturn( driver != NULL, ENOMEM, NULL );
  MIDIDriverInit( &(driver->base), name, APPLEMIDI_CLOCK_RATE );
 
  driver->control_socket = 0;
  driver->rtp_socket     = 0;
  driver->port           = port;
  driver->accept         = 0;
  driver->sync           = 0;
  strncpy( &(driver->name[0]), name, sizeof(driver->name) );

  driver->in_queue  = MIDIMessageQueueCreate();
  driver->out_queue = MIDIMessageQueueCreate();
  
  driver->base.send    = &_driver_send;
  driver->base.destroy = &_driver_destroy;
  
  ret = _applemidi_connect( driver );
  if (ret==-1)
    MIDILog( ERROR, "Bind failed for port: %hu\n", port);

  driver->peer = NULL;
  driver->rtp_session     = RTPSessionCreate( driver->rtp_socket );  
  driver->rtpmidi_session = RTPMIDISessionCreate( driver->rtp_session );

  MIDIClockGetNow( driver->base.clock, &timestamp );
  MIDILog( DEBUG, "initial timestamp: %lli\n", timestamp );
  driver->token = timestamp;

  memset( &(driver->command), 0, sizeof(driver->command) );
  driver->command.peer = NULL;

  _applemidi_init_runloop_source( driver );

  return driver;
}
コード例 #13
0
ファイル: event.c プロジェクト: jitendarKumar/midikit
/**
 * @brief Create a MIDIEvent instance.
 * Allocate space and initialize a MIDIEvent instance.
 * @public @memberof MIDIEvent
 * @param id      A (hopefully) unique ID.
 * @param info    Any optional data to be associated with the event.
 * @param message A message format that may contain placeholders.
 * @param ...     The data to be filled into the message format placeholders.
 *                (Refer to the sprintf specification for details.)
 * @return a pointer to the created event structure on success.
 * @return a @c NULL pointer if the event could not created.
 */
struct MIDIEvent * MIDIEventCreate( size_t id, void * info, char * message, ... ) {
  void * buffer;
  size_t length, required;
  va_list vargs;
  struct MIDIEvent * event = malloc( sizeof( struct MIDIEvent ) );
  MIDIPrecondReturn( event != NULL, ENOMEM, NULL );

  event->refs = 1;
  event->id   = id;
  event->info = info;

  if( message != NULL ) {
    length = 64;
    buffer = malloc( length );

    va_start( vargs, message );
    do {
      if( buffer == NULL ) {
        MIDIError( ENOMEM, "Could not allocate space for static buffer." );
        free (event);
        return NULL;
      }
      required = vsnprintf( buffer, length-1, message, vargs );
      if( required > length ) {
        buffer = realloc( buffer, required );
        length = required;
      }
    } while( required > length );
    va_end( vargs );

    event->message = buffer;
    event->length  = length;
  } else {
    event->message = NULL;
    event->length  = 0;
  }

  return event;
}
コード例 #14
0
ファイル: driver.c プロジェクト: mgsx-dev/midikit
/**
 * @brief Retain a MIDIDriver instance.
 * Increment the reference counter of a driver so that it won't be destroyed.
 * @public @memberof MIDIDriver
 * @param driver The driver.
 */
void MIDIDriverRetain( struct MIDIDriver * driver ) {
    MIDIPrecondReturn( driver != NULL, EFAULT, (void)0 );
    driver->refs++;
}
コード例 #15
0
ファイル: cfintegration.c プロジェクト: VishalChandla/midikit
/**
 * @brief Release a CFMIDIRunLoopSource instance.
 * Decrement the reference counter of a clock. If the reference count
 * reached zero, destroy the clock.
 * @public @memberof CFMIDIRunLoopSource
 * @param source The runloop source.
 */
void CFMIDIRunLoopSourceRelease( struct CFMIDIRunLoopSource * source ) {
  MIDIPrecondReturn( source != NULL, EFAULT, (void)0 );
  if( ! --source->refs ) {
    CFMIDIRunLoopSourceDestroy( source );
  }
}
コード例 #16
0
ファイル: cfintegration.c プロジェクト: VishalChandla/midikit
/**
 * @brief Retain a CFMIDIRunLoopSource instance.
 * Increment the reference counter of a clock so that it won't be destroyed.
 * @public @memberof CFMIDIRunLoopSource
 * @param source The runloop source.
 */
void CFMIDIRunLoopSourceRetain( struct CFMIDIRunLoopSource * source ) {
  MIDIPrecondReturn( source != NULL, EFAULT, (void)0 );
  source->refs++;
}
コード例 #17
0
ファイル: port.c プロジェクト: jitendarKumar/midikit
/**
 * @brief Retain a MIDIPort instance.
 * Increment the reference counter of a port so that it won't be destroyed.
 * @public @memberof MIDIPort
 * @param port The port.
 */
void MIDIPortRetain( struct MIDIPort * port ) {
  MIDIPrecondReturn( port != NULL, EFAULT, (void)0 );
  port->refs++;
}
コード例 #18
0
ファイル: event.c プロジェクト: jitendarKumar/midikit
/**
 * @brief Retain a MIDIEvent instance.
 * Increment the reference counter of an event so that it won't be destroyed.
 * @public @memberof MIDIEvent
 * @param event The event.
 */
void MIDIEventRetain( struct MIDIEvent * event ) {
  MIDIPrecondReturn( event != NULL, EFAULT, (void)0 );
  event->refs++;
}
コード例 #19
0
ファイル: cfintegration.c プロジェクト: VishalChandla/midikit
/**
 * @brief Release a CFMIDIRunloop instance.
 * Decrement the reference counter of a runloop. If the reference count
 * reached zero, destroy the runloop.
 * @public @memberof CFMIDIRunloop
 * @param cf_runloop The core foundation runloop.
 */
void CFMIDIRunloopRelease( struct CFMIDIRunloop * cf_runloop ) {
  MIDIPrecondReturn( cf_runloop != NULL, EFAULT, (void)0 );
  if( ! --cf_runloop->refs ) {
    CFMIDIRunloopDestroy( cf_runloop );
  }
}
コード例 #20
0
ファイル: cfintegration.c プロジェクト: VishalChandla/midikit
/**
 * @brief Retain a CFMIDIRunloop instance.
 * Increment the reference counter of a runloop so that it won't be destroyed.
 * @public @memberof CFMIDIRunloop
 * @param cf_runloop The core foundation runloop.
 */
void CFMIDIRunloopRetain( struct CFMIDIRunloop * cf_runloop ) {
  MIDIPrecondReturn( cf_runloop != NULL, EFAULT, (void)0 );
  cf_runloop->refs++;
}
コード例 #21
0
ファイル: cfintegration.c プロジェクト: VishalChandla/midikit
void CFMIDIRunloopDestroy( struct CFMIDIRunloop * cf_runloop ) {
  MIDIPrecondReturn( cf_runloop, EFAULT, (void)0 );
  free( cf_runloop );
}
コード例 #22
0
ファイル: event.c プロジェクト: jitendarKumar/midikit
/**
 * @brief Release a MIDIEvent instance.
 * Decrement the reference counter of an event. If the reference count
 * reached zero, destroy the event.
 * @public @memberof MIDIEvent
 * @param event The event.
 */
void MIDIEventRelease( struct MIDIEvent * event ) {
  MIDIPrecondReturn( event != NULL, EFAULT, (void)0 );
  if( ! --event->refs ) {
    MIDIEventDestroy( event );
  }
}
コード例 #23
0
ファイル: driver.c プロジェクト: mgsx-dev/midikit
/**
 * @brief Release a MIDIDriver instance.
 * Decrement the reference counter of a driver. If the reference count
 * reached zero, destroy the driver.
 * @public @memberof MIDIDriver
 * @param driver The driver.
 */
void MIDIDriverRelease( struct MIDIDriver * driver ) {
    MIDIPrecondReturn( driver != NULL, EFAULT, (void)0 );
    if( ! --driver->refs ) {
        MIDIDriverDestroy( driver );
    }
}
コード例 #24
0
ファイル: driver.c プロジェクト: mgsx-dev/midikit
/**
 * @brief Create a MIDIDriver instance.
 * Allocate space and initialize a MIDIDriver instance.
 * @public @memberof MIDIDriver
 * @param name The name to identify the driver.
 * @param rate The sampling rate to use.
 * @return a pointer to the created driver structure on success.
 * @return a @c NULL pointer if the driver could not created.
 */
struct MIDIDriver * MIDIDriverCreate( char * name, MIDISamplingRate rate ) {
    struct MIDIDriver * driver = malloc( sizeof( struct MIDIDriver ) );
    MIDIPrecondReturn( driver != NULL, ENOMEM, NULL );
    MIDIDriverInit( driver, name, rate );
    return driver;
}