SoundFont2技术协议 之 RIFF文件格式

1.RIFF结构

        RIFF(资源交换文件格式)是一种为多媒体资源文件开发的标记文件结构,在Microsoft Windows SDK多媒体程序参考资料中有详细描述。标记的文件结构非常有用是因为它有助于防止在文件定义随时间变化时出现兼容性问题。因为文件中的每一段数据都由标准头标识,所以不识别给定数据元素的应用程序可以跳过未知信息。

RIFF文件是由称为“chunk”的基本构建块构建的。在“C”语法中,定义了一个chunk:

typedef DWORD FOURCC;  //  Four-character code 
 
typedef struct {  
		FOURCC ckID;  //  A chunk ID identifies the type of data within the chunk.  
		DWORD ckSize;  //  The size of the chunk data in bytes, excluding any pad byte.  
		BYTE  ckDATA[ckSize]; //  The actual data plus a pad byte if req’d to word align. 
}; 

两种类型的块,“RIFF”和“LIST”块可以包含称为子块的嵌套块作为其数据。

RIFF文件中块和子块的排序要求没有很好地记录在RIFF文件格式中。在SoundFont 2.0中,信息块中子块的顺序是任意的,但是为了一致性,建议按照本文中的说明对子块进行排序。所有其他块和子块的顺序都是严格定义的,必须按照本文档中的说明进行维护

2.SoundFont2 块和子块

一个与SoundFont2兼容的RIFF文件包含三个块:
一个INFO-list 列表块(INFO),其中包含描述该文件及其历史和预期用途的许多必需和可选子块;
一个sdta-list 列表块(SDTA),其中包含一个子块,其中包含任何引用的数字音频样本;
以及一个 pdta-list 列表块(PDTA),其中包含九个子块,其中定义数字音频数据的清晰度。
SoundFont2标准允许信息列表块中的子块以任意顺序出现。但是,这三个块的顺序以及PDTA列表块中子块的顺序是固定的。
SoundFont2规范要求实现忽略信息列表块中的未知子块。但是,请注意,在规范中定义这些子块之前,包含其他信息列表子块将阻止文件符合SoundFont标准。


3.RIFF结构中的冗余和错误处理

RIFF文件结构包含有关文件长度和块和子块长度的冗余信息。这一事实使SoundFont兼容文件的任何读卡器都可以确定文件是否因数据丢失而损坏。

如果检测到任何此类丢失,则SoundFont兼容文件被称为“结构不健全”,通常应予以拒绝。与SoundFont兼容的软件开发人员可以生成实用程序,从结构上不健全的文件中恢复数据,在用户帮助下或在没有用户帮助的情况下生成正确且结构上健全的SoundFont 2兼容文件。


4.  SoundFont 2 RIFF 文件格式 Level 0 

<SFBK-form> -> RIFF (‘sfbk’ ; RIFF form header   
                     {    
                        <INFO-list> ; Supplemental Information    
                        <sdta-list> ; The Sample Binary Data    
                        <pdta-list> ; The Preset, Instrument, and Sample Header data   
                     }   
                    ) 


5. SoundFont 2 RIFF 文件格式 Level 1 

<INFO-list> -> LIST (‘INFO’   
                     {    
                        <ifil-ck> ; Refers to the version of the Sound Font RIFF file 
                        <isng-ck> ; Refers to the target Sound Engine    
                        <INAM-ck> ; Refers to the Sound Font Bank Name    
                        [<irom-ck>] ; Refers to the Sound ROM Name    
                        [<iver-ck>] ; Refers to the Sound ROM Version    
                        [<ICRD-ck>] ; Refers to the Date of Creation of the Bank    
                        [<IENG-ck>] ; Sound Designers and Engineers for the Bank    
                        [<IPRD-ck>] ; Product for which the Bank was intended    
                        [<ICOP-ck>] ; Contains any Copyright message    
                        [<ICMT-ck>] ; Contains any Comments on the Bank    
                        [<ISFT-ck>] ; The SoundFont tools used to create and alter the bank   
                     }   
                    ) 
 
<sdta-ck> -> LIST (‘sdta’   
                     {    
                        [<smpl-ck>] ; The Digital Audio Samples for the upper 16 bits   
                     }   
                     {    
                        [<sm24-ck>] ; The Digital Audio Samples for the lower 8 bits   
                     } 
                ) 
 
<pdta-ck> -> LIST (‘pdta’   
                     {    
                     <phdr-ck> ; The Preset Headers    
                     <pbag-ck> ; The Preset Index list    
                     <pmod-ck> ; The Preset Modulator list    
                     <pgen-ck> ; The Preset Generator list    
                     <inst-ck> ; The Instrument Names and Indices    
                     <ibag-ck> ; The Instrument Index list    
                     <imod-ck> ; The Instrument Modulator list    
                     <igen-ck> ; The Instrument Generator list    
                     <shdr-ck> ; The Sample Headers   
                     }   
                ) 


 
6. SoundFont 2 RIFF 文件格式 Level 2 

<ifil-ck> -> ifil(<iver-rec>) ; e.g. 2.01 
<isng-ck> -> isng(szSoundEngine:ZSTR) ; e.g. “EMU8000” 
<irom-ck> -> irom(szROM:ZSTR) ; e.g. “1MGM” 
<iver-ck> -> iver(<iver-rec>) ; e.g. 2.08 
<INAM-ck> -> INAM(szName:ZSTR) ; e.g. “General MIDI” 
<ICRD-ck> -> ICRD(szDate:ZSTR) ; e.g. “July 15, 1997” 
<IENG-ck> -> IENG(szName:ZSTR) ; e.g. “John Q. Sounddesigner” 
<IPRD-ck> -> IPRD(szProduct:ZSTR) ; e.g. “SBAWE64 Gold” 
<ICOP-ck> -> ICOP(szCopyright:ZSTR) ; e.g. “Copyright (c) 1997 E-mu Systems, Inc.” 
<ICMT-ck> -> ICMT(szComment:ZSTR) ; e.g. “This is a comment” 
<ISTF-ck> -> ISFT(szTools:ZSTR) ; e.g. “:Preditor 2.00a:Vienna SF Studio 2.0:” 
 
<smpl-ck> -> smpl(<sample:SHORT>) ; 16 bit Linearly Coded Digital Audio Data 
 
<phdr-ck> -> phdr(<phdr-rec>) 
 
<pbag-ck> -> pbag(<pbag-rec>) 
<pmod-ck> -> pmod(<pmod-rec>) 
<pgen-ck> -> pgen(<pgen-rec>) 
<inst-ck> -> inst (<inst -rec>) 
<ibag-ck> -> ibag(<ibag-rec>) 
<imod-ck> -> imod(<imod-rec>) 
<igen-ck> -> igen(<igen-rec>) 
<shdr-ck> -> shdr(<shdr-rec>) 


7. SoundFont 2 RIFF 文件格式 Level 3 

<iver-rec> -> struct sfVersionTag  
    {  
    WORD wMajor;  
    WORD wMinor;  
    }; 
 
<phdr-rec> -> struct sfPresetHeader  
    {  
    CHAR achPresetName[20];  
    WORD wPreset;  
    WORD wBank;  
    WORD wPresetBagNdx;  
    DWORD dwLibrary;  
    DWORD dwGenre;  
    DWORD dwMorphology;  
    }; 
 
<pbag-rec> -> struct sfPresetBag  
    {  
    WORD wGenNdx;  
    WORD wModNdx;  
    }; 
 
<pmod-rec> -> struct sfModList  
    {  
    SFModulator sfModSrcOper;  
    SFGenerator sfModDestOper;  
    SHORT modAmount;  
    SFModulator sfModAmtSrcOper;  
    SFTransform sfModTransOper;  
    }; 
 
<pgen-rec> -> struct sfGenList  
    {  
    SFGenerator sfGenOper;  
    genAmountType genAmount;  
    }; 
 
<inst-rec> -> struct sfInst  
    {  
    CHAR achInstName[20];  
    WORD wInstBagNdx;  
    }; 

 
 
<ibag-rec> -> struct sfInstBag  
    {  
    WORD wInstGenNdx;  
    WORD wInstModNdx;  
    }; 
 
<imod-rec> -> struct sfInstModList  
    {  
    SFModulator sfModSrcOper;  
    SFGenerator sfModDestOper;  
    SHORT modAmount;  
    SFModulator sfModAmtSrcOper;  
    SFTransform sfModTransOper;  
    }; 
 
<igen-rec> -> struct sfInstGenList  
    {  
    SFGenerator sfGenOper;  
    genAmountType genAmount;  
    }; 
 
<shdr-rec> -> struct sfSample  
    {  CHAR achSampleName[20];  
    DWORD dwStart;  
    DWORD dwEnd;  
    DWORD dwStartloop;  
    DWORD dwEndloop;  
    DWORD dwSampleRate;  
    BYTE byOriginalKey;  
    CHAR chCorrection;  
    WORD wSampleLink;  
    SFSampleLink sfSampleType;  
    }; 

 

8. SoundFont 2 RIFF 文件格式类型定义

 
 sfModulator, sfGenerator和sfTransform类型都是枚举类型,其值在后面的章节中定义。
 genAmountType 是一个联合,它允许有符号16位、无符号16位和两个无符号8位字段:

typedef struct  
    {  
    BYTE byLo;  
    BYTE byHi;  
    } rangesType; 
     
typedef union  
    {  
    rangesType ranges;  
    SHORT shAmount;  
    WORD wAmount; 
    } genAmountType; 


 SFSampleLink 是一种枚举类型,它描述了采样的类型(单声道、左立体声等)以及采样是位于RAM还是ROM内存中:

typedef enum  
    {  
    monoSample = 1,  
    rightSample = 2,  
    leftSample = 4,  
    linkedSample = 8,  
    RomMonoSample = 0x8001,  
    RomRightSample = 0x8002,  
    RomLeftSample = 0x8004,  
    RomLinkedSample = 0x8008  
    } SFSampleLink; 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Android中使用.sf2音色库播放midi文件,您可以使用Android自带的Midi API和SoundFont文件格式。以下是一个简单的示例代码,可以帮助您了解如何在Android应用程序中实现这个功能: ``` import android.media.midi.MidiDevice; import android.media.midi.MidiDeviceInfo; import android.media.midi.MidiManager; import android.media.midi.MidiOutputPort; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import java.io.IOException; public class MainActivity extends AppCompatActivity { private MidiManager midiManager; private MidiDevice device; private MidiOutputPort outputPort; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); midiManager = (MidiManager) getSystemService(MIDI_SERVICE); // 查找可用的MIDI设备 MidiDeviceInfo[] infos = midiManager.getDevices(); if (infos.length > 0) { device = midiManager.openDevice(infos[0], null); if (device != null) { outputPort = device.openOutputPort(0); } } // 播放midi文件 if (outputPort != null) { try { // 加载SoundFont文件 SoundFont soundFont = new SoundFont(getResources().openRawResource(R.raw.soundfont)); soundFont.load(); // 创建一个MidiPlayer MidiPlayer player = new MidiPlayer(outputPort, soundFont); // 播放midi文件 player.play(getResources().openRawResource(R.raw.midi_file)); } catch (IOException e) { e.printStackTrace(); } } } @Override protected void onDestroy() { super.onDestroy(); // 关闭Midi设备和输出端口 if (outputPort != null) { outputPort.close(); } if (device != null) { device.close(); } } } ``` 请注意,上面的代码仅供参考,您需要根据您的具体需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值