/* File: MusicPlayer.h Contains: MusicPlayer application interfaces Copyright: (c) 2000-2008 by Apple, Inc., all rights reserved. Bugs?: For bug reports, consult the following page on the World Wide Web: http://developer.apple.com/bugreporter/ */ #ifndef __MusicPlayer #define __MusicPlayer #include #include #include #include #include #if defined(__cplusplus) extern "C" { #endif /*! @header MusicPlayer.h @abstract API for Music sequencing and playing services @discussion Basic idea behind the Sequencing Services APIs: A MusicSequence contains an arbitrary number of tracks (MusicTrack) each of which contains time-stamped (in units of beats) events in time-increasing order. There are various types of events, defined below, including the expected MIDI events, tempo, and extended events. A MusicTrack has properties which may be inspected and assigned, including support for looping, muting/soloing, and time-stamp interpretation. APIs exist for iterating through the events in a MusicTrack, and for performing editing operations on them. A MusicPlayer is used to play a sequence and provides control of playback rate and setting to a particular time. Each MusicSequence may have an associated AUGraph object, which represents a set of AudioUnits and the connections between them. Then, each MusicTrack of the MusicSequence may address its events to a specific AudioUnit within the AUGraph. In such a manner, it's possible to automate arbitrary parameters of AudioUnits, and schedule notes to be played to MusicDevices (AudioUnit software synthesizers) within an arbitrary audio processing network (AUGraph). A MusicSequence or its tracks can also address a MIDI endpoint directly. The objects defined in this header are: Music Sequence - container of music tracks Music Track - a time ordered list of events Music Track Iterator - an object to iterate over events in a track Music Player - an object used to play a sequence */ /*! @enum MusicEventType @abstract music event types, including both MIDI and "extended" protocol @constant kMusicEventType_NULL @constant kMusicEventType_ExtendedNote note with variable number of arguments (non-MIDI) @constant kMusicEventType_ExtendedTempo tempo change in BPM @constant kMusicEventType_User user defined data @constant kMusicEventType_Meta standard MIDI file meta event @constant kMusicEventType_MIDINoteMessage MIDI note-on with duration (for note-off) @constant kMusicEventType_MIDIChannelMessage MIDI channel messages (other than note-on/off) @constant kMusicEventType_MIDIRawData for MIDI system exclusive data @constant kMusicEventType_Parameter, general purpose AudioUnit parameter, added in 10.2 @constant kMusicEventType_AUPreset, the AU's user preset CFDictionaryRef (the ClassInfo property), added 10.3 */ enum { kMusicEventType_NULL = 0, kMusicEventType_ExtendedNote = 1, kMusicEventType_ExtendedTempo = 3, kMusicEventType_User = 4, kMusicEventType_Meta = 5, kMusicEventType_MIDINoteMessage = 6, kMusicEventType_MIDIChannelMessage = 7, kMusicEventType_MIDIRawData = 8, kMusicEventType_Parameter = 9, kMusicEventType_AUPreset = 10 }; typedef UInt32 MusicEventType; /*! @enum MusicSequenceLoadFlags @abstract Flags used to customise loading behaviour @constant kMusicSequenceLoadSMF_ChannelsToTracks If this flag is set the resultant Sequence will contain: a tempo track 1 track for each MIDI Channel that is found in the SMF 1 track for SysEx or MetaEvents - this will be the last track in the sequence after the LoadSMFWithFlags calls */ enum { kMusicSequenceLoadSMF_ChannelsToTracks = (1 << 0) }; typedef UInt32 MusicSequenceLoadFlags; /*! @enum MusicSequenceType @abstract A sequence type @discussion Different sequence types to describe the basic mode of operation of a sequence's time line You cannot change a music sequence's type to samples/seconds if there are tempo events The type will also define how the sequence is saved to a MIDI file: Beats - normal midi file Seconds - midi file with SMPTE time Samples - cannot be saved to a midi file @constant kMusicSequenceType_Beats The default/normal type of a sequence. Tempo track defines the number of beats per second and can have multiple tempo events @constant kMusicSequenceType_Seconds A music sequence with a single 60bpm tempo event @constant kMusicSequenceType_Samples A music sequence with a single tempo event that represents the audio sample rate */ enum { kMusicSequenceType_Beats = 'beat', kMusicSequenceType_Seconds = 'secs', kMusicSequenceType_Samples = 'samp' }; typedef UInt32 MusicSequenceType; /*! @enum MusicSequenceFileTypeID @abstract describes different types of files that can be parsed by a music sequence @constant kMusicSequenceFile_MIDIType read and write MIDI files @constant kMusicSequenceFile_iMelodyType read iMelody files */ enum { kMusicSequenceFile_MIDIType = 'midi', kMusicSequenceFile_iMelodyType = 'imel' }; typedef UInt32 MusicSequenceFileTypeID; /*! @enum MusicSequenceFileFlags @abstract controls the behaviour of the create file calls @constant kMusicSequenceFileFlags_EraseFile Erase an existing file when creating a new file */ enum { kMusicSequenceFileFlags_EraseFile = 1 }; typedef UInt32 MusicSequenceFileFlags; /*! @typedef MusicTimeStamp @abstract The type used to refer to time values in a music sequence */ typedef Float64 MusicTimeStamp; /*! @struct kMusicTimeStamp_EndOfTrack @abstract used to signal end of track @discussion Pass this value in to indicate a time passed the last event in the track. In this way, it's possible to perform edits on tracks which include all events starting at some particular time up to and including the last event */ #define kMusicTimeStamp_EndOfTrack DBL_MAX /*! @struct MIDINoteMessage @discussion The parameters to specify a MIDI note */ typedef struct MIDINoteMessage { UInt8 channel; UInt8 note; UInt8 velocity; UInt8 releaseVelocity; // was "reserved". 0 is the correct value when you don't know. Float32 duration; } MIDINoteMessage; /*! @struct MIDIChannelMessage @discussion The parameters to specify a MIDI channel message */ typedef struct MIDIChannelMessage { UInt8 status; // contains message and channel // message specific data UInt8 data1; UInt8 data2; UInt8 reserved; } MIDIChannelMessage; /*! @struct MIDIRawData @discussion Generally used to represent a MIDI SysEx message */ typedef struct MIDIRawData { UInt32 length; UInt8 data[1]; } MIDIRawData; /*! @struct MIDIMetaEvent @discussion The parameters to specify a MIDI meta event */ typedef struct MIDIMetaEvent { UInt8 metaEventType; UInt8 unused1; UInt8 unused2; UInt8 unused3; UInt32 dataLength; UInt8 data[1]; } MIDIMetaEvent; /*! @struct MusicEventUserData @discussion Provides a general struct for specifying a user defined event. @field length the size in bytes of the data @field data size bytes of user defined event data */ typedef struct MusicEventUserData { UInt32 length; UInt8 data[1]; } MusicEventUserData; /*! @struct ExtendedNoteOnEvent @discussion The parameters to specify an extended note on event */ typedef struct ExtendedNoteOnEvent { MusicDeviceInstrumentID instrumentID; MusicDeviceGroupID groupID; Float32 duration; MusicDeviceNoteParams extendedParams; } ExtendedNoteOnEvent; /*! @struct ParameterEvent @discussion The parameters to specify a parameter event to an audio unit. */ typedef struct ParameterEvent { AudioUnitParameterID parameterID; AudioUnitScope scope; AudioUnitElement element; AudioUnitParameterValue value; } ParameterEvent; /*! @struct ExtendedTempoEvent @discussion specifies the value for a tempo in beats per minute */ typedef struct ExtendedTempoEvent { Float64 bpm; } ExtendedTempoEvent; /*! @struct AUPresetEvent @discussion The parameters to specify a preset for an audio unit. */ typedef struct AUPresetEvent { AudioUnitScope scope; AudioUnitElement element; CFPropertyListRef preset; } AUPresetEvent; #if TARGET_OS_IPHONE // CAClock is currently not supported on iOS, so we include the definition of this structure here // (otherwise we include the CAClock header /*! @struct CABarBeatTime @abstract A display representation of a musical time in beats. @field bar A measure number. @field beat A beat number (1..n). @field subbeat The numerator of the fractional number of beats. @field subbeatDivisor The denominator of the fractional number of beats. @field reserved Must be 0. @discussion A clock's internal representation of musical time is in beats based on the beginning of the timeline. Normally, such times should be displayed to the user in terms of bars, beats, and subbeats (sometimes called "units" or "parts per quarter" [PPQ]). This data structure is such a display representation. By convention, bar 1 is the beginning of the sequence. Beat 1 is the first beat of the measure. In 4/4 time, beat will have a value from 1 to 4. Music applications often use beat divisions such as 480 and 960. */ struct CABarBeatTime { SInt32 bar; UInt16 beat; UInt16 subbeat; UInt16 subbeatDivisor; UInt16 reserved; }; typedef struct CABarBeatTime CABarBeatTime; #else #include #endif typedef struct OpaqueMusicPlayer *MusicPlayer; typedef struct OpaqueMusicSequence *MusicSequence; typedef struct OpaqueMusicTrack *MusicTrack; typedef struct OpaqueMusicEventIterator *MusicEventIterator; /*! @typedef MusicSequenceUserCallback @discussion See MusicSequenceSetUserCallback */ typedef void (*MusicSequenceUserCallback)( void *inClientData, MusicSequence inSequence, MusicTrack inTrack, MusicTimeStamp inEventTime, const MusicEventUserData *inEventData, MusicTimeStamp inStartSliceBeat, MusicTimeStamp inEndSliceBeat); /*! @enum MusicPlayerErrors @constant kAudioToolboxErr_InvalidSequenceType @constant kAudioToolboxErr_TrackIndexError @constant kAudioToolboxErr_TrackNotFound @constant kAudioToolboxErr_EndOfTrack @constant kAudioToolboxErr_StartOfTrack @constant kAudioToolboxErr_IllegalTrackDestination @constant kAudioToolboxErr_NoSequence @constant kAudioToolboxErr_InvalidEventType @constant kAudioToolboxErr_InvalidPlayerState @constant kAudioToolboxErr_CannotDoInCurrentContext */ enum { kAudioToolboxErr_InvalidSequenceType = -10846, kAudioToolboxErr_TrackIndexError = -10859, kAudioToolboxErr_TrackNotFound = -10858, kAudioToolboxErr_EndOfTrack = -10857, kAudioToolboxErr_StartOfTrack = -10856, kAudioToolboxErr_IllegalTrackDestination = -10855, kAudioToolboxErr_NoSequence = -10854, kAudioToolboxErr_InvalidEventType = -10853, kAudioToolboxErr_InvalidPlayerState = -10852, kAudioToolboxErr_CannotDoInCurrentContext = -10863 }; /*! @enum MusicTrackProperties @discussion Property values are always get and set by reference @constant kSequenceTrackProperty_LoopInfo read/write - MusicTrackLoopInfo The default looping behaviour is off (track plays once) Looping is set by specifying the length of the loop. It loops from (TrackLength - loop length) to Track Length If numLoops is set to zero, it will loop forever. To turn looping off, you set this with loop length equal to zero. @constant kSequenceTrackProperty_OffsetTime read/write - MusicTimeStamp offset's the track's start time to the specified beat. By default this value is zero. @constant kSequenceTrackProperty_MuteStatus read/write - Boolean mute state of a track. By default this value is false (not muted) @constant kSequenceTrackProperty_SoloStatus read/write - Boolean solo state of a track. By default this value is false (not soloed) @constant kSequenceTrackProperty_AutomatedParameters read/write - UInt32 Determines whether a track is used for automating parameters. If set to != 0 the track is used to automate parameter events to an AUNode. The track can only contain parameter events and these events are interpreted as points in the automation curve @constant kSequenceTrackProperty_TrackLength read/write - MusicTimeStamp The time of the last event in the track plus any additional time that is allowed for fading out of ending notes or round a loop point to musical bar, etc. If this is not set, the track length will always be adjusted to the end of the last active event in a track and is adjusted dynamically as events are added or removed. The property will return the max of the user set track length, or the calculated length @constant kSequenceTrackProperty_TimeResolution read only - SInt16 (only valid on the Tempo track) This retrieves the time resolution value for a sequence. This time resolution can be the resolution that was contained within the midi file used to construct a sequence. If you want to keep a time resolution when writing a new file, you can retrieve this value and then specify it when creating a new file from a sequence. It has no direct baring on the rendering or notion of time of the sequence itself (just its representation in file formats such as MIDI files). By default this is set to either: 480 if the sequence is created manually some_value based on what was in a MIDI file if the sequence was created from a MIDI file */ enum { kSequenceTrackProperty_LoopInfo = 0, kSequenceTrackProperty_OffsetTime = 1, kSequenceTrackProperty_MuteStatus = 2, kSequenceTrackProperty_SoloStatus = 3, // added in 10.2 kSequenceTrackProperty_AutomatedParameters = 4, // added in 10.3 kSequenceTrackProperty_TrackLength = 5, // added in 10.5 kSequenceTrackProperty_TimeResolution = 6 }; /*! @struct MusicTrackLoopInfo @discussion Used to control the looping behaviour of a track */ typedef struct MusicTrackLoopInfo { MusicTimeStamp loopDuration; SInt32 numberOfLoops; } MusicTrackLoopInfo; //===================================================================================================================== #pragma mark - //===================================================================================================================== #pragma mark Music Player /*! @functiongroup Music Player */ /*! @function NewMusicPlayer @abstract Create a new music player @discussion A music player is used to play a sequence back. This call is used to create a player When a sequence is to be played by a player, it can play to either an AUGraph, a MIDI Destination or a mixture/combination of both. @param outPlayer the newly created player */ extern OSStatus NewMusicPlayer( MusicPlayer *outPlayer) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function DisposeMusicPlayer @abstract Dispose a music player @param inPlayer the player to dispose */ extern OSStatus DisposeMusicPlayer( MusicPlayer inPlayer) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicPlayerSetSequence @abstract Set the sequence for the player to play @discussion A Sequence cannot be set on a player while it is playing. Setting a sequence will overide the currently set sequence. @param inPlayer the player @param inSequence the sequence for the player to play */ extern OSStatus MusicPlayerSetSequence( MusicPlayer inPlayer, MusicSequence inSequence) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicPlayerGetSequence @abstract Get the sequence attached to a player @discussion If the player does not have a sequence set, this will return the _NoSequence error @param inPlayer the player @param outSequence the sequence currently set on the player */ extern OSStatus MusicPlayerGetSequence( MusicPlayer inPlayer, MusicSequence *outSequence) __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_NA); /*! @function MusicPlayerSetTime @abstract Set the current time on the player @discussion The Get and Set Time calls take a specification of time as beats. This positions the player to the specified time based on the currently set sequence. No range checking on the time value is done. This can be set on a playing player (in which case playing will be resumed from the new time). @param inPlayer the player @param inTime the new time value */ extern OSStatus MusicPlayerSetTime( MusicPlayer inPlayer, MusicTimeStamp inTime) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicPlayerGetTime @abstract Get the current time of the player @discussion The Get and Set Time calls take a specification of time as beats. This retrieves the player's current time. If it is playing this time is the time of the player at the time the call was made. @param inPlayer the player @param outTime the current time value */ extern OSStatus MusicPlayerGetTime( MusicPlayer inPlayer, MusicTimeStamp *outTime) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicPlayerGetHostTimeForBeats @abstract Returns the host time that will be (or was) played at the specified beat. @discussion This call is only valid if the player is playing and will return an error if the player is not playing or if the starting position of the player (its "starting beat") was after the specified beat. For general translation of beats to time in a sequence, see the MusicSequence calls for beat<->seconds. The call uses the player's sequence's tempo map to translate a beat time from the starting time and beat of the player. @param inPlayer the player @param inBeats the specified beat-time value @param outHostTime the corresponding host time */ extern OSStatus MusicPlayerGetHostTimeForBeats( MusicPlayer inPlayer, MusicTimeStamp inBeats, UInt64 * outHostTime) __OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_NA); /*! @function MusicPlayerGetBeatsForHostTime @abstract Returns the beat that will be (or was) played at the specified host time. @discussion This call is only valid if the player is playing and will return an error if the player is not playing or if the starting time of the player was after the specified host time. For general translation of beats to time in a sequence, see the MusicSequence calls for beat<->seconds. The call uses the player's sequence's tempo map to retrieve a beat time from the starting and specified host time. @param inPlayer the player @param inHostTime the specified host time value @param outBeats the corresponding beat time */ extern OSStatus MusicPlayerGetBeatsForHostTime( MusicPlayer inPlayer, UInt64 inHostTime, MusicTimeStamp *outBeats) __OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_NA); /*! @function MusicPlayerPreroll @abstract Prepare the player for playing @discussion Allows the player to prepare its state so that starting is has a lower latency. If a player is started without being prerolled, the player will pre-roll itself and then start. @param inPlayer the player */ extern OSStatus MusicPlayerPreroll( MusicPlayer inPlayer) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicPlayerStart @abstract Start the player @discussion If the player has not been prerolled, it will pre-roll itself and then start. @param inPlayer the player */ extern OSStatus MusicPlayerStart( MusicPlayer inPlayer) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicPlayerStop @abstract Stop the player @param inPlayer the player */ extern OSStatus MusicPlayerStop( MusicPlayer inPlayer) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); // /*! @function MusicPlayerIsPlaying @abstract Returns the playing state of the player. "Is it playing?" @discussion This call returns a non-zero value in outIsPlaying if the player has been started and not stopped. It may have "played" past the events of the attached MusicSequence, but it is still considered to be playing (and its time value increasing) until it is explicitly stopped @param inPlayer the player @param outIsPlaying false if not, true (non-zero) if is playing */ extern OSStatus MusicPlayerIsPlaying( MusicPlayer inPlayer, Boolean * outIsPlaying) __OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_NA); /*! @function MusicPlayerSetPlayRateScalar @abstract Scale the playback rate of the player @param inPlayer the player @param inScaleRate a scalar that will be applied to the playback rate. If 2, playback is twice as fast, if 0.5 it is half as fast. As a scalar, the value must be greater than zero. */ extern OSStatus MusicPlayerSetPlayRateScalar( MusicPlayer inPlayer, Float64 inScaleRate) __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_NA); /*! @function MusicPlayerGetPlayRateScalar @abstract Get the playback rate scalar of the player @param inPlayer the player @param outScaleRate the current scalar being applied to the player. Default value is 1.0 */ extern OSStatus MusicPlayerGetPlayRateScalar( MusicPlayer inPlayer, Float64 * outScaleRate) __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_NA); //===================================================================================================================== #pragma mark - //===================================================================================================================== #pragma mark Music Sequence /*! @functiongroup Music Sequence */ /*! @function NewMusicSequence @abstract Create a new empty sequence @discussion A new music sequence will only have a tempo track (with a default tempo of 120 bpm), and the default type is beat based. When a sequence is to be played by a player, it can play to either an AUGraph, a MIDI Destination or a mixture/combination of both. See MusicSequenceSetAUGraph and MusicSequenceSetMIDIEndpoint for the generic destination assignments. Specific tracks can also be assigned nodes of a graph or a MIDI endpoint as targets for the events that they contain; see MusicTrackSetDestNode and MusicTrackSetDestMIDIEndpoint. @param outSequence the new sequence */ extern OSStatus NewMusicSequence( MusicSequence *outSequence) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function DisposeMusicSequence @abstract Dispose the sequence @discussion A sequence cannot be disposed while a MusicPlayer has it. @param inSequence the sequence */ extern OSStatus DisposeMusicSequence( MusicSequence inSequence) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicSequenceNewTrack @abstract Add a new (empty) track to the sequence @param inSequence the sequence @param outTrack the new track (it is always appended to any existing tracks) */ extern OSStatus MusicSequenceNewTrack( MusicSequence inSequence, MusicTrack *outTrack) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicSequenceDisposeTrack @abstract Remove and dispose a track from a sequence @param inSequence the sequence @param inTrack the track to remove and dispose */ extern OSStatus MusicSequenceDisposeTrack( MusicSequence inSequence, MusicTrack inTrack) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicSequenceGetTrackCount @abstract The number of tracks in a sequence. The track count and accessors exclude the tempo track (which is treated as a special case) @param inSequence the sequence @param outNumberOfTracks the number of tracks */ extern OSStatus MusicSequenceGetTrackCount( MusicSequence inSequence, UInt32 *outNumberOfTracks) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicSequenceGetIndTrack @abstract Get a track at the specified index @discussion Index is zero based. It will return kAudio_ParamError if index is not in the range: 0 < TrackCount The track count and accessors exclude the tempo track (which is treated as a special case) @param inSequence the sequence @param inTrackIndex the index @param outTrack the track at that index */ extern OSStatus MusicSequenceGetIndTrack( MusicSequence inSequence, UInt32 inTrackIndex, MusicTrack *outTrack) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicSequenceGetTrackIndex @abstract Get the index for a specific track @discussion Index is zero based. It will return an error if the track is not a member of the sequence. The track count and accessors exclude the tempo track (which is treated as a special case) @param inSequence the sequence @param inTrack the track @param outTrackIndex the index of the track */ extern OSStatus MusicSequenceGetTrackIndex( MusicSequence inSequence, MusicTrack inTrack, UInt32 *outTrackIndex) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicSequenceGetTempoTrack @abstract Get the tempo track of the sequence @discussion Each sequence has a single tempo track. All tempo events are placed into this tempo track (as well as other appropriate events (time sig for instance from a MIDI file). The tempo track, once retrieved can be edited and iterated upon as any other track. Non-tempo events in a tempo track are ignored. @param inSequence the sequence @param outTrack the tempo track of the sequence */ extern OSStatus MusicSequenceGetTempoTrack( MusicSequence inSequence, MusicTrack *outTrack) __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_NA); /*! @function MusicSequenceSetAUGraph @abstract Set the graph to be associated with the sequence @discussion A sequence can be associated with an AUGraph and this graph will be used to render the events as controlled by the sequence when it is played. By default, all of the tracks of a sequence will find the first AUNode that is an instance of Apple's DLSMusicDevice audio unit. This audio unit is a software synthesiser that is compatible with the GM and GS MIDI standards. Specific nodes of the graph can be targeted for different tracks as well (MusicTrackSetDestNode) @param inSequence the sequence @param inGraph the graph */ extern OSStatus MusicSequenceSetAUGraph( MusicSequence inSequence, AUGraph inGraph) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicSequenceGetAUGraph @abstract Gets the graph currently associated with a sequence @discussion By default if no graph is assigned to a sequence then the sequence will create a default graph. This default graph contains a DLSMusicDevice and a DynamicCompressor and all tracks will be targeted to the DLSMusicDevice. This call will thus either return the graph as set by the user, or this default graph. @param inSequence the sequence @param outGraph the graph */ extern OSStatus MusicSequenceGetAUGraph( MusicSequence inSequence, AUGraph *outGraph) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicSequenceSetMIDIEndpoint @abstract Makes the target of all of the tracks in the sequence a MIDI endpoint @discussion This is a convenience function, and is equivalent to iterating through all of the tracks in a sequence and targeting each track to the MIDI endpoint @param inSequence the sequence @param inEndpoint the MIDI endpoint */ extern OSStatus MusicSequenceSetMIDIEndpoint( MusicSequence inSequence, MIDIEndpointRef inEndpoint) __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_NA); /*! @function MusicSequenceSetSequenceType @abstract Set the sequence type (the default is beats) @discussion These two calls allow you to get and set a MusicSequence type; specifying kMusicSequenceType_Beats = 'beat', kMusicSequenceType_Seconds = 'secs', kMusicSequenceType_Samples = 'samp' The sequence type can be set to beats at any time. The sequence type can only be set to seconds or samples if there are NO tempo events already in the sequence. For beats - it can have as many tempo events as you want For Samples and Seconds - you should add a single tempo event after setting the type Samples - the tempo is the desired sample rate - e.g. 44100 and each "beat" in the sequence will be interpreted as a sample count at that sample rate (so beat == 44100 is a second) Seconds - the tempo should be set to 60 - a beat is a second. Beats is the default (and is the behaviour on pre 10.5 systems) A meta event of interest for Seconds based MIDI files is the SMPTE Offset meta event - stored in the tempo track. The sequence doesn't do anything with this event (except store/write it) @param inSequence the sequence @param inType the sequence type */ extern OSStatus MusicSequenceSetSequenceType( MusicSequence inSequence, MusicSequenceType inType) __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_NA); /*! @function MusicSequenceGetSequenceType @abstract Get the sequence type @discussion See SetSequence for a full description @param inSequence the sequence @param outType the type */ extern OSStatus MusicSequenceGetSequenceType( MusicSequence inSequence, MusicSequenceType * outType) __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_NA); /*! @function MusicSequenceFileLoad @abstract Load the data contained within the referenced file to the sequence @discussion This function will parse the file referenced by the URL and add the events to the sequence. @param inSequence the sequence @param inFileRef a file:// URL that references a file @param inFileTypeHint provides a hint to the sequence on the file type being imported @param inFlags flags that can control how the data is parsed in the file and laid out in the tracks that will be created and added to the sequence in this operation */ extern OSStatus MusicSequenceFileLoad (MusicSequence inSequence, CFURLRef inFileRef, MusicSequenceFileTypeID inFileTypeHint, // can be zero in many cases MusicSequenceLoadFlags inFlags) __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_NA); /*! @function MusicSequenceFileLoadData @abstract Load the data to the sequence @discussion This function will parse the data and add the events to the sequence. The data provided needs to be of a particular file type as specified by the fileTypeHint. @param inSequence the sequence @param inData the contents of a valid file loaded into a CFData object @param inFileTypeHint provides a hint to the sequence on the file type being imported @param inFlags flags that can control how the data is parsed in the file and laid out in the tracks that will be created and added to the sequence in this operation */ extern OSStatus MusicSequenceFileLoadData (MusicSequence inSequence, CFDataRef inData, MusicSequenceFileTypeID inFileTypeHint, // can be zero in many cases MusicSequenceLoadFlags inFlags) __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_NA); /*! @function MusicSequenceSetSMPTEResolution @abstract Helper function to establish the SMPTE based MIDI file resolution for the specified ticks @discussion SMPTE resolution helpers for dealing with the interpretation and creation of tick values for standard MIDI files (see MusicSequenceFileCreate) @param fps the frames per second @param ticks the ticks per quarter note @result the resolution that can be used when creating a MIDI file derived from the two parameters */ CF_INLINE SInt16 MusicSequenceSetSMPTEResolution (SignedByte fps, Byte ticks) { SInt16 res = fps < 0 ? fps : -fps; res = res << 8; res += ticks; return res; } /*! @function MusicSequenceGetSMPTEResolution @abstract Helper function to get the fps and ticks from their representation in a SMPTE based MIDI file @discussion SMPTE resolution helpers for dealing with the interpretation and creation of tick values for standard MIDI files (see MusicSequenceFileCreate) @param inRes the resolution from a MIDI file @param fps the frames per second @param ticks the ticks per quarter note */ CF_INLINE void MusicSequenceGetSMPTEResolution (SInt16 inRes, SignedByte * fps, Byte * ticks) { *fps = (SignedByte)((0xFF00 & inRes) >> 8); *ticks = 0x7F & inRes; } /*! @function MusicSequenceFileCreate @abstract Create a file from a sequence @discussion This function can be (and is most commonly) used to create a MIDI file from the events in a sequence. Only MIDI based events are used when creating the MIDI file. MIDI files are normally beat based, but can also have a SMPTE (or real-time rather than beat time) representation. inResolution is relationship between "tick" and quarter note for saving to Standard MIDI File - pass in zero to use default - this will be the value that is currently set on the tempo track - see the comments for the set track property's time resolution The different Sequence types determine the kinds of files that can be created: Beats When saving a MIDI file, it saves a beats (PPQ) based axis Seconds When saving a MIDI file, it will save it as a SMPTE resolution - so you should specify this resolution when creating the MIDI file. If zero is specified, 25 fps and 40 ticks/frame is used (a time scale of a millisecond) Samples You cannot save to a MIDI file with this sequence type The complete meaning of the 16-bit "division" field in a MIDI File's MThd chunk. If it is positive, then a tick represents 1/D quarter notes. If it negative: bits 14-8 are a signed 7-bit number representing the SMPTE format: -24, -25, -29 (drop), -30 bits 7-0 represents the number of ticks per SMPTE frame typical values: 4, 10, 80, 100 You can obtain millisecond resolution by specifying 25 frames/sec and 40 divisions/frame. 30 fps with 80 bits (ticks) per frame: 0xE250 ((char)0xE2 == -30) @param inSequence the sequence @param inFileRef the location of the file to create @param inFileType the type of file to create @param inFlags flags to control the file creation @param inResolution the resolution (depending on file type and sequence type) */ extern OSStatus MusicSequenceFileCreate (MusicSequence inSequence, CFURLRef inFileRef, MusicSequenceFileTypeID inFileType, MusicSequenceFileFlags inFlags, SInt16 inResolution) __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_NA); /*! @function MusicSequenceFileCreateData @abstract Create a data object from a sequence @discussion The same basic parameters apply to this as with the MusicSequenceFileCreate function. The difference being that that function will create a file on disk, whereas this one will create a CFData object that is a file in memory. The CFData object should be released by the caller. @param inSequence the sequence @param inFileType the type of file to create @param inFlags flags to control the file creation @param inResolution the resolution (depending on file type and sequence type) @param outData the resulting data object */ extern OSStatus MusicSequenceFileCreateData (MusicSequence inSequence, MusicSequenceFileTypeID inFileType, MusicSequenceFileFlags inFlags, SInt16 inResolution, CFDataRef * outData) __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_NA); /*! @function MusicSequenceReverse @abstract Reverse in time all events in a sequence, including the tempo events @param inSequence the sequence */ extern OSStatus MusicSequenceReverse( MusicSequence inSequence) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicSequenceGetSecondsForBeats @abstract Returns a seconds value that would correspond to the supplied beats @discussion Uses the sequence's tempo events @param inSequence the sequence @param inBeats the beats @param outSeconds the seconds (time from 0 beat) */ extern OSStatus MusicSequenceGetSecondsForBeats( MusicSequence inSequence, MusicTimeStamp inBeats, Float64 * outSeconds) __OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_NA); /*! @function MusicSequenceGetBeatsForSeconds @abstract Returns a beat value that would correspond to the supplied seconds from zero. @discussion Uses the sequence's tempo events @param inSequence the sequence @param inSeconds the seconds @param outBeats the corresponding beat */ extern OSStatus MusicSequenceGetBeatsForSeconds( MusicSequence inSequence, Float64 inSeconds, MusicTimeStamp * outBeats) __OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_NA); /*! @function MusicSequenceSetUserCallback @abstract Establish a user callback for a sequence @discussion This call is used to register (or remove if inCallback is NULL) a callback that the MusicSequence will call for ANY UserEvents that are added to any of the tracks of the sequence. If there is a callback registered, then UserEvents will be chased when MusicPlayerSetTime is called. In that case the inStartSliceBeat and inEndSliceBeat will both be the same value and will be the beat that the player is chasing too. In normal cases, where the sequence data is being scheduled for playback, the following will apply: inStartSliceBeat <= inEventTime < inEndSliceBeat The only exception to this is if the track that owns the MusicEvent is looping. In this case the start beat will still be less than the end beat (so your callback can still determine that it is playing, and what beats are currently being scheduled), however, the inEventTime will be the original time-stamped time of the user event. @param inSequence the sequence @param inCallback the callback @param inClientData client (user supplied) data provided back to the callback when it is called by the sequence */ extern OSStatus MusicSequenceSetUserCallback( MusicSequence inSequence, MusicSequenceUserCallback inCallback, void* inClientData) __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_NA); /*! @function MusicSequenceBeatsToBarBeatTime @abstract Convenience function to format a sequence's beat time to its bar-beat time @discussion see . The sequence's tempo track Time Sig events are used to to calculate the bar-beat representation. If there are no Time Sig events added to the sequence 4/4 is assumed. A Time Sig event is a MIDI Meta Event as specified for MIDI files. @param inSequence the sequence @param inBeats the beat which should be represented by the bar-beat @param inSubbeatDivisor The denominator of the fractional number of beats. @param outBarBeatTime the formatted bar/beat time */ extern OSStatus MusicSequenceBeatsToBarBeatTime(MusicSequence inSequence, MusicTimeStamp inBeats, UInt32 inSubbeatDivisor, CABarBeatTime * outBarBeatTime) __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_NA); /*! @function MusicSequenceBarBeatTimeToBeats @abstract Convenience function to format a bar-beat time to a sequence's beat time @discussion see . The sequence's tempo track Time Sig events are used to to calculate the bar-beat representation. If there are no Time Sig events added to the sequence 4/4 is assumed. A Time Sig event is a MIDI Meta Event as specified for MIDI files. @param inSequence the sequence @param inBarBeatTime the bar-beat time @param outBeats the sequence's beat time for that bar-beat time */ extern OSStatus MusicSequenceBarBeatTimeToBeats(MusicSequence inSequence, const CABarBeatTime * inBarBeatTime, MusicTimeStamp * outBeats) __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_NA); /*! @function MusicSequenceGetInfoDictionary @abstract Returns a dictionary containing meta-data derived from a sequence @discussion The dictionary can contain one or more of the kAFInfoDictionary_* keys specified in The caller should release the returned dictionary. If the call fails it will return NULL @param inSequence the sequence @result a CFDictionary or NULL if the call fails. */ extern CFDictionaryRef MusicSequenceGetInfoDictionary( MusicSequence inSequence) __OSX_AVAILABLE_STARTING(__MAC_10_5,__IPHONE_NA); //===================================================================================================================== #pragma mark - //===================================================================================================================== #pragma mark Music Track /*! @functiongroup Music Track */ /*! @function MusicTrackGetSequence @abstract Gets the sequence which the track is a member of @param inTrack the track @param outSequence the track's sequence */ extern OSStatus MusicTrackGetSequence( MusicTrack inTrack, MusicSequence *outSequence) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicTrackSetDestNode @abstract Sets the track's target to the specified AUNode @discussion The node must be a member of the graph that the track's sequence is using. When played, the track will send all of its events to that node. @param inTrack the track @param inNode the new node */ extern OSStatus MusicTrackSetDestNode( MusicTrack inTrack, AUNode inNode) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicTrackSetDestMIDIEndpoint @abstract Sets the track's target to the specified MIDI endpoint @discussion When played, the track will send all of its events to the specified MIDI Endpoint. @param inTrack the track @param inEndpoint the new MIDI endpoint */ extern OSStatus MusicTrackSetDestMIDIEndpoint( MusicTrack inTrack, MIDIEndpointRef inEndpoint) __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_NA); /*! @function MusicTrackGetDestNode @abstract Gets the track's target if it is an AUNode @discussion Returns kAudioToolboxErr_IllegalTrackDestination if the track's target is a MIDIEndpointRef and NOT an AUNode @param inTrack the track @param outNode the node target for the track */ extern OSStatus MusicTrackGetDestNode( MusicTrack inTrack, AUNode * outNode) __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_NA); /*! @function MusicTrackGetDestMIDIEndpoint @abstract Gets the track's target if it is a MIDI Endpoint @discussion Returns kAudioToolboxErr_IllegalTrackDestination if the track's target is an AUNode and NOT a MIDI Endpoint @param inTrack the track @param outEndpoint the MIDI Endpoint target for the track */ extern OSStatus MusicTrackGetDestMIDIEndpoint( MusicTrack inTrack, MIDIEndpointRef * outEndpoint) __OSX_AVAILABLE_STARTING(__MAC_10_1,__IPHONE_NA); /*! @function MusicTrackSetProperty @abstract Sets the specified property value @discussion Property values are always get and set by reference @param inTrack the track @param inPropertyID the property ID @param inData the new property value @param inLength the size of the property value being set */ extern OSStatus MusicTrackSetProperty( MusicTrack inTrack, UInt32 inPropertyID, void *inData, UInt32 inLength) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicTrackGetProperty @abstract Gets the specified property value @discussion If outData is NULL, then the size of the data will be passed back in ioLength This allows the client to allocate a buffer of the correct size (useful for variable length properties -- currently all properties have fixed size) Property values are always get and set by reference @param inTrack the track @param inPropertyID the property ID @param outData if not NULL, points to data of size ioLength @param ioLength on input the available size of outData, on output the size of the valid data that outData will then point too. */ extern OSStatus MusicTrackGetProperty( MusicTrack inTrack, UInt32 inPropertyID, void *outData, UInt32 *ioLength) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Editing operations on sequence tracks /*! @function MusicTrackMoveEvents @abstract Move events in a track @discussion Moves all of the events in the specified time range by the moveTime. MoveTime maybe negative to move events backwards (towards zero). All time ranges are [starttime < endtime] @param inTrack the track @param inStartTime the start time for the range of events @param inEndTime the end time up to which will form the range of the events to move @param inMoveTime amount of beats to move the selected events. */ extern OSStatus MusicTrackMoveEvents( MusicTrack inTrack, MusicTimeStamp inStartTime, MusicTimeStamp inEndTime, MusicTimeStamp inMoveTime) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicTrackClear @abstract Removes all events within the specified range @discussion All time ranges are [starttime < endtime] @param inTrack the track @param inStartTime the start time for the range of events @param inEndTime the end time up to which will form the range of the events to clear */ extern OSStatus MusicTrackClear( MusicTrack inTrack, MusicTimeStamp inStartTime, MusicTimeStamp inEndTime) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicTrackCut @abstract Removes all the events within the specified range @discussion Events that fall past the specified range will be moved back by the specified range time. All time ranges are [starttime < endtime] @param inTrack the track @param inStartTime the start time for the range of events @param inEndTime the end time up to which will form the range of the events to cut out */ extern OSStatus MusicTrackCut( MusicTrack inTrack, MusicTimeStamp inStartTime, MusicTimeStamp inEndTime) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicTrackCopyInsert @abstract Copies events from one track and inserts them into another @discussion Copies all of the events with the specified time range of the source track. It then inserts those events into the destination track. All events at and after inDestInsertTime in inDestTrack are moved forward by the range's duration All time ranges are [starttime < endtime] @param inSourceTrack the source track @param inSourceStartTime the start time for the range of events @param inSourceEndTime the end time up to which will form the range of the events to copy from the source track @param inDestTrack the destination track to copy too @param inDestInsertTime the time at which the copied events will be inserted. */ extern OSStatus MusicTrackCopyInsert( MusicTrack inSourceTrack, MusicTimeStamp inSourceStartTime, MusicTimeStamp inSourceEndTime, MusicTrack inDestTrack, MusicTimeStamp inDestInsertTime) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicTrackMerge @abstract Copies events from one track and merges them into another @discussion Copies all of the events with the specified time range of the source track. It then merges those events into the destination track starting at inDestInsertTime. All time ranges are [starttime < endtime] @param inSourceTrack the source track @param inSourceStartTime the start time for the range of events @param inSourceEndTime the end time up to which will form the range of the events to copy from the source track @param inDestTrack the destination track to copy too @param inDestInsertTime the time at which the copied events will be merged. */ extern OSStatus MusicTrackMerge( MusicTrack inSourceTrack, MusicTimeStamp inSourceStartTime, MusicTimeStamp inSourceEndTime, MusicTrack inDestTrack, MusicTimeStamp inDestInsertTime) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); //===================================================================================================================== #pragma mark - //===================================================================================================================== #pragma mark Music Events /*! @functiongroup Music Events */ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // adding time-stamped events to the track /*! @function MusicTrackNewMIDINoteEvent @abstract Adds a MIDINoteMessage event to a track @discussion The event is added at the specified time stamp. The time stamp should not be less than zero. @param inTrack the track @param inTimeStamp the time stamp @param inMessage the event */ extern OSStatus MusicTrackNewMIDINoteEvent( MusicTrack inTrack, MusicTimeStamp inTimeStamp, const MIDINoteMessage * inMessage) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicTrackNewMIDIChannelEvent @abstract Adds a MIDIChannelMessage event to a track @discussion The event is added at the specified time stamp. The time stamp should not be less than zero. @param inTrack the track @param inTimeStamp the time stamp @param inMessage the event */ extern OSStatus MusicTrackNewMIDIChannelEvent( MusicTrack inTrack, MusicTimeStamp inTimeStamp, const MIDIChannelMessage * inMessage) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicTrackNewMIDIRawDataEvent @abstract Adds a MIDIRawData event to a track @discussion The event is added at the specified time stamp. The time stamp should not be less than zero. @param inTrack the track @param inTimeStamp the time stamp @param inRawData the event */ extern OSStatus MusicTrackNewMIDIRawDataEvent( MusicTrack inTrack, MusicTimeStamp inTimeStamp, const MIDIRawData * inRawData) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicTrackNewExtendedNoteEvent @abstract Adds a ExtendedNoteOnEvent to a track @discussion The event is added at the specified time stamp. The time stamp should not be less than zero. @param inTrack the track @param inTimeStamp the time stamp @param inInfo the event */ extern OSStatus MusicTrackNewExtendedNoteEvent( MusicTrack inTrack, MusicTimeStamp inTimeStamp, const ExtendedNoteOnEvent *inInfo) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicTrackNewParameterEvent @abstract Adds a ParameterEvent to a track @discussion The event is added at the specified time stamp. The time stamp should not be less than zero. @param inTrack the track @param inTimeStamp the time stamp @param inInfo the event */ extern OSStatus MusicTrackNewParameterEvent( MusicTrack inTrack, MusicTimeStamp inTimeStamp, const ParameterEvent * inInfo) __OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_NA); /*! @function MusicTrackNewExtendedTempoEvent @abstract Adds a tempo event to a track @discussion The event is added at the specified time stamp. The time stamp should not be less than zero. @param inTrack the track @param inTimeStamp the time stamp @param inBPM the event */ extern OSStatus MusicTrackNewExtendedTempoEvent( MusicTrack inTrack, MusicTimeStamp inTimeStamp, Float64 inBPM) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicTrackNewMetaEvent @abstract Adds a MIDIMetaEvent to a track @discussion The event is added at the specified time stamp. The time stamp should not be less than zero. @param inTrack the track @param inTimeStamp the time stamp @param inMetaEvent the event */ extern OSStatus MusicTrackNewMetaEvent( MusicTrack inTrack, MusicTimeStamp inTimeStamp, const MIDIMetaEvent * inMetaEvent) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicEventUserData @abstract Adds a MusicEventUserData event to a track @discussion The event is added at the specified time stamp. The time stamp should not be less than zero. @param inTrack the track @param inTimeStamp the time stamp @param inUserData the event */ extern OSStatus MusicTrackNewUserEvent( MusicTrack inTrack, MusicTimeStamp inTimeStamp, const MusicEventUserData * inUserData) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicTrackNewAUPresetEvent @abstract Adds a AUPresetEvent to a track @discussion The event is added at the specified time stamp. The time stamp should not be less than zero. @param inTrack the track @param inTimeStamp the time stamp @param inPresetEvent the event */ extern OSStatus MusicTrackNewAUPresetEvent( MusicTrack inTrack, MusicTimeStamp inTimeStamp, const AUPresetEvent * inPresetEvent) __OSX_AVAILABLE_STARTING(__MAC_10_3,__IPHONE_NA); //===================================================================================================================== #pragma mark - //===================================================================================================================== #pragma mark Music Event Iterator /*! @functiongroup Music Event Iterator */ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // actual event representation and manipulation within a track.... // // Here we need to be very careful to be able to deal with both SMF type of MIDI events, and // also be upwardly compatible with an extended MPEG4-SA like paradigm! // // The solution is to hide the internal event representation from the client // and allow access to the events through accessor functions. The user, in this way, can // examine and create standard events, or any user-defined event. /*! @function NewMusicEventIterator @abstract Creates an iterator to iterator over a track's events @discussion The iterator should be considered invalid if a track is edited. In that case you should create a new iterator and seek it to the desired position. @param inTrack the track upon which to iterate @param outIterator the new iterator */ extern OSStatus NewMusicEventIterator( MusicTrack inTrack, MusicEventIterator *outIterator) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function DisposeMusicEventIterator @abstract Dispose an iterator @param inIterator the iterator */ extern OSStatus DisposeMusicEventIterator( MusicEventIterator inIterator) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicEventIteratorSeek @abstract Move the iterator to an event at the specified time @discussion If there is no event at the specified time, the iterator will point to the first event after that time. By specifying kMusicTimeStamp_EndOfTrack you will position the iterator to the end of track (which is pointing to the space just AFTER the last event). You can use MusicEventIteratorPreviousEvent to backup to the last event. By specifying 0, you will position the iterator at the first event @param inIterator the iterator @param inTimeStamp the time stamp to seek too */ extern OSStatus MusicEventIteratorSeek( MusicEventIterator inIterator, MusicTimeStamp inTimeStamp) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicEventIteratorNextEvent @abstract Move the iterator to the next event @discussion If the iterator was at the last event, then it will move past the last event and will no longer point to an event. You can use check MusicEventIteratorHasCurrentEvent to see if there is an event at the iterator's current position. See also MusicEventIteratorHasNextEvent. Typically this call is used to move the iterator forwards through the track's events. @param inIterator the iterator */ extern OSStatus MusicEventIteratorNextEvent( MusicEventIterator inIterator) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicEventIteratorPreviousEvent @abstract Move the iterator to the previous event @discussion If the iterator was at the first event, then it will leave the iterator unchanged and return an error. See also MusicEventIteratorHasPreviousEvent Typically this call is used to move the iterator backwards through the track's events. @param inIterator the iterator */ extern OSStatus MusicEventIteratorPreviousEvent( MusicEventIterator inIterator) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicEventIteratorGetEventInfo @abstract Retrieves the event data at the iterator. @discussion Retrieves the event and other information from the iterator's current position. If you do not want specific information (eg, the time stamp) pass in NULL for that parameter. @param inIterator the iterator @param outTimeStamp the time stamp of the event @param outEventType one of kMusicEventType_XXX that indicates what kind of event type the iterator is currently pointing too @param outEventData a reference to the event data. The type of data is described by the eventType. This data is read only and should not be edited in place. @param outEventDataSize the size of the data referenced by outEventData */ extern OSStatus MusicEventIteratorGetEventInfo( MusicEventIterator inIterator, MusicTimeStamp * outTimeStamp, MusicEventType * outEventType, const void ** outEventData, UInt32 * outEventDataSize) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicEventIteratorSetEventInfo @abstract Changes the type or value of an event @discussion Allows you to change either the event type, or the values of the event data, that the iterator is currently pointing too. You cannot change the event's time (to do that you should use MusicEventIteratorSetEventTime). @param inIterator the iterator @param inEventType the new (or existing) type of the event you are changing @param inEventData the new event data. The size and type of this event data must match the inEventType */ extern OSStatus MusicEventIteratorSetEventInfo( MusicEventIterator inIterator, MusicEventType inEventType, const void * inEventData) __OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_NA); /*! @function MusicEventIteratorSetEventTime @abstract Set a new time for an event @discussion The iterator will still be pointing to the same event, but as the event will have moved, it may or may not have a next or previous event now (depending of course on the time you moved it too). @param inIterator the iterator @param inTimeStamp the new time stamp of the event */ extern OSStatus MusicEventIteratorSetEventTime( MusicEventIterator inIterator, MusicTimeStamp inTimeStamp) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicEventIteratorDeleteEvent @abstract Deletes the event pointed to by the iterator @discussion The iterator will reference the next event after the event has been deleted. @param inIterator the iterator */ extern OSStatus MusicEventIteratorDeleteEvent( MusicEventIterator inIterator) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicEventIteratorHasPreviousEvent @abstract Does the track have an event previous to the event the iterator is pointing to? @discussion To use the iterator going backwards through a track: iter = New Iterator (points at first event) MusicEventIteratorSeek (iter, kMusicTimeStamp_EndOfTrack) // will point it past the last event bool hasPreviousEvent; MusicEventIteratorHasPreviousEvent (iter, &hasPreviousEvent) while (hasPreviousEvent) { MusicEventIteratorPreviousEvent (iter) // do work... MusicEventIteratorGetEventInfo (iter, ... MusicEventIteratorHasPreviousEvent (iter, &hasPreviousEvent); } @param inIterator the iterator @param outHasPrevEvent true if there is a previous event, false if not */ extern OSStatus MusicEventIteratorHasPreviousEvent( MusicEventIterator inIterator, Boolean * outHasPrevEvent) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicEventIteratorHasNextEvent @abstract Does the track have an event past the event the iterator is pointing too? @discussion To use the iterator going forwards through a track: iter = New Iterator (points at first event) bool hasCurrentEvent; MusicEventIteratorHasCurrentEvent(iter, &hasCurrentEvent); while (hasCurrentEvent) { // do work... MusicEventIteratorGetEventInfo (iter, ... MusicEventIteratorNextEvent (iter) MusicEventIteratorHasCurrentEvent(iter, &hasCurrentEvent); } @param inIterator the iterator @param outHasNextEvent true if there is a next event, false if not */ extern OSStatus MusicEventIteratorHasNextEvent( MusicEventIterator inIterator, Boolean * outHasNextEvent) __OSX_AVAILABLE_STARTING(__MAC_10_0,__IPHONE_NA); /*! @function MusicEventIteratorHasCurrentEvent @abstract Is there an event at the iterator's current position? @param inIterator the iterator @param outHasCurEvent true if there is an event, false if not */ extern OSStatus MusicEventIteratorHasCurrentEvent( MusicEventIterator inIterator, Boolean * outHasCurEvent) __OSX_AVAILABLE_STARTING(__MAC_10_2,__IPHONE_NA); //===================================================================================================================== #pragma mark - #pragma mark -- Deprecated // standard MIDI files (SMF, and RMF) // MusicSequenceLoadSMF() also intelligently parses an RMID file to extract SMF part #if !__LP64__ extern OSStatus MusicSequenceLoadSMFData( MusicSequence inSequence, CFDataRef inData) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_5, __IPHONE_NA, __IPHONE_NA); #endif // !__LP64__ // passing a value of zero for the flags makes this call equivalent to MusicSequenceLoadSMFData // a kAudio_ParamError is returned if the sequence has ANY data in it and the flags value is != 0 // This will create a sequence with the first tracks containing MIDI Channel data // IF the MIDI file had Meta events or SysEx data, then the last track in the sequence // will contain that data. extern OSStatus MusicSequenceLoadSMFWithFlags( MusicSequence inSequence, const struct FSRef * inFileRef, MusicSequenceLoadFlags inFlags) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3,__MAC_10_5, __IPHONE_NA, __IPHONE_NA); extern OSStatus MusicSequenceLoadSMFDataWithFlags( MusicSequence inSequence, CFDataRef inData, MusicSequenceLoadFlags inFlags) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_3,__MAC_10_5, __IPHONE_NA, __IPHONE_NA); // inFlags must be zero extern OSStatus MusicSequenceSaveMIDIFile( MusicSequence inSequence, const struct FSRef *inParentDirectory, CFStringRef inFileName, UInt16 inResolution, UInt32 inFlags) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4,__MAC_10_5, __IPHONE_NA, __IPHONE_NA); extern OSStatus MusicSequenceSaveSMFData( MusicSequence inSequence, CFDataRef *outData, UInt16 inResolution) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2,__MAC_10_5, __IPHONE_NA, __IPHONE_NA); extern OSStatus NewMusicTrackFrom( MusicTrack inSourceTrack, MusicTimeStamp inSourceStartTime, MusicTimeStamp inSourceEndTime, MusicTrack *outNewTrack) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0,__MAC_10_6, __IPHONE_NA, __IPHONE_NA); #if !TARGET_OS_IPHONE enum { kMusicEventType_ExtendedControl = 2 }; typedef struct ExtendedControlEvent { MusicDeviceGroupID groupID; AudioUnitParameterID controlID; AudioUnitParameterValue value; } ExtendedControlEvent; extern OSStatus MusicTrackNewExtendedControlEvent( MusicTrack inTrack, MusicTimeStamp inTimeStamp, const ExtendedControlEvent *inInfo) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_0,__MAC_10_7, __IPHONE_NA, __IPHONE_NA); #endif #if defined(__cplusplus) } #endif #endif // __MusicPlayer