AIFF-C压缩格式容器规范解析
1、AIFF-C與AIFF的區別和注意事項:
? ? (1)AIFF-C和AIFF的區別:
?? ??? ?1)FORM標識符已從“AIFF”更改為“AIFC”。這將AIFF-C文件與AIFF文件區分開來。
?? ??? ?2)Common Chunk已擴展為包含壓縮類型ID和壓縮類型名稱。因此,AIFF-C能夠存儲從任何壓縮算法生成的壓縮音頻數據。
?? ??? ?3)Sound Data Chunk可以包含壓縮音頻數據。Chunk格式尚未修改。
?? ??? ?4)Sound Accelerator(Saxel)Chunk是全新的。它旨在消除在由標記定義的隨機點開始播放時由解壓縮算法引起的初始偽像。
?? ??? ?5)Format Version Chunk是新的。此Chunk旨在為AIFF-C規范的未來潛在升級提供平滑過渡。
?? ?(2)注意事項:
?? ??? ?1)Chunk Ordering(塊排序)
?? ??? ??? ?塊沒有順序!它們可能以任何順序出現在AIFF文件中。
?? ??? ??? ?應用程序讀取AIFF文件應該被設計為獲取塊,識別它,然后處理它,而不是假設它被識別之前它是什么塊。
?? ??? ?2)Modifying Chunks(修改Chunks)?? ?
?? ??? ??? ?如果應用程序允許修改Chunk,您還必須負責更新基于修改的Chunk的其他Chunks。
?? ??? ?3)Registering New Compression Types(注冊新的壓縮類型)?? ?
?? ??? ??? ?您必須向Apple注冊壓縮類型才能建立正式的compressionType和compressionName。
?? ??? ??? ?您還應該為壓縮類型描述Sound Accelerator Chunk的格式和用法。
?? ??? ?4)Number of Sample Frames(樣本幀數)
?? ??? ??? ?文件中包含的樣本幀數的是從Common Chunk中的numSampleFrames參數獲得的,而不是Sound Data Chunk中的ckDataSize參數。
?? ??? ?5)Remember the Pad Byte!(記住填充字節)
?? ??? ??? ?每個Chunk必須包含偶數個字節。對于總內容將產生奇數字節數的塊,必須在塊的末尾添加零填充字節。此填充字節不包含在ckDataSize中。
?? ??? ?6)Format Version Chunk(格式版本Chunk)
?? ??? ??? ?Format Version Chunk中標題為“何時讀取AIFF-C文件”的部分特別重要。
2、AIFF-C壓縮格式規范:
? ? (1)INTRODUCTION(介紹)
?? ??? ?音頻交換文件格式AIFF-C為存儲未壓縮或壓縮的采樣聲音提供了標準。
?? ??? ?該格式可以存儲一系列采樣率和樣本寬度的單聲道或多聲道采樣聲音。
?? ??? ?該格式是可擴展的,以處理新的壓縮類型和特定應用程序的數據。
?? ??? ?AIFF-C基于Audio IFF(AIFF),它符合Electronic Arts開發的“EA IFF 85”交換格式文件標準。
?? ??? ?AIFF-C專為交換而設計,盡管應用程序設計人員應該發現它足夠靈活,可以用作日常數據存儲格式。
?? ??? ?如果應用程序使用不同的存儲格式,它可以轉換為此處定義的AIFF-C格式。這將有助于在應用程序之間和各種計算機平臺之間共享聲音數據。
?? ??? ?1)Data types(數據類型)
?? ??? ??? ?char、unsigned char;
? ?? ??? ??? ?short、unsigned short;
? ?? ??? ??? ?long、unsigned long;
? ?? ??? ??? ?extends:80位IEEE標準754浮點數(標準Apple數字環境[SANE]數據類型擴展)。
?? ??? ??? ?pstring:Pascal樣式的字符串,一個字節計數后跟文本字節。 此數據類型中的總字節數應為偶數。可以在文本末尾添加填充字節以完成此操作。該填充字節不會反映在計數中。
?? ??? ??? ?ID:32位,在''(SP,0x20)到'~'(0x7E)范圍內的四個可打印ASCII字符的串聯。空格(0x20)不能在打印字符之前; 允許尾隨空格。禁止控制字符。
?? ??? ??? ?OSType:32位。內部定義的由四個字符組成的串接。大寫/小寫很重要,也就是說,使用簡單的32位相等性檢查來比較OSType。
?? ??? ?2)Data Organization(數據組織)
?? ??? ??? ?所有數據均以Motorola 68000格式存儲。數字首先存儲為高字節。
?? ??? ??? ?數據的低位存放在高地址,高位存放在低地址(Big-endian)。
?? ?(2)FILE STRUCTURE(文件結構)
?? ??? ?交換格式文件的“EA IFF 85”標準定義了用于在文件中存儲數據的整體結構。
?? ??? ?“EA IFF 85”文件是從許多數據塊構建的。Chunks是“EA IFF 85”文件的構建塊。塊包含一些標頭信息,后跟數據。
?? ??? ?結構表示如下:
?? ??? ?typedef struct {
?? ??? ??? ?ID ckID; /* chunk ID */
?? ??? ??? ?long ckDataSize; /* chunk data size, in bytes */
?? ??? ??? ?char ckData[]; /* data */
?? ??? ?} Chunk;
?? ??? ?參數解析:
?? ??? ?ckID描述了chunk數據部分的格式。程序可以通過檢查ckID來確定如何解釋chunk數據。
?? ??? ?ckDataSize是塊的數據部分的大小,以字節為單位。它不包括ckID和ckDataSize使用的8個字節。
?? ??? ?ckData是存儲在塊中的數據。該數據的格式由ckID確定。如果數據的長度為奇數個字節,則必須在末尾添加零填充字節。填充字節不包含在ckDataSize中。
?? ??? ?
?? ??? ?AIFF-C文件是許多不同類型的塊的集合。
?? ??? ?Common Chunk包含描述采樣聲音的重要參數,例如其length和sample rate。
?? ??? ?Sound Data Chunk包含實際的音頻樣本。
?? ??? ?還有其他幾個可選塊來定義markers,列出instrument parameters(儀器參數),存儲應用程序特定信息等。
?? ??? ?AIFF-C文件中的塊在容器塊中組合在一起。“EA IFF 85”定義了許多容器塊,但AIFF-C使用的容器塊稱為FORM。
?? ??? ?FORM具有以下格式:
?? ??? ?typedef struct {
?? ??? ??? ?ID ckID; /* 'FORM' */
?? ??? ??? ?long ckDataSize;
?? ??? ??? ?
?? ??? ??? ?ID formType; /* 'AIFC' */
?? ??? ??? ?Chunk chunks[];
?? ??? ?} FormAIFCChunk;
?? ??? ?參數解析:
?? ??? ?ckID始終是'FORM'。這表明這是一個FORM chunk。
?? ??? ?ckDataSize包含'FORM'塊的數據部分的大小。注意數據部分已分為兩部分,formType和chunks []。
?? ??? ?formType描述'FORM'塊中的內容,非常類似于Mac文件類型。對于AIFF-C文件,formType是'AIFC'。FORMType“AIFC”的FORM塊稱為FORM AIFC。
?? ??? ?chunks是FORM中包含的chunks。這些chunks稱為local chunks,因為它們自己的ckID是FORM AIFC的local chunks。FORM AIFC及其local chunks構成AIFF-C文件。
?? ??? ?
?? ??? ?FORM AIFC中對本地塊的排序沒有限制。
?? ??? ?
?? ??? ?1)Local Chunk Types(本地塊類型)
?? ??? ??? ?FORM AIFC中需要Common Chunk。如果采樣的聲音長度大于零,則需要Sound Data chunk。所有其他塊都是可選的。
?? ??? ??? ?使用FORM AIFC的所有應用程序必須能夠讀取所需的塊,并可以選擇有選擇地忽略可選塊。
?? ??? ?2)Dealing with Unrecognized Local Chunks(處理無法識別的本地塊)
?? ??? ??? ?在讀取IFF文件時,程序可能會遇到無法識別的本地塊類型,可能是在編寫程序后定義的擴展。
?? ??? ??? ?在FORM AIFC中,這種情況也適用于具有無法識別的應用程序簽名的應用于特定程序的塊。(應用程序簽名充當塊子類型。)
?? ??? ??? ?程序在IFF FORM中遇到無法識別的塊時應該怎么做?最安全的是在讀FORM時簡單地丟棄它們。
?? ?(3)FORMAT VERSION CHUNK(格式版本塊)
?? ??? ?Format Version Chunk包含一個日期字段,用于指示AIFF-C規范的格式規則。這將使未來更順利地升級到此規范。
?? ??? ?1)Format Version Chunk
?? ??? ??? ?Format Version Chunk數據格式如下:
?? ??? ??? ?#define AIFCVersion1 0xA2805140 /* Version 1 of AIFF-C this is 2726318400 in decimal */
?? ??? ??? ?typedef struct {
?? ??? ??? ??? ?ID ckID ; /* 'FVER' */
?? ??? ??? ??? ?long ckDataSize ; /* 4 */
?? ??? ??? ??? ?unsigned long timestamp ; /* AIFCVersion1 */
?? ??? ??? ?} FormatVersionChunk;
?? ??? ??? ?參數解析:
?? ??? ??? ?ckID總是'FVER'。
?? ??? ??? ?ckDataSize是塊的數據部分的大小,以字節為單位。它不包括ckID和ckDataSize使用的8個字節。對于此Chunk,ckDataSize的值為4。
?? ??? ??? ?timeStamp表示何時創建AIFF-C文件的格式版本。單位是自1904年1月1日以來的秒數。
?? ??? ??? ?
?? ??? ??? ?只有Apple可能會改變時間戳的值。不要將格式版本與文件的創建日期混淆。
?? ??? ??? ?格式版本是指在此文檔或將來的文檔中包含的規則,這些文檔指定如何安排AIFF-C文件。
?? ??? ??? ?格式版塊是必需的。一個且只有一個Format Version Chunk必須出現在FORM AIFC中。
?? ??? ?2)為什么添加了格式版本塊
?? ??? ??? ?“如果我們在AIFF中有一個版本塊,我們就不必更改AIFFC的FORM類型了。hh”
?? ??? ??? ?您識別的Chunk名稱將包含您熟悉的格式的信息。
?? ??? ??? ?如果找不到應用程序所需的Chunk,請檢查Format Version Chunk以確定文件是否已損壞,或者應用程序與文件之間是否存在不匹配。
?? ??? ??? ?
?? ??? ?了解以下步驟如何簡化您的生活(和我們的生活)以確定FORM AIFC是否可用:
?? ??? ?
?? ??? ?3)讀取AIFF-C文件時
?? ??? ??? ?1.首先找到FORM AIFC字段。如果找不到,請發出“此文件不包含AIFC標準錄音”的提醒,然后退出這些指示。
?? ??? ??? ?2.嘗試找到對您的應用程序至關重要的所有塊(可能是COMM和SSND,但我們可以想象一個只需要COMM塊的應用程序,例如確定播放持續時間)。
?? ??? ??? ??? ?如果找到,那些熟悉的chunk ID表示塊內容采用您期望的格式。
?? ??? ??? ?3.如果沒有找到,請不要崩潰。而是檢查格式版本塊。
?? ??? ?4)Remember
?? ??? ??? ?為了在交換和格式演變中生存,讀程序必須對塊順序,缺少塊和意外塊有強大的作用。
?? ??? ??? ?與原始AIFF規范相反,當程序遇到無法識別的塊時,它應該跳過它。請勿將其復制到新的已編輯文件中。這是IFF中的一般規則,因為在編輯周圍數據時無法保持無法識別的塊的完整性。
?? ??? ?5)Format Version Chunk如何幫助未來的潛在升級
?? ??? ??? ?如果在AIFF中已經有格式版本塊,將如何升級AIFF來處理壓縮音頻:
?? ??? ??? ??? ??壓縮是可選的。
?? ??? ??? ??? ??不要更改COMM Chunk的格式。現有程序仍然可以讀取它。
?? ??? ??? ??? ??添加一個“Compression Descriptor”塊,其中包含4個字母的壓縮類型代碼和壓縮名稱字符串。
?? ??? ??? ??? ??用壓縮聲音數據塊“CSND”替換SSND塊。(現有程序將忽略它。)
?? ??? ??? ??? ??更改格式版本日期(為了警報)。
?? ??? ??? ??? ??添加可選的Saxel Chunk。
?? ??? ??? ?將FORM類型從AIFF更改為AIFC,是由于缺少Format Version Chunk,現有應用程序將無法發出有用的錯誤消息。如果某些現有應用程序找不到SSND Chunk,它們甚至可能會崩潰。
?? ?(4)COMMON CHUNK?? ??? ?
?? ??? ?Common Chunk描述了采樣聲音的基本參數。結構如下:
?? ??? ?#define CommonID 'COMM' /* ckID for Common Chunk */
?? ??? ?typedef struct {
?? ??? ??? ?ID ckID; /* 'COMM' */
?? ??? ??? ?long ckDataSize;
?? ??? ??? ?
?? ??? ??? ?short numChannels; /* # audio channels */
?? ??? ??? ?unsigned long numSampleFrames; /* # sample frames = samples/channel */
?? ??? ??? ?short sampleSize; /* # bits/sample */
?? ??? ??? ?extended sampleRate; /* sample_frames/sec */
?? ??? ??? ?ID compressionType; /* compression type ID code */
?? ??? ??? ?pstring compressionName; /* human-readable compression type name */
?? ??? ?} CommonChunk;
?? ??? ?參數解析:
?? ??? ?ckID始終是'COMM'。
?? ??? ?ckDataSize是塊的數據部分的大小(以字節為單位)。它不包括ckID和ckDataSize使用的8個字節。
?? ??? ??? ?對于Common Chunk,ckDataSize是22 +pstring的大小。(當需要填充偶數個字節時,pstring包含填充字節。)
?? ??? ?numChannels包含聲音的音頻通道數。值1表示單聲道聲音,2表示立體聲,4表示四聲道聲音等。可以表示任意數量的音頻聲道。
?? ??? ??? ?實際的聲音樣本存儲在另一個Sound Data Chunk中,對于多聲道聲音,來自每個聲道的單個采樣點是交錯的。一組交錯的采樣點稱為采樣幀。
?? ??? ??? ?對于單聲道聲音,樣本幀是單個樣本點。
?? ??? ?numSampleFrames包含Sound Data Chunk中的樣本幀數。
?? ??? ??? ?請注意,numSampleFrames是樣本幀的數量,而不是Sound Data Chunk中的字節數和采樣點數。對于未壓縮的聲音數據,文件中的采樣點總數為numSampleFrames * numChannels。
?? ??? ?sampleSize是未壓縮聲音數據的每個采樣點中的位數。
?? ??? ??? ?它可以是1到32之間的任何數字。對于壓縮聲音數據,sampleSize表示壓縮前原始聲音數據中的位數。
?? ??? ?sampleRate是播放聲音的采樣率,是sample frames per second(每秒采樣幀數)。
?? ??? ?程序使用compressionType來識別聲音數據上使用的壓縮算法(如果有的話)。
?? ??? ?compressionName被人們用來識別壓縮算法。
?? ??? ??? ?使用compressionType選擇解壓縮例程。當您沒有所需的解壓縮例程時,使用compressionName顯示人類可讀的消息。
?? ??? ??? ?如果pstring長度不是偶數個字節,用零字節填充compressionName的末尾,但不要在計數中包含填充字節。
?? ??? ?compressionType compressionName ?? ??? ?meaning
?? ??? ?'NONE'?? ??? ? ? ?"not compressed" ?? ??? ?uncompressed, that is, straight digitized samples
?? ??? ?'ACE2' ?? ??? ??? ?"ACE 2-to-1" 2-to-1 ?? ?IIGS ACE (Audio Compression / Expansion)
?? ??? ?'ACE8' ?? ??? ??? ?"ACE 8-to-3" 8-to-3 ?? ?IIGS ACE (Audio Compression / Expansion)
?? ??? ?'MAC3' ?? ??? ??? ?"MACE 3-to-1" 3-to-1 ?? ?Macintosh Audio Compression / Expansion
?? ??? ?'MAC6'?? ??? ? ? ?"MACE 6-to-1" 6-to-1 ?? ?Macintosh Audio Compression / Expansion
?? ??? ?
?? ??? ?注意:compressionType是標識壓縮算法的標準32位ID值。
?? ??? ?相反,compressionName的值可以是特定于國家的,例如 以法語或西班牙語存儲。
?? ??? ?
?? ??? ?每個FORM AIFC中必須出現一個且只有一個Common Chunk。
?? ??? ?
?? ?(5)SOUND DATA CHUNK
?? ??? ?SOUND DATA CHUNK包含實際的采樣幀。
?? ??? ?結構定義如下:
?? ??? ?#define SoundDataID 'SSND' /* ckID for Sound Data Chunk */
?? ??? ?typedef struct {
?? ??? ??? ?ID ckID; /* 'SSND' */
?? ??? ??? ?long ckDataSize;
?? ??? ??? ?unsigned long offset;
?? ??? ??? ?unsigned long blockSize;
?? ??? ??? ?char soundData[];
?? ??? ?} SoundDataChunk;
?? ??? ?參數解析:
?? ??? ?ckID始終是'SSND'。
?? ??? ?ckDataSize是塊的數據部分的大小,以字節為單位。
?? ??? ??? ?它不包括ckID和ckDataSize使用的8個字節。它包括offset和blockSize占用的8個字節。
?? ??? ??? ?如果soundData []包含奇數個字節,則在末尾添加一個值為零的填充字節,以保留此塊的偶數長度。此填充字節(如果存在)不包含在ckDataSize中。
?? ??? ??? ?為避免混淆,應始終從Common Chunk中的numSampleFrames參數獲取實際的采樣幀數。
?? ??? ?offset確定soundData中第一個樣本幀的開始位置。offset以字節為單位。
?? ??? ??? ?下面的BlockAligning Sound Data部分解釋了用于非零偏移的用法。
?? ??? ?blockSize與偏移結合用于塊對齊聲音數據。它包含聲音數據對齊的塊的字節大小。
?? ??? ??? ?與偏移量一樣,大多數應用程序不會使用blockSize,應將其設置為零。
?? ??? ?soundData包含組成聲音的采樣幀。soundData中的樣本幀數由Common Chunk中的numSampleFrames參數確定。?? ?
?? ??? ??? ?如果soundData []包含奇數個字節,則在末尾添加零填充字節(但不用于回放)。
?? ??? ?
?? ??? ?1)Linear Sound Data (not compressed)(線性聲音數據)
?? ??? ??? ?樣本幀中的每個樣本點都是線性的2的補碼值。
?? ??? ??? ?采樣點的寬度為1到32位,由Common Chunk中的sampleSize參數決定。每個采樣點存儲在整數個連續字節中。
?? ??? ??? ?一到八位寬的采樣點存儲在一個字節中; 9到16位寬的采樣點存儲在兩個字節中; 17至24位寬的采樣點以3個字節存儲; 25到32位寬的采樣以4個字節存儲。
?? ??? ??? ?當采樣點的寬度小于8位的倍數時,采樣點數據左對齊(使用左移指令),其余位為零。右端的剩余低位設置為零。
?? ??? ??? ?
?? ??? ??? ?例如,12位樣本二進制101000010111以左對齊方式存儲在兩個字節中:
?? ??? ??? ?1 0 1 0 0 0 0 1 0 1 1 1 ? 0 0 0 0
?? ??? ??? ?12位采樣點左對齊 ? ? ? ? ?最右邊的4位是零填充
?? ??? ?2)Sample Frames(采樣幀)
?? ??? ??? ?采樣幀內的采樣點按照上面“Common Chunk”中的描述打包在一起。采樣幀按照增加的時間順序存儲。采樣點之間或采樣幀之間沒有填充字節。
?? ??? ?3)Compressed Sound Data(壓縮聲音數據)
?? ??? ??? ?soundData根據Common Chunk中的compressionType參數進行壓縮。
?? ??? ??? ?附錄C描述了現有Apple Computer音頻壓縮實用程序的編碼格式以及Marker和Saxel Chunks(見下文)與各種壓縮類型的使用。
?? ??? ?4)Block-Aligning Sound Data
?? ??? ??? ?可能存在一些應用程序,為了實現音頻的實時記錄和回放,希望將采樣的聲音數據對準固定大小的磁盤塊。這可以使用offset和blockSize參數來完成。
?? ??? ??? ?第一個樣本幀從磁盤塊N的開頭開始。這是通過跳過soundData的第一個偏移字節來完成的。
?? ??? ??? ?blockSize指定對齊塊的大小(以字節為單位)。blockSize為零表示聲音數據不需要塊對齊。
?? ??? ??? ?在編寫AIFF-C文件時,不關心塊對齊的應用程序應將blockSize和offset設置為零。4
?? ??? ??? ?寫入塊對齊聲音數據的應用程序應將blockSize設置為適當的塊大小。
?? ??? ??? ?修改現有AIFF-C文件的應用程序應嘗試保留聲音數據的對齊,盡管這不是必需的。
?? ??? ??? ?如果應用程序不保留對齊,則應將blockSize和offset設置為零。如果應用程序需要將聲音數據重新對齊到不同大小的塊,則應更新blockSize并相應地進行偏移。
?? ??? ??? ?
?? ??? ??? ?除非Common Chunk中的numSampleFrames字段為零,否則聲音數據塊是必需的。最多一個聲音數據塊可以出現在FORM AIFC中。
?? ??? ?
?? ?(6)MARKER CHUNK
?? ??? ?Marker Chunk包含指向聲音數據中位置的標記。
?? ??? ??? ?Markers可用于應用程序所需的任何目的。后面定義的Instrument Chunk使用標記來標記循環起點和終點。
?? ??? ?1)Markers
?? ??? ??? ?Markers結構如下:
?? ??? ??? ?typedef short MarkerId;
?? ??? ??? ?typedef struct {
?? ??? ??? ??? ?MarkerId id; /* must be > 0 */
?? ??? ??? ??? ?unsigned long position; /* sample frame number */
?? ??? ??? ??? ?pstring markerName;
?? ??? ??? ?} Marker;
?? ??? ??? ?參數解析:
?? ??? ??? ?id是唯一標識FORM AIFC中marker的數字。只要同一個FORM AIFC中沒有其他marker具有相同的id,id就可以是任何正的非零整數。
?? ??? ??? ?marker在聲音數據中的位置由position指示。marker在概念上落在兩個采樣幀之間。
?? ??? ??? ??? ?落在聲音數據中第一個樣本幀之前的標記位于零位置,而落在聲音數據中第一個和第二個樣本幀之間的標記位于位置1.注意位置的單位是樣本幀,而不是字節和樣本點。
?? ??? ??? ?
?? ??? ??? ??? ?對于壓縮聲音數據,標記的位置基于擴展(未壓縮)聲音數據,而不是壓縮樣本幀的位置。
?? ??? ??? ??? ?這允許細粒度分辨率將標記點精確放置在需要的位置(對于循環點尤其重要)。
?? ??? ??? ??? ?單個字節的壓縮聲音數據可以擴展為擴展聲音數據的許多字節,從而防止基于壓縮數據的標記的高分辨率。
?? ??? ??? ??? ?對于現有的Apple音頻壓縮算法,可以輕松完成壓縮聲音數據樣本幀到擴展聲音數據樣本幀的映射。
?? ??? ??? ??? ?
?? ??? ??? ??? ?建議音頻編輯器程序在編輯音頻數據時更新標記。
?? ??? ??? ?markerName是一個包含標記名稱的pstring。在需要時將填充字節包括為pstring到偶數個字節。
?? ??? ?2)Marker Chunk Format
?? ??? ??? ?Marker Chunk中數據的格式如下所示:
?? ??? ??? ?#define MarkerID 'MARK' /* ckID for Marker Chunk */
?? ??? ??? ?typedef struct {
?? ??? ??? ??? ?ID ckID; /* 'MARK' */
?? ??? ??? ??? ?long ckDataSize;
?? ??? ??? ??? ?unsigned short numMarkers;
?? ??? ??? ??? ?Marker markers[];
?? ??? ??? ?} MarkerChunk;
?? ??? ??? ?參數解析:
?? ??? ??? ?ckID總是'MARK'。
?? ??? ??? ?ckDataSize是塊的數據部分的大小,以字節為單位。它不包括ckID和ckDataSize使用的8個字節。
?? ??? ??? ?numMarkers是Marker Chunk中的標記數。
?? ??? ??? ?numMarkers,如果非零,則后跟標記本身。
?? ??? ??? ??? ?由于標記中的所有字段長度均為偶數個字節,因此任何標記的長度始終為偶數。
?? ??? ??? ??? ?因此,標記被打包在一起,它們之間沒有未使用的字節。標記不需要以任何特定方式排序。
?? ??? ??? ?Marker Chunk是可選的。在FORM AIFC中只能出現一個Marker Chunk。
?? ??? ??? ?
?? ??? ??? ?注意:如果包含一個或多個標記的聲音數據片段在聲音流中重新定位,則必須重新計算要移動的片段內的標記。
?? ?(7)COMMENTS CHUNK
?? ??? ?Comments Chunk用于在FORM AIFF中存儲注釋。“EA IFF 85”有一個可用于注釋的注釋塊,但是注釋塊有兩個在“EA IFF 85”塊中找不到的功能。它們是:1)評論的時間戳;2)指向標記的鏈接。
?? ??? ?1)Comment
?? ??? ?Comments由時間戳,標記ID和文本計數跟文本組成。結構如下:
?? ??? ?typedef struct {
?? ??? ??? ?unsigned long timeStamp; /* comment creation date */
?? ??? ??? ?MarkerId marker; /* comments for this marker number */
?? ??? ??? ?unsigned short count; /* comment text string length */
?? ??? ??? ?char text[]; /* comment text */
?? ??? ?} Comment;
?? ??? ?參數解析:
?? ??? ?timeStamp表示Comments的創建時間。單位是自1904年1月1日以來的秒數。
?? ??? ?Comments可以鏈接到標記。這允許應用程序將標記的長描述存儲為Comments。如果Comments指的是標記,則marker是該標記的ID。否則,標記為零,表示此Comments未鏈接到標記。
?? ??? ?count是組成Comments的文本的長度。這是一個16位的數量,允許比pstring更長的Comments。
?? ??? ?text包含Comments本身。必須在末尾用一個字節填充此文本,以確保它的長度為偶數個字節。該填充字節(如果存在)不包括在計數中。
?? ??? ?
?? ??? ?2)Comments Chunk Format:
?? ??? ??? ?結構如下:
?? ??? ??? ?#define CommentID 'COMT' /* ckID for Comments Chunk. */
?? ??? ??? ?typedef struct {
?? ??? ??? ??? ?ID ckID;
?? ??? ??? ??? ?long ckSize;
?? ??? ??? ??? ?unsigned short numComments;
?? ??? ??? ??? ?Comment comments[];
?? ??? ??? ?} CommentsChunk;
?? ??? ??? ?ckID總是'COMT'。ckSize是塊的數據部分的大小,以字節為單位。它不包括ckID和ckSize使用的8個字節。
?? ??? ??? ?numComments包含Comments Chunk中的Comments數。接下來是Comments本身。Comments長度總是為偶數個字節,因此Comments Chunk中的Comments之間沒有填充。
?? ??? ??? ?Comments Chunk是可選的。一個FORM AIFF中只能出現一個Comments Chunk。
?? ?(8)SOUND ACCELERATOR (SAXEL) CHUNK(聲音加速器(SAXEL)CHUNK)
?? ??? ?Saxel Chunk旨在通過壓縮音頻數據流中的任何隨機點(由標記指示)提供高質量的播放。
?? ??? ?對Saxel Chunk的需求源于音頻解壓縮器的行為,其在很大程度上依賴于最近解壓縮的樣本的一些歷史來預測下一個要解壓縮的樣本的值。
?? ??? ??? ?在隨機點開始解壓縮音頻流將導致在算法的內部解壓縮參數穩定之前聽到初始音頻偽像。
?? ?(9)INSTRUMENT CHUNK?? ?
?? ??? ?Instrument Chunk定義了儀器(例如采樣鍵盤)可用于回放聲音數據的基本參數。
?? ??? ?1)Looping(循環)
?? ??? ??? ?可以重復聲音數據的一部分以延長聲音。該部分稱為循環段,重復進行,直到被取樣鍵盤上的鍵釋放中斷為止。
?? ??? ??? ?有兩種播放循環的方法:前向循環和前進/后退(或“乒乓”)循環。
?? ??? ??? ?
?? ??? ??? ?要實現前向循環,請反復播放循環段。要實現向前/向后循環,請向前播放循環段,然后向后播放,并反復向前/向后重復此對。
?? ??? ??? ?下面的結構描述了一個循環:
?? ??? ??? ?typedef struct {
?? ??? ??? ??? ?short playMode;
?? ??? ??? ??? ?MarkerId beginLoop;
?? ??? ??? ??? ?MarkerId endLoop;
?? ??? ??? ?} Loop;
?? ??? ??? ?參數解析:
?? ??? ??? ?playMode指定要執行的循環類型:
?? ??? ??? ?#define NoLooping 0
?? ??? ??? ?#define ForwardLooping 1
?? ??? ??? ?#define ForwardBackwardLooping 2
?? ??? ??? ?
?? ??? ??? ?NoLooping意味著在播放期間忽略這些循環點。
?? ??? ??? ?beginLoop和endLoop是標記id,用于標記循環段的開始和結束位置。
?? ??? ??? ?開始位置必須小于結束位置,因此環段將具有正長度。(如果不是這種情況,則忽略此循環段。不會發生循環。)
?? ??? ?2)Instrument Chunk Format
?? ??? ??? ?Instrument Chunk中的數據格式如下所述:
?? ??? ??? ?#define InstrumentID 'INST' /* ckID for Instrument Chunk */
?? ??? ??? ?typedef struct {
?? ??? ??? ??? ?ID ckID; /* 'INST' */
?? ??? ??? ??? ?long ckDataSize;
?? ??? ??? ??? ?char baseNote;
?? ??? ??? ??? ?char detune;
?? ??? ??? ??? ?char lowNote;
?? ??? ??? ??? ?char highNote;
?? ??? ??? ??? ?char lowVelocity;
?? ??? ??? ??? ?char highVelocity;
?? ??? ??? ??? ?short gain;
?? ??? ??? ??? ?Loop sustainLoop;
?? ??? ??? ??? ?Loop releaseLoop;
?? ??? ??? ?} InstrumentChunk;
?? ??? ??? ?參數解析:
?? ??? ??? ?ckID始終是'INST'。
?? ??? ??? ?ckDataSize是塊的數據部分的大小,以字節為單位。
?? ??? ??? ??? ?對于儀器塊,ckDataSize始終為20。
?? ??? ??? ?ckID始終是'INST'。ckSize是塊的數據部分的大小,以字節為單位。對于儀器塊,ckSize始終為20。
?? ??? ??? ?baseNote是工具在沒有音調修改的情況下播放聲音數據的注釋。單位是MIDI(MIDI是樂器數字接口的首字母縮寫)音符編號,范圍是0到127.中間C是60。
?? ??? ??? ?detune決定工具在播放時應改變聲音音高的程度。單位為美分(半音的1/100),范圍從-50到+50。負數表示聲音的音高應該降低,而正數表示應該提高聲音的音高。
?? ??? ??? ?lowNote和highNote指定鍵盤上的建議范圍以播放聲音數據。如果要求樂器在低音符和高音符之間播放音符,則應播放聲音數據。基調不必在此范圍內。lowNote和highNote的單位是MIDI音符值。
?? ??? ??? ?lowVelocity和highVelocity指定播放聲音數據的建議速度范圍。如果音符開啟速度介于低速和高速之間,則應播放聲音數據。單位是MIDI速度值,1(最低速度)到127(最高速度)。
?? ??? ??? ?gain(增益)是在播放時改變聲音增益的量。單位是分貝。例如,0 db表示沒有變化,6 db表示每個采樣點的值加倍,而-6 db表示每個采樣點的值減半。
?? ??? ??? ?sustainLoop指定一個循環,當工具維持聲音時要播放該循環。
?? ??? ??? ?releaseLoop指定當樂器處于播放聲音的釋放階段時要播放的循環。釋放階段通常在樂器上的鍵釋放后發生。
?? ??? ??? ?
?? ??? ??? ?Instrument Chunk是可選的。FORM AIFF中只能出現一個Instrument Chunk。
?? ?(10)MIDI DATA CHUNK
?? ??? ?MIDI數據塊可用于存儲MIDI數據。
?? ??? ?此塊的主要用途是存儲MIDI系統專用消息,盡管其他類型的MIDI數據可以存儲在此塊。
?? ??? ?隨著越來越多的儀器上市,它們可能會有一些參數未包含在AIFF-C規范中。
?? ??? ?這些樂器的MIDI系統專用信息可能包含許多未包含在樂器組塊中的參數。
?? ??? ?例如,新的采樣儀器可能具有多于Instrument Chunk中定義的兩個環路。
?? ??? ?這些循環可能會在新機器的MIDI System Exclusive消息中表示。此MIDI系統專用消息可以存儲在MIDI數據塊中。
?? ??? ?
?? ??? ?#define MIDIDataID 'MIDI' /* ckID for MIDI Data Chunk */
?? ??? ?typedef struct {
?? ??? ??? ?ID ckID; /* 'MIDI' */
?? ??? ??? ?long ckDataSize;
?? ??? ??? ?unsigned char MIDIdata[];
?? ??? ?} MIDIDataChunk;
?? ??? ?ckID總是'MIDI'。
?? ??? ?ckDataSize是塊的數據部分的大小,以字節為單位。它不包括ckID和ckSize使用的8個字節。
?? ??? ?MIDIData包含MIDI數據流。
?? ??? ?MIDI數據塊是可選的。FORM AIFF中可能存在任意數量的MIDI數據塊。
?? ??? ??? ?如果要將多個樂器的MIDI系統專用信息存儲在FORM AIFF中,最好每個樂器使用一個MIDI數據塊,而不是所有樂器使用一個大的MIDI數據塊。
?? ?(11)AUDIO RECORDING CHUNK(錄音塊)
?? ??? ?錄音塊包含與錄音設備有關的信息。結構定義如下:
?? ??? ?#define AudioRecordingID 'AESD' /* ckID for Audio Recording Chunk */
?? ??? ?typedef struct {
?? ??? ??? ?ID ckID; /* 'AESD' */
?? ??? ??? ?long ckDataSize;
?? ??? ??? ?unsigned char AESChannelStatusData[24];
?? ??? ?} AudioRecordingChunk;
?? ??? ?#define AudioRecordingID 'AESD' /* ckID for Audio Recording Chunk. */
?? ??? ?typedef struct {
?? ??? ??? ?ID ckID;
?? ??? ??? ?long ckSize;
?? ??? ??? ?unsigned char AESChannelStatusData[24];
?? ??? ?} AudioRecordingChunk;
?? ??? ?
?? ??? ?ckID始終是'AESD'。
?? ??? ?ckDataSize是塊的數據部分的大小,以字節為單位。對于錄音塊,ckSize始終為24。
?? ??? ?AESChannelStatusData的24個字節在AES推薦的數字音頻工程實踐 - 線性表示的數字音頻數據的串行傳輸格式,第7.1節,通道狀態數據中規定。該文件描述了用于音頻設備之間的數字音頻的實時數字傳輸的格式。為方便起見,此信息在音頻記錄塊中重復。一般感興趣的是字節0的位2,3和4,它們描述了記錄強調。
?? ??? ?音頻錄制塊是可選的。FORM AIFF中不得出現多個音頻錄制塊。
?? ?(12)APPLICATION SPECIFIC CHUNK(應用程序特殊塊)
?? ??? ?Application Specific Chunk可以用于應用程序制造商的任何目的。結構如下:
?? ??? ??? ?例如,編輯聲音的應用程序可能希望使用該塊來存儲編輯器狀態參數,例如放大級別,最后光標位置等。
?? ??? ?結構如下:
?? ??? ?#define ApplicationSpecificID 'APPL' /* ckID for Application Specific Chunk. */
?? ??? ?typedef struct {
?? ??? ??? ?ID ckID;
?? ??? ??? ?long ckDataSize;
?? ??? ??? ?OSType applicationSignature;
?? ??? ??? ?char data[];
?? ??? ?} ApplicationSpecificChunk;
?? ??? ?
?? ??? ?ckID總是'APPL'。
?? ??? ?ckDataSize是塊的數據部分的大小,以字節為單位。它不包括ckID和ckSize使用的8個字節。
?? ??? ?applicationSignature標識特定的應用程序。
?? ??? ??? ?對于Macintosh應用程序,這將是應用程序的四個字符簽名。
?? ??? ??? ?對于Apple II應用程序,applicationSignature應始終為“pdos”或十六進制字節0x70646F73。
?? ??? ??? ?如果applicationSignature是'pdos',則數據區的開頭被定義為包含應用程序名稱的Pascal樣式字符串(長度字節后跟ASCII字符串字節)。
?? ??? ??? ?這是必要的,因為Apple II應用程序沒有Macintosh應用程序那樣的四字節簽名。
?? ??? ??? ?對于在Apple計算機以外運行的應用程序,應用程序簽名應始終為“stoc”。數據區的開頭被定義為包含應用程序名稱的Pascal樣式字符串(長度字節后跟ASCII字符串字節)。
?? ??? ?data是Application Specific Chunk的數據。必須根據需要在末尾填充一個字節,以使其長度為偶數個字節。
?? ??? ?Application Specific Chunk是可選的。單個FORM AIFF中可能存在任意數量的Application Specific Chunk。
?? ?(13)TEXT CHUNKS - NAME, AUTHOR, COPYRIGHT, ANNOTATION
?? ??? ?這四個塊包含在每個“EA IFF 85”文件的定義中。全是文本塊;他們的數據部分僅由文本組成。這些塊中的每一個都是可選的。
?? ??? ?#define NameID 'NAME' /* ckID for Name Chunk. */
?? ??? ?#define AuthorID 'AUTH' /* ckID for Author Chunk. */
?? ??? ?#define CopyrightID '(c) ' /* ckID for Copyright Chunk. */
?? ??? ?#define AnnotationID 'ANNO' /* ckID for Annotation Chunk. */
?? ??? ?typedef struct {
?? ??? ??? ?ID ckID;
?? ??? ??? ?long ckDataSize;
?? ??? ??? ?char text[];
?? ??? ?} TextChunk;
?? ?
?? ??? ?ckID是“NAME”,“AUTH”,“(c)”或“ANNO”,具體取決于塊是否分別為Name Chunk,Author Chunk,Copyright Chunk或Annotation Chunk。對于版權塊,'c'是小寫的,并且在右括號后面有一個空格(0x20)。
?? ??? ?ckDataSize是塊的數據部分的大小,在本例中是文本。
?? ??? ?text包含純ASCII字符。它不是pstring也不是C字符串。text中的字符數由ckSize確定。text內容取決于塊,如下所述:?
?? ??? ?
?? ??? ?Name Chunk:
?? ??? ??? ?text包含采樣聲音的名稱。名稱塊是可選的。FORM AIFF中可能只存在一個名稱塊。
?? ??? ?Author Chunk:
?? ??? ??? ?text包含一個或多個作者姓名。在這種情況下,作者是采樣聲音的創建者。作者塊是可選的。FORM AIFF中可能只存在一個作者塊。?? ?
?? ??? ?Copyright Chunk:
?? ??? ??? ?版權塊包含聲音的版權聲明。文本包含版權所有者遵循的日期。
?? ??? ??? ?版權塊是可選的。FORM AIFF中可能只存在一個版權塊。
?? ??? ?Annotation Chunk:
?? ??? ??? ?text包含評論。在FORM AIFF中不鼓勵使用此塊。應該使用功能更強大的Comments Chunk。Annotation Chunk是可選的。FORM AIFF中可能存在許多Annotation Chunk。
?? ?(14)CHUNK PRECEDENCE
?? ??? ?FORM AIFF的幾個本地塊可能包含重復信息。例如,樂器塊定義了循環點,MIDI數據塊中的MIDI系統專用數據也可以定義循環點。如果這些循環點不同會發生什么?應用程序應該如何循環聲音?
?? ??? ?通過定義塊的優先級來解決此類沖突:?
?? ??? ?Format Version Chunk ?? ??? ??? ?Highest precedence
?? ??? ?Common Chunk
?? ??? ?Instrument Chunk
?? ??? ?Saxel Chunk
?? ??? ?Comments Chunk
?? ??? ?Marker Chunk
?? ??? ?Sound Data Chunk
?? ??? ?Name Chunk
?? ??? ?Author Chunk
?? ??? ?Copyright Chunk
?? ??? ?Annotation Chunk(s) ?? ??? ??? ?-- in the order they appear in the FORM
?? ??? ?Audio Recording Chunk
?? ??? ?MIDI Data Chunk(s)
?? ??? ?Application Specific Chunks?? ??? ?Lowest precedence
?? ??? ?Common Chunk具有最高優先級,而Application Specific Chunk具有最低優先級。
?? ??? ?Common Chunk中的信息始終優先于任何其他塊中的沖突信息。Application Specific Chunk總是在與其他塊沖突時丟失。
?? ??? ?例如,通過查看塊層次結構,可以看到Instrument Chunk中的循環點優先于MIDI數據塊中發現的沖突循環點。
?? ??? ?應用程序負責將數據寫入較低優先級的塊,以確保更高優先級的塊相應地更新。
?? ?(15)FORM AIFC的示例?? ?
?? ??? ?請記住,塊可以在FORM AIFC中以任何順序出現
?? ??? ?示例列表:
?? ??? ?1.以22.25454 kHz采樣的8位單聲道聲音數據。聲音數據未壓縮。
?? ??? ?2.使用Macintosh Audio Compression&Expansion實用程序以22.25454 kHz采樣的8位單聲道聲音數據,壓縮3倍。
?? ??? ?3.以44.1kHz(CD質量)采樣的16位立體聲數據。聲音數據未壓縮。
?? ??? ?
?? ??? ?1)一個文件包含大約4.476秒的8位單聲道聲音數據,采樣頻率為22.25454 kHz。聲音數據未壓縮。
?? ??? ?2)一個文件,包含大約28.972秒的8位聲音數據,以22.25454 kHz采樣,并使用Macintosh音頻壓縮和擴展實用程序壓縮3倍。
?? ??? ??? ?注意:聲音加速器塊(Saxel)使用附錄D中定義的Saxels的初步版本。
?? ??? ?3)包含大約2.325秒的16位立體聲聲音數據的文件,采樣頻率為44.1kHz(CD質量)。聲音數據未壓縮。
?? ?(16)Compressed Audio Encoding Format
?? ??? ?1. ACE和Macintosh壓縮實用程序的編碼格式
?? ??? ?2. ACE和Macintosh壓縮聲音數據的標記
?? ??? ?3. ACE和Macintosh的Saxels壓縮聲音數據
?? ??? ?
?? ??? ?編碼格式:
?? ??? ?針對單聲道聲音數據示出了編碼格式。下面描述多通道壓縮音頻編碼的示例。以下的原始聲音數據是8位線性樣本。
?? ??? ?3:1 Macintosh音頻壓縮和擴展實用程序 ? Frame size = 2 bytes
?? ??? ?原始未壓縮單聲道聲音數據:
?? ??? ?Marker:
?? ??? ?0 ?? ??? ?1 ?? ??? ?2 ?? ??? ?3 ?? ? ? 4 ?? ?5 ?? ??? ?6 ?? ??? ?7 ?? ??? ?8 ?? ? ?9 ?? ?10
?? ??? ?8-bits 8-bits 8-bits 8-bits 8-bits 8-bits 8-bits 8-bits 8-bits 8-bits 8-bits
?? ??? ?3:1 Compressed Sound Data: 8-bits 8-bits 8-bits 8-bits
?? ??? ?......
?? ??? ?
?? ??? ?標記位置(參見標記塊部分)針對擴展(未壓縮)聲音數據。
?? ??? ?因此,必須進行計算以從壓縮數據流中的位置映射到未壓縮聲音數據中的目標位置。
未完...
參考:http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/AIFF/AIFF.html
?
總結
以上是生活随笔為你收集整理的AIFF-C压缩格式容器规范解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ubuntu18.04 未发现wifi驱
- 下一篇: 2021考研数学 高数第五章 定积分与反