==================================使用说明=============================================== Readme: There are 2 midi music inside. 1. You can select one by masking the other( see below) in dobblebuffering.c. Then compile this prj. //char *midi_file = (char *)(0x2200000 + .....); //const U32 midi_file_end = 0x2200000+ .....; //#define DELAY_TIME 4000 char *midi_file = (char *)(0x2200000 + ......); const U32 midi_file_end = 0x2200000+.....; #define DELAY_TIME 5500 更改MIDI文件的首尾地址和延时 更改m_ch_instr[] 定位乐器表 2. From VIDE->TOOLS->Sdownload, select com1, press connect. Select *.dmp. Key in downlaod address of 0x2200000, then downlaod. After that quit it. 3. In VIDE, press debugger. choose 38400, com1, load. Then run. You can hear midi music. Remark: *.dmp includes piano wave table and it has Grand_piano just C3 C4 C5 tone. Midi file is also included in *.dmp. XGAL1.txt and 1897a.txt are midi file. *.txt includes address of each file in *.dmp. ======================================================================================== VG2有<4M的波表空间,采样都为一致如S16位44100(大),11025... copy波表到TMEM的音频空间 ============================================= 播放一个音时:填充地址,频率,长度,时间,模式,音量。 typedef struct tagDgSndChannel { // Software Registers U8 MidiChannel, Note; U32 Velocity; // Hardware Channel Register S32 CurSAddr; // 22.10 S32 dSAddr; // 6.10 S32 dLoop, LoopEnd, LoopBegin; // 22 U8 LoopDir; // 1 S32 EnvVol; // S.7.16 U8 EnvStage; // 4 S16 LChnVol, RChnVol; // 7 U8 Mode; // 7 S32 EnvRate[4]; // S.0.16 U8 EnvTarget[4]; // 7 } _DGSNDCHANNEL; 播放完后有中断,记录CHANNEL和下一个播放的TONE,做一个数组SIZE=32*5=160 (present_note, freg_number,CHANNEL,NEXT_TONE,vol),及时更新。播完清除。 MIDI3完成 是双音包罗的,再播放包罗的余音,用NOTE ON / OFF来控制时间长短。 ================================== 用一定时器产生***MS的中断,设计一个时钟。用TIMER0 节拍到了就播放一个音。或停一个音。 MIDI4完成 ================================== 读MIDI TXT文件分析 做一个结构树组。 typedef struct MIDI_TONE { U16 md_time; //开始的时间 U8 onoff; //开,关 U8 md_ch; U8 md_note_number; U8 md_volume; U32 midi_add; // a pointer of sound data that must be in VR0 Memory. U32 midi_freq; // frequency of data U32 midi_len; // data length U8 midi_mode; // play mode U8 VG_channel; // It'll be set by playmidi } _MIDI_TONE; 构成32个循环队列,有头尾指针。 先读MIDI文件,先添1个。 MIDI5 finished 播放一个,补上一个。移动指针。 ================================== 播放: 时间 == md_time,如为ON 开始播放。 时间 == md_time,如为Off 停止播放,要向回找CH和NOTE相等的,把CH NOTEOFF。 ================================== MIDI17改用WIN的GM.DLS波表实验 首先是吉他OK 将波表用Miles Sound Tools抽取出WAV和RAW 用Audio Compositor分析SAMPLE RATE=22050,LOOP S 和LOOP E 波表为10.DMP,10_a.dmp 10_b.dmp ----------------------- 调试方法:在MAIN() if(PlayMidi(midiaddress, midiloopbegin, midi_note[md_temp_1][frequency_number], midilength, midivol, mode)==vgFALSE) break;// erro设置BP 在MIDI_1.c中的函数midi_read() vgSndStopChannel(midi_tone[md_f_p].VG_channel); //CLOSE CH 设置BP 程序停下后检查:md_r_p, md_f_p , midi_tone[md_r_p]的值 RELEASE ========================= MIDI18测试弦乐,大小提琴,用11.DMP波表,11_a.dmp,11_b.dmp Release ========================= =========================