📄 mmf2ma1.cpp
字号:
if((ret_val=pass2()) < MMF2MA1_R_SUCCESSFUL) return ret_val;
// 壒堟偺専弌丄壒怓曄峏忣曬偺専弌
if((ret_val=pass3()) < MMF2MA1_R_SUCCESSFUL) return ret_val;
// pass3偱摼傜傟偨壒堟傪傕偲偵曄姺壜擻偐偳偆偐敾抐
if(check_note_range() == false){
return MMF2MA1_E_NOTE_RANGE;
}
// 暘夝擻偺挷嵏
if((ret_val=pass4()) < MMF2MA1_R_SUCCESSFUL) return ret_val;
// MA1偱偺僥儞億丄暘夝擻偺寛掕
if(tempo_time_base_decision() < MMF2MA1_R_SUCCESSFUL)
return MMF2MA1_E_ERROR;
// MA1僼僅乕儅僢僩僨乕僞偺僿僢僟晹暘(妝晥僨乕僞偺慜亖僐儞僩儘乕儖傑偱)
// 傪弌椡偡傞丅
if(ma1_header_output() < MMF2MA1_R_SUCCESSFUL)
return MMF2MA1_E_ERROR;
//僔乕働儞僗僨乕僞曄姺幚峴
if((ret_val=pass5()) < MMF2MA1_R_SUCCESSFUL) return ret_val;
// MA1僼僅乕儅僢僩僨乕僞偺僔乕働儞僗僨乕僞廔椆俬俢傪弌椡偡傞丅
if(ma1_tail_output() < MMF2MA1_R_SUCCESSFUL)
return MMF2MA1_E_ERROR;
#if OCTAVE_RANGE_OVER_TYPE == 1
if(m_warning_note_removed_by_range == true){
return MMF2MA1_W_NOTE_REMOVED_BY_RANGE;
}else{
return MMF2MA1_R_SUCCESSFUL;
}
#else
return MMF2MA1_R_SUCCESSFUL;
#endif
}
/********************************************************************
* Name: crc_check
* Function: check CRC
********************************************************************/
MMF2MA1_RESULT MMF2MA1_CLASS_CC crc_check(void){
UINT8 data0; // 擖椡偐傜撉傒崬傫偩僨乕僞傪曐懚偡傞侾僶僀僩偺僶僢僼傽
UINT8 id[4]; // Chunk ID曐懚梡
UINT32 size; // Chunk Size曐懚梡
UINT16 crc;
UINT16 res; // current residual
UINT16 res1; // previous residual
UINT16 res2; // previous previous residual
// 僨乕僞撉傒崬傒埵抲傪愭摢偵栠偡丅
if(seek_data(0) == false) return MMF2MA1_E_ERROR;
// 慡懱僠儍儞僋偺専弌
if(get_chunk_head(id,&size) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_CHUNK_HEAD;
if(memcmp(id,TOPLEVEL_CHUNK_ID,4) != 0) return MMF2MA1_E_ERROR;
m_toplevel_body_size = size;
// Initialize: 僨乕僞撉傒崬傒埵抲傪愭摢偵栠偡丅
if(seek_data(0) == false) return MMF2MA1_E_ERROR;
res = 0xFFFFU;
res1 = 0xFFFFU;
res2 = 0xFFFFU;
crc = 0;
//
while(m_input_pos_abs < m_toplevel_body_size + 8){ // 僼傽僀儖偺廔椆偵側傞傑偱孞傝曉偡丅俉偼Chunk Head偺俉僶僀僩
if(get_byte(&data0) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
res2 = res1;
res1 = res;
res = (res << 8) ^ CRC_table[(UINT8)(res >> 8) ^ data0];
crc = (crc << 8) | data0;
}
// Compare CRC
if(crc != (~res2 & 0xFFFFU)) return MMF2MA1_E_CRC;
#if OCTAVE_RANGE_OVER_TYPE == 1
if(m_warning_note_removed_by_range == true){
return MMF2MA1_W_NOTE_REMOVED_BY_RANGE;
}else{
return MMF2MA1_R_SUCCESSFUL;
}
#else
return MMF2MA1_R_SUCCESSFUL;
#endif
}
/********************************************************************
* Name: pass1
* Function: 僩儔僢僋僠儍儞僋偺専弌
********************************************************************/
MMF2MA1_RESULT MMF2MA1_CLASS_CC pass1(void){
UINT8 data0; // 擖椡偐傜撉傒崬傫偩僨乕僞傪曐懚偡傞侾僶僀僩偺僶僢僼傽
UINT8 data1; // 擖椡偐傜撉傒崬傫偩僨乕僞傪曐懚偡傞侾僶僀僩偺僶僢僼傽
UINT8 id[4]; // Chunk ID曐懚梡
UINT32 size; // Chunk Size曐懚梡
UINT8 track_number;
UINT32 mtr_chunk_size;
UINT32 count_in_mtr;
UINT32 count_in_setup;
UINT32 count_in_mspi;
#ifndef NO_MA1_EXCLUSIVE
UINT8 exclusive_size;
#endif
UINT8 c0,c1,c2;
int i;
// 僨乕僞撉傒崬傒埵抲傪愭摢偵栠偡丅
if(seek_data(0) == false) return MMF2MA1_E_ERROR;
////////////////////////////////////
// MIDI/ FM Track Chunk傑偱偺憗憲傝
////////////////////////////////////
// 慡懱僠儍儞僋偺専弌
if(get_chunk_head(id,&size) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_CHUNK_HEAD;
if(memcmp(id,TOPLEVEL_CHUNK_ID,4) != 0) return MMF2MA1_E_ERROR;
m_toplevel_body_size = size;
// MIDI/ FM TrackChunk偺専弌
while(m_input_pos_abs + 2 < m_toplevel_body_size + 8){ // 僼傽僀儖偺廔椆偵側傞傑偱孞傝曉偡丅俀偼CRC偺俀僶僀僩丄俉偼Chunk Head偺俉僶僀僩
while(1){ // MIDI/FM chunk偑尒偮偐傟偽儖乕僾偐傜敳偗傞丅
if (get_chunk_head(id,&size) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_CHUNK_HEAD;
if (memcmp(id,MIDI_FM_CHUNK_ID,3) == 0) break;
if (skip_data(size)< MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_ERROR;
}
track_number = id[3]; // id[3] is the track number.
if(track_number >= m_max_track_number){
// Ignore this track
if (skip_data(size)< MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_ERROR;
continue;
}
mtr_chunk_size = size;
/////////////////////////////////////////////////////
// M1 & M2: Format Type, Sequence Type偺撉傒崬傒亄専嵏
/////////////////////////////////////////////////////
// Format Type撉傒崬傒丄専嵏
// 尰忬偱偼Handy Phone Standard梡僼僅乕儅僢僩偺傒懳墳丅
if(get_byte(&data0) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
if(data0 != MMF_FORMAT_TYPE_HANDY_PHONE_STANDARD)
return MMF2MA1_E_FORMAT_TYPE;
// Sequence Type撉傒崬傒丄専嵏
// 尰忬偱偼Stream Sequence偺傒偵懳墳丅
if(get_byte(&data0) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
if((m_sequence_type[track_number] = data0) != MMF_SEQUENCE_TYPE_STREAM_SEQUENCE)
return MMF2MA1_E_SEQUENCE_TYPE;
////////////////////
// TimeBase撉傒崬傒
////////////////////
// TimeBase_D
if(get_byte(&data0) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
if(data0 >= 0x20) return MMF2MA1_E_TIMEBASE;
if((m_timebase_d[track_number]=Timebase_table[data0]) == 0) return MMF2MA1_E_TIMEBASE;
// TimeBase_G
if(get_byte(&data0) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
if(data0 >= 0x20) return MMF2MA1_E_TIMEBASE;
if((m_timebase_g[track_number]=Timebase_table[data0]) == 0) return MMF2MA1_E_TIMEBASE;
//////////////////////////
// Channel Status撉傒崬傒
//////////////////////////
if(get_byte(&data0) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
m_channel_status[track_number][0] = data0;
if(get_byte(&data0) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
m_channel_status[track_number][1] = data0;
count_in_mtr = 6;
//////////////////////////////
// Sequence Data Chunk偺専弌
//////////////////////////////
while(count_in_mtr < mtr_chunk_size){
if (get_chunk_head(id,&size) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_CHUNK_HEAD;
if (memcmp(id,SEQUENCE_CHUNK_ID,4) == 0){
// 屻偱丄僔乕働儞僗僨乕僞偺傒傪撉傒崬傓偲偒偵巊偆偨傔丄埵抲偲僒僀僘傪婰榐偡傞丅
m_sequence_start_pos_abs[track_number] = m_input_pos_abs;
m_sequence_size[track_number] = size;
// Sequence Data偺body傪撉傒旘偽偡丅
if (skip_data(size) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_ERROR;
}else if (memcmp(id,SEEK_PHRASE_CHUNK_ID,4) == 0){
// Sequence type == 0x00(Stream sequence) 傪壖掕丅
// Sebsequence偁傝偼婛偵偼偠偐傟偰偄傞丅
count_in_mspi = 0;
while(count_in_mspi < size){
if(count_in_mspi + 2 < size){
if(get_byte(&c0) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
if(get_byte(&c1) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
if(get_byte(&c2) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
count_in_mspi += 3;
if(c0 == 's'){
if(c1 == 't'){
if(count_in_mspi + 3 < size){
m_play_pos_info[track_number].start_byte = 0;
for(i=0;i<4;++i){
if(get_byte(&data0) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
m_play_pos_info[track_number].start_byte = m_play_pos_info[track_number].start_byte << 8;
m_play_pos_info[track_number].start_byte |= data0;
}
m_play_pos_info[track_number].is_start_defined = true;
count_in_mspi += 4;
}
}else if(c1 == 'p'){
if(count_in_mspi + 3 < size){
m_play_pos_info[track_number].stop_byte = 0;
for(i=0;i<4;++i){
if(get_byte(&data0) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
m_play_pos_info[track_number].stop_byte = m_play_pos_info[track_number].stop_byte << 8;
m_play_pos_info[track_number].stop_byte |= data0;
}
m_play_pos_info[track_number].is_stop_defined = true;
count_in_mspi += 4;
}
}
}else if(c0 == 'P'){
if(c1 >= 'A' && c1 <= 'z'){
c1 -= 'A';
if(count_in_mspi + 7 < size){
m_phrase_list[track_number][c1].start_byte = 0;
for(i=0;i<4;++i){
if(get_byte(&data0) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
m_phrase_list[track_number][c1].start_byte = m_phrase_list[track_number][c1].start_byte << 8;
m_phrase_list[track_number][c1].start_byte |= data0;
}
m_phrase_list[track_number][c1].is_start_defined = true;
count_in_mspi += 4;
m_phrase_list[track_number][c1].stop_byte = 0;
for(i=0;i<4;++i){
if(get_byte(&data0) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
m_phrase_list[track_number][c1].stop_byte = m_phrase_list[track_number][c1].stop_byte << 8;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -