Module Frame


module Frame: sig .. end
Operations on frames, which are small portions of streams.


Frame definitions



type ('a, 'b, 'c) fields = {
   audio : 'a;
   video : 'b;
   midi : 'c;
}
A frame contains fields which hold audio, video and MIDI data.

type multiplicity =
| Variable
| Zero
| Succ of multiplicity
Multiplicity of a field, used in types to impose constraints on channels (empty, variable, at least k, etc.).
type content_kind = (multiplicity, multiplicity, multiplicity) fields 
Multiplicity of each field of a frame.
type content_type = (int, int, int) fields 
Content type of a frame: number of channels for audio, video and MIDI.
type content = (audio_t array, video_t array, midi_t array) fields 
Actual content of a frame.
type audio_t = Audio.Mono.buffer 
Audio data.
type video_t = Video.buffer 
Video data.
type midi_t = MIDI.buffer 
MIDI data.
val blit_content : content -> int -> content -> int -> int -> unit
blit_content c1 o1 c2 o2 l copies l data from c1 starting at offset o1 into c2 starting at offset o2. All numerical values are in ticks.
val copy : content -> content
Make a copy of the contents of a frame.
type metadata = (string, string) Hashtbl.t 
Metadata of a frame.

type t = {
   mutable breaks : int list; (*End of track markers. A break at the end of the buffer is not an end of track (if needed, the end-of-track needs to be put at the beginning of the next frame).*)
   mutable metadata : (int * metadata) list; (*Metadata along with the time they occur.*)
   mutable contents : (int * content) list; (*The actual content can represent several tracks in one content chunk, for efficiency, but may also be split in several chunks of different content_type. Each chunk has an end position, after which data should be considered as undefined. Chunks can be seen as layers: they all have the same (full) size, and data goes from one to the other. For example: [5,A;7,B;10,C] is A = 0 1 2 3 4 . . . . ., B = . . . . . 5 6 . . ., C = . . . . . . . 7 8 9 where "." is an undefined sample. This representation is slightly costly in memory (but several chunks shouldn't happen too often) but is very convenient to handle; notably, there's no need to pass offsets around.*)
}
A frame.

Content-independent frame operations



All units are in ticks (master clock).
val create : content_kind -> t
Create a frame of given content kind.
val position : t -> int
Position of the end of the last chunk of the frame (i.e. the offset of the end of the frame).
val is_partial : t -> bool
Is the frame partially filled, i.e. is its end position strictly before its size?
val clear : t -> unit
Make the frame empty.
val clear_from : t -> int -> unit
Same as clear from a given position.
val advance : t -> unit
Same as clear but leaves the last metadata at position -1.

Breaks


val breaks : t -> int list
List of breaks in a frame.
val set_breaks : t -> int list -> unit
Set all the breaks of a frame.
val add_break : t -> int -> unit
Add a break to a frame (which should be past its current end position).

Metadata


exception No_metadata
val set_metadata : t -> int -> metadata -> unit
Attach metadata at a given position in the frame.
val get_metadata : t -> int -> metadata option
Retrieve metadata at a given position.
val free_metadata : t -> int -> unit
Remove all metadata at given position.
val free_all_metadata : t -> unit
Remove all metadata.
val get_all_metadata : t -> (int * metadata) list
Retrieve all metadata.
val set_all_metadata : t -> (int * metadata) list -> unit
Set all metadata.
val get_past_metadata : t -> metadata option
Retreive "past metadata" which are stored at offset -1 (cf. advance).

Content operations


val content : t -> int -> int * content
Get the current content of a frame at a given position. Independently of breaks, this content may only be valid until some end position (that is returned together with the content) in case the frame content type is not fixed. Calling this function requires that the caller handles all possible content types allowed by the frame kind, and never affects the contents layout.
val content_of_type : ?force:content -> t -> int -> content_type -> content
Get the content for a given position and type in a frame. Calling this function may trigger a change of the contents layout, if the current content type at the given position is not the required one. Hence, the caller of this function should always assume the invalidation of all data after the given position.
val hide_contents : t -> unit -> unit
hide_contents frame removes all content layers from the frame, and returns a function that restores them in their current state. Hiding content layers avoids that they are used in any way, which is often needed in optimized content conversions.

type content_layer = {
   content : content; (*Actual content.*)
   start : int; (*Begining position.*)
   length : int; (*End position.*)
}
A content layer representation (see t.contents).
val get_content_layers : t -> content_layer list
Retrieve all content layers in a frame.
exception No_chunk
Raised by get_chunk when no chunk is available.
val get_chunk : t -> t -> unit
get_chunk dst src gets the (end of) next chunk from src (a chunk is a region of a frame between two breaks). Metadata relevant to the copied chunk is copied as well, and content layout is changed if needed.

Compatibilities between content values, types and kinds



Compatibilities between content kinds, types and values: sub a b is true when b is more permissive than a.
val mul_sub_mul : multiplicity -> multiplicity -> bool
val int_sub_mul : int -> multiplicity -> bool
val mul_eq_int : multiplicity -> int -> bool
val kind_sub_kind : content_kind -> content_kind -> bool
val type_has_kind : content_type -> content_kind -> bool
val content_has_type : content -> content_type -> bool
val type_of_content : content -> content_type
val type_of_kind : content_kind -> content_type
val mul_of_int : int -> multiplicity
val add_mul : multiplicity -> multiplicity -> multiplicity
val string_of_content_kind : content_kind -> string
val string_of_content_type : content_type -> string

Format settings



The channel numbers are only defaults, used when channel numbers cannot be inferred / are not forced from the context. I'm currently unsure how much they are really useful.
val allow_lazy_config_eval : unit -> unit
Prevent forcing the value of a lazy configuration value before the user gets a chance to override the default.
val audio_channels : int Lazy.t
Default number of audio channels.
val video_channels : int Lazy.t
Default number of video channels.
val midi_channels : int Lazy.t
Default number of MIDI channels.
val video_width : int Lazy.t
Width of video images.
val video_height : int Lazy.t
Height of video images.
val audio_rate : int Lazy.t
Rate of audio (in samples per second).
val video_rate : int Lazy.t
Video rate (in images per second).
val midi_rate : int Lazy.t
val master_rate : int Lazy.t
Ticks per second.
val size : int Lazy.t
The frame size (in master ticks) should allow for an integer number of samples of all types (audio, video). With audio@44100Hz and video@25Hz, ticks=samples and one video sample takes 1764 ticks: we need frames of size N*1764.
val duration : float Lazy.t
Duration of a frame in seconds.

Time and frequency conversions



Conversion between the internal unit (master ticks), seconds, and data units.
val audio_of_master : int -> int
Duration of given number of samples in ticks.
val video_of_master : int -> int
val midi_of_master : int -> int
val master_of_audio : int -> int
val master_of_video : int -> int
val master_of_midi : int -> int
val master_of_seconds : float -> int
val audio_of_seconds : float -> int
val video_of_seconds : float -> int
val seconds_of_master : int -> float
val seconds_of_audio : int -> float
val seconds_of_video : int -> float