Chris@634: #ifndef IMAFENCODER_H Chris@634: #define IMAFENCODER_H Chris@634: Chris@634: //***********************************************************// Chris@634: // Interactive Music Audio Format (IMAF) ENCODER // Chris@634: // Version 2.0 // Chris@634: // // Chris@634: // Eugenio Oñate Hospital // Chris@634: // Costantino Taglialatela & Jesus Corral Garcìa // Chris@634: // // Chris@634: // Copyright (c) 2013 Centre for Digital Music (C4DM) // Chris@634: // Queen Mary University of London. All rights reserved. // Chris@634: //***********************************************************// Chris@634: // IM_AF Encoder.h // Chris@634: //***********************************************************// Chris@634: Chris@634: Chris@634: /* for FILE typedef, */ Chris@634: #include Chris@634: Chris@634: #define maxtracks 8 //change this value to support more than 8 audio tracks. This value was 6 before I changed it Chris@634: #define maxgroups 2 Chris@634: #define maxpreset 10 Chris@634: #define maxrules 10 Chris@634: #define maxfilters 3 //Max number of Filters for an EQ preset Chris@634: #define maxdynamic 2 //Max number of Dynamic Volume changes Chris@634: #define num_ch 2 //Number of channel outputs (STEREO) Chris@634: Chris@634: typedef long long u64; Chris@634: typedef unsigned int u32; Chris@634: typedef unsigned short u16; Chris@634: typedef unsigned char u8; Chris@634: Chris@634: //typedef struct nametrack { // Stores the different titles of the tracks Chris@634: // char title[20]; Chris@634: //}nametrack[maxtracks]; Chris@634: Chris@634: typedef struct FileTypeBox Chris@634: { Chris@634: u32 size; Chris@634: u32 type; // ftyp Chris@634: u32 major_brand; // brand identifier Chris@634: u32 minor_version; // informative integer for the mirror version Chris@634: u32 compatible_brands[2]; //list of brands Chris@634: }FileTypeBox; Chris@634: Chris@634: typedef struct MovieBox //extends Box('moov') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; // moov Chris@634: Chris@634: struct MovieHeaderBox Chris@634: { Chris@634: u32 size; Chris@634: u32 type; // mvhd Chris@634: u32 version; // version + flag Chris@634: u32 creation_time; Chris@634: u32 modification_time; Chris@634: u32 timescale; // specifies the time-scale Chris@634: u32 duration; Chris@634: u32 rate; // typically 1.0 Chris@634: u16 volume; // typically full volume Chris@634: u16 reserved; // =0 Chris@634: u32 reserved2[2]; //=0 Chris@634: u32 matrix[9]; // information matrix for video (u,v,w) Chris@634: u32 pre_defined[6]; // =0 Chris@634: u32 next_track_ID; //non zero value for the next track ID Chris@634: }MovieHeaderBox; Chris@634: Chris@634: struct TrackBox Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: struct TrackHeaderBox Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; // version + flag Chris@634: u32 creation_time; Chris@634: u32 modification_time; Chris@634: u32 track_ID; Chris@634: u32 reserved; // =0 Chris@634: u32 duration; Chris@634: u32 reserved2[2]; // =0 Chris@634: u16 layer; // =0 // for video Chris@634: u16 alternate_group; // =0 Chris@634: u16 volume; // full volume is 1 = 0x0100 Chris@634: u16 reserved3;// =0 Chris@634: u32 matrix[9]; // for video Chris@634: u32 width; // video Chris@634: u32 height; // video Chris@634: }TrackHeaderBox; Chris@634: Chris@634: struct MediaBox // extends Box('mdia') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: struct MediaHeaderBox // extends FullBox('mdhd', version,0) Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; // version + flag Chris@634: u32 creation_time; Chris@634: u32 modification_time; Chris@634: u32 timescale; Chris@634: u32 duration; Chris@634: u16 language; // [pad,5x3] = 16 bits and pad = 0 Chris@634: u16 pre_defined; // =0 Chris@634: }MediaHeaderBox; Chris@634: struct HandlerBox // extends FullBox('hdlr') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; // version = 0 + flag Chris@634: u32 pre_defined; // =0 Chris@634: u32 handler_type; // = 'soun' for audio track, text or hint Chris@634: u32 reserved[3]; // =0 Chris@634: unsigned char data[5]; // Does not work! only 4 bytes Chris@634: Chris@634: }HandlerBox; Chris@634: struct MediaInformationBox //extends Box('minf') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: // smhd in sound track only!! Chris@634: struct SoundMediaHeaderBox //extends FullBox('smhd') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; Chris@634: u16 balance; // =0 place mono tracks in stereo. 0 is center Chris@634: u16 reserved; // =0 Chris@634: }SoundMediaHeaderBox; Chris@634: struct NullMediaHeaderBox //extends FullBox('nmhd') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 flags; Chris@634: }NullMediaHeaderBox; Chris@634: struct DataInformationBox //extends Box('dinf') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: struct DataReferenceBox Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 flags; Chris@634: u32 entry_count; // counts the actual entries. Chris@634: struct DataEntryUrlBox //extends FullBox('url', version=0, flags) Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 flags; Chris@634: }DataEntryUrlBox; Chris@634: }DataReferenceBox; Chris@634: }DataInformationBox; Chris@634: struct SampleTableBox // extends Box('stbl') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: struct TimeToSampleBox{ Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; Chris@634: u32 entry_count; Chris@634: u32 sample_count[3000]; Chris@634: u32 sample_delta[3000]; Chris@634: }TimeToSampleBox; Chris@634: struct SampleDescriptionBox // stsd Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; Chris@634: u32 entry_count; // = 1 number of entries Chris@634: // unsigned char esds[88]; Chris@634: struct TextSampleEntry{ Chris@634: u32 size; Chris@634: u32 type; //tx3g Chris@634: u32 a; Chris@634: u32 b; Chris@634: u32 displayFlags; Chris@634: u8 horizontaljustification; Chris@634: u8 verticaljustification; Chris@634: u8 backgroundcolorrgba[4]; Chris@634: u16 top; Chris@634: u16 left; Chris@634: u16 bottom; Chris@634: u16 right; Chris@634: //StyleRecord Chris@634: u16 startChar; Chris@634: u16 endChar; Chris@634: u16 fontID; Chris@634: u8 facestyleflags; Chris@634: u8 fontsize; Chris@634: u8 textcolorrgba[4]; Chris@634: struct FontTableBoX{ Chris@634: u32 size; Chris@634: u32 type; Chris@634: u16 entrycount; Chris@634: u16 fontID; Chris@634: u8 fontnamelenght; Chris@634: u8 font[5]; //Serif Chris@634: }FontTableBox; Chris@634: }TextSampleEntry; Chris@634: struct AudioSampleEntry{ Chris@634: u32 size; Chris@634: u32 type; //mp4a Chris@634: char reserved[6]; Chris@634: u16 data_reference_index; // = 1 Chris@634: u32 reserved2[2]; Chris@634: u16 channelcount; // = 2 Chris@634: u16 samplesize; // = 16 Chris@634: u32 reserved3; Chris@634: u32 samplerate; // 44100 << 16 Chris@634: // unsigned char esds[81]; Chris@634: struct ESbox{ Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; Chris@634: struct ES_Descriptor{ Chris@634: unsigned char tag; Chris@634: unsigned char length; Chris@634: u16 ES_ID; Chris@634: unsigned char mix; Chris@634: struct DecoderConfigDescriptor{ Chris@634: unsigned char tag; Chris@634: unsigned char length; Chris@634: unsigned char objectProfileInd; Chris@634: u32 mix; Chris@634: u32 maxBitRate; Chris@634: u32 avgBitrate; Chris@634: /* struct DecoderSpecificInfo{ Chris@634: unsigned char tag; Chris@634: unsigned length; Chris@634: // unsigned char decSpecificInfosize; Chris@634: unsigned char decSpecificInfoData[2]; Chris@634: }DecoderSpecificInfo; Chris@634: */ }DecoderConfigDescriptor; Chris@634: struct SLConfigDescriptor{ Chris@634: unsigned char tag; Chris@634: unsigned char length; Chris@634: unsigned char predifined; Chris@634: }SLConfigDescriptor; Chris@634: }ES_Descriptor; Chris@634: }ESbox; Chris@634: }AudioSampleEntry; Chris@634: }SampleDescriptionBox; Chris@634: struct SampleSizeBox{ Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; Chris@634: u32 sample_size; // =0 Chris@634: u32 sample_count; Chris@634: u32 entry_size[9000]; Chris@634: }SampleSizeBox; Chris@634: struct SampleToChunk{ Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; Chris@634: u32 entry_count; Chris@634: u32 first_chunk; Chris@634: u32 samples_per_chunk; Chris@634: u32 sample_description_index; Chris@634: }SampleToChunk; Chris@634: struct ChunkOffsetBox{ Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; Chris@634: u32 entry_count; Chris@634: u32 chunk_offset[maxtracks]; Chris@634: }ChunkOffsetBox; Chris@634: }SampleTableBox; Chris@634: }MediaInformationBox; Chris@634: }MediaBox; Chris@634: }TrackBox[maxtracks]; // max 10 tracks Chris@634: Chris@634: struct PresetContainerBox // extends Box('prco') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: unsigned char num_preset; Chris@634: unsigned char default_preset_ID; Chris@634: struct PresetBox //extends FullBox('prst',version=0,flags) Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 flags; Chris@634: unsigned char preset_ID; Chris@634: unsigned char num_preset_elements; Chris@634: struct presElemId{ Chris@634: u32 preset_element_ID; Chris@634: }presElemId[maxtracks]; Chris@634: unsigned char preset_type; Chris@634: unsigned char preset_global_volume; Chris@634: Chris@634: // if (preset_type == 0) || (preset_type == 8) - Static track volume preset Chris@634: struct StaticTrackVolume{ Chris@634: struct presVolumElem{ Chris@634: u8 preset_volume_element; Chris@634: struct EQ{ // if preset_type == 8 (with EQ) Chris@634: u8 num_eq_filters; Chris@634: struct Filter{ Chris@634: u8 filter_type; Chris@634: u16 filter_reference_frequency; Chris@634: u8 filter_gain; Chris@634: u8 filter_bandwidth; Chris@634: }Filter[maxfilters]; Chris@634: }EQ; Chris@634: }presVolumElem[maxtracks]; Chris@634: }StaticTrackVolume; Chris@634: Chris@634: // if (preset_type == 1) || (preset_type == 9) - Static object volume preset Chris@634: struct StaticObjectVolume{ Chris@634: struct InputCH{ Chris@634: u8 num_input_channel; Chris@634: }InputCH[maxtracks]; Chris@634: u8 output_channel_type; Chris@634: struct presElVol_1{ Chris@634: struct Input{ Chris@634: struct Output{ Chris@634: u8 preset_volume_element; Chris@634: }Output[num_ch]; Chris@634: struct EQ_1{ // if preset_type == 9 (with EQ) Chris@634: u8 num_eq_filters; Chris@634: struct Filter_1{ Chris@634: u8 filter_type; Chris@634: u16 filter_reference_frequency; Chris@634: u8 filter_gain; Chris@634: u8 filter_bandwidth; Chris@634: }Filter[maxfilters]; Chris@634: }EQ; Chris@634: }Input[num_ch]; Chris@634: }presElVol[maxtracks]; Chris@634: }StaticObjectVolume; Chris@634: Chris@634: // if (preset_type == 2) || (preset_type == 10) - Dynamic track volume preset Chris@634: struct DynamicTrackVolume{ Chris@634: u16 num_updates; Chris@634: struct DynamicChange{ Chris@634: u16 updated_sample_number; Chris@634: struct presVolumElem_2{ Chris@634: u8 preset_volume_element; Chris@634: struct EQ_2{ // if preset_type == 10 (with EQ) Chris@634: u8 num_eq_filters; Chris@634: struct Filter_2{ Chris@634: u8 filter_type; Chris@634: u16 filter_reference_frequency; Chris@634: u8 filter_gain; Chris@634: u8 filter_bandwidth; Chris@634: }Filter[maxfilters]; Chris@634: }EQ; Chris@634: }presVolumElem[maxtracks]; Chris@634: }DynamicChange[maxdynamic]; Chris@634: }DynamicTrackVolume; Chris@634: Chris@634: // if (preset_type == 3) || (preset_type == 11) - Dynamic object volume preset Chris@634: struct DynamicObjectVolume{ Chris@634: u16 num_updates; Chris@634: struct InputCH_3{ Chris@634: u8 num_input_channel; Chris@634: }InputCH[maxtracks]; Chris@634: u8 output_channel_type; Chris@634: struct DynamicChange_3{ Chris@634: u16 updated_sample_number; Chris@634: struct presElVol{ Chris@634: struct Input_3{ Chris@634: struct Output_3{ Chris@634: u8 preset_volume_element; Chris@634: }Output[num_ch]; Chris@634: struct EQ_3{ // if preset_type == 11 (with EQ) Chris@634: u8 num_eq_filters; Chris@634: struct Filter_3{ Chris@634: u8 filter_type; Chris@634: u16 filter_reference_frequency; Chris@634: u8 filter_gain; Chris@634: u8 filter_bandwidth; Chris@634: }Filter[maxfilters]; Chris@634: }EQ; Chris@634: }Input[num_ch]; Chris@634: }presElVol[maxtracks]; Chris@634: }DynamicChange[maxdynamic]; Chris@634: }DynamicObjectVolume; Chris@634: Chris@634: // if (preset_type == 4) || (preset_type == 12) - Dynamic track approximated volume preset Chris@634: struct DynamicTrackApproxVolume{ Chris@634: u16 num_updates; Chris@634: struct DynamicChange_4{ Chris@634: u16 start_sample_number; Chris@634: u16 duration_update; Chris@634: struct presElVol_4{ Chris@634: u8 end_preset_volume_element; Chris@634: struct EQ_4{ // if preset_type == 12 (with EQ) Chris@634: u8 num_eq_filters; Chris@634: struct Filter_4{ Chris@634: u8 filter_type; Chris@634: u16 filter_reference_frequency; Chris@634: u8 end_filter_gain; Chris@634: u8 filter_bandwidth; Chris@634: }Filter[maxfilters]; Chris@634: }EQ; Chris@634: }presElVol[maxtracks]; Chris@634: }DynamicChange[maxdynamic]; Chris@634: }DynamicTrackApproxVolume; Chris@634: Chris@634: // if (preset_type == 5) || (preset_type == 13) - Dynamic object approximated volume preset Chris@634: // THIS STRUCTURE GIVES STACK OVERFLOW PROBLEMS - MORE STACK SIZE NEEDED -> Needs investigation Chris@634: struct DynamicObjectApproxVolume{ Chris@634: u16 num_updates; Chris@634: struct InputCH_5{ Chris@634: u8 num_input_channel; Chris@634: }InputCH[maxtracks]; Chris@634: u8 output_channel_type; Chris@634: struct DynamicChange_5{ Chris@634: u16 start_sample_number; Chris@634: u16 duration_update; Chris@634: struct presElVol_5{ Chris@634: struct Input_5{ Chris@634: struct Output_5{ Chris@634: u8 preset_volume_element; Chris@634: }Output[num_ch]; Chris@634: struct EQ_5{ // if preset_type == 11 (with EQ) Chris@634: u8 num_eq_filters; Chris@634: struct Filter_5{ Chris@634: u8 filter_type; Chris@634: u16 filter_reference_frequency; Chris@634: u8 end_filter_gain; Chris@634: u8 filter_bandwidth; Chris@634: }Filter[maxfilters]; Chris@634: }EQ; Chris@634: }Input[num_ch]; Chris@634: }presElVol[maxtracks]; Chris@634: }DynamicChange[maxdynamic]; Chris@634: }DynamicObjectApproxVolume; Chris@634: Chris@634: char preset_name[50]; Chris@634: Chris@634: }PresetBox[maxpreset]; Chris@634: Chris@634: }PresetContainerBox; Chris@634: Chris@634: struct RulesContainer{ Chris@634: u32 size; Chris@634: u32 type; Chris@634: u16 num_selection_rules; Chris@634: u16 num_mixing_rules; Chris@634: struct SelectionRules{ Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; Chris@634: u16 selection_rule_ID; Chris@634: unsigned char selection_rule_type; Chris@634: u32 element_ID; Chris@634: // Only for Min/Max Rule Chris@634: // if (selection_rule_type==0) Chris@634: u16 min_num_elements; Chris@634: u16 max_num_elements; Chris@634: // Only for Exclusion and Implication Rules Chris@634: // if (selection_rule_type==1 || selection_rule_type==3) Chris@634: u32 key_element_ID; Chris@634: char rule_description[20]; Chris@634: }SelectionRules; Chris@634: struct MixingRules{ Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; Chris@634: u16 mixing_rule_ID; Chris@634: unsigned char mixing_type; Chris@634: u32 element_ID; Chris@634: u16 min_volume; Chris@634: u16 max_volume; Chris@634: u32 key_elem_ID; Chris@634: char mix_description[17]; Chris@634: }MixingRules; Chris@634: }RulesContainer; Chris@634: struct GroupContainerBox{ //extends Box('grco') Chris@634: u32 size; // = 10 + sizeGRUP Chris@634: u32 type; Chris@634: u16 num_groups; Chris@634: struct GroupBox{ // extends FullBox('grup') Chris@634: u32 size; // = 21 + 22 + 32 (+2 if group_activation_mode = 2) Chris@634: u32 type; Chris@634: u32 version; Chris@634: u32 group_ID; Chris@634: u16 num_elements; Chris@634: struct groupElemId{ Chris@634: u32 element_ID; Chris@634: }groupElemId[maxtracks]; Chris@634: unsigned char group_activation_mode; Chris@634: u16 group_activation_elements_number; Chris@634: u16 group_reference_volume; Chris@634: char group_name[22]; Chris@634: char group_description[32]; Chris@634: }GroupBox[maxgroups]; Chris@634: }GroupContainerBox; Chris@634: }MovieBox; Chris@634: Chris@634: typedef struct MetaBox // extends FullBox ('meta') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; Chris@634: struct theHandler //extends FullBox HandlerBox('hdlr') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; // version = 0 + flag Chris@634: u32 pre_defined; // =0 Chris@634: u32 handler_type; // = 'meta' for Timed Metadata track Chris@634: u32 reserved[3]; // =0 Chris@634: unsigned char name[4]; Chris@634: }theHandler; Chris@634: struct file_locations //extends Box DataInformationBox('dinf') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: /* struct DataReferenceBox2 Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 flags; Chris@634: u32 entry_count; // = 1 Chris@634: struct DataEntryUrlBox2 //extends FullBox('url', version=0, flags) Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 flags; Chris@634: }DataEntryUrlBox; Chris@634: }DataReferenceBox; */ Chris@634: }file_locations; Chris@634: struct item_locations //extends FullBox ItemLocationBox('iloc') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; // version = 0 + flags Chris@634: unsigned char offset_size; // = 4 bytes Chris@634: unsigned char lenght_size; // = 4 bytes Chris@634: unsigned char base_offset_size; // = 4 bytes Chris@634: unsigned char reserved; // = 0 Chris@634: u16 item_count; // = 1 Chris@634: u16 item_ID; // = 1 Chris@634: u16 data_reference_index; // = 0 (this file) Chris@634: u32 base_offset; // size=(base_offset_size*8)=4*8 Chris@634: u16 extent_count; // = 1 Chris@634: u32 extent_offset; // size=(offset_size*8)=4*8 Chris@634: u32 extent_length; // size=(lenght_size*8)=4*8 Chris@634: }item_locations; Chris@634: struct item_infos //extends FullBox ItemInfoBox('iinf') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; // version = 0 + flag Chris@634: u16 entry_count; // = 1 Chris@634: struct info_entry// extends FullBox ItemInfoEntry('infe') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; // = 0 Chris@634: u16 item_ID; // = 1 Chris@634: u16 item_protection_index; // = 0 for "unprotected" Chris@634: char item_name[6]; // name with max 5 characters Chris@634: char content_type[18]; // = 'application/other' -> 17 characters Chris@634: char content_encoding[4]; // = 'jpg' for JPEG image -> 3 characters Chris@634: }info_entry; Chris@634: }item_infos; Chris@634: struct XMLBox // extends FullBox('xml ') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: u32 version; Chris@634: char string[2000]; Chris@634: }XMLBox; Chris@634: }MetaBox; Chris@634: Chris@634: typedef struct MediaDataBox // extends Box('mdat') Chris@634: { Chris@634: u32 size; Chris@634: u32 type; Chris@634: unsigned char data; Chris@634: }MediaDataBox; Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: Chris@634: #endif // IMAFENCODER_H