📄 mmf2ma1.cpp
字号:
if(get_byte(&data1) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
if(data1 != 0xf0){ // Exclusive Message埲奜偺応崌
}else{ // Exclusive Message偺応崌
#ifndef NO_MA1_EXCLUSIVE
if (get_byte(&exclusive_size) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_EXCLUSIVE;
if (read_exclusive(exclusive_size) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_EXCLUSIVE;
#else
// 愭摢偵偁傞僒僀僘傪撉傒崬傒丄偦偺僶僀僩悢僗僉僢僾偡傞丅
if (get_byte(&data2) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_EXCLUSIVE;
if (skip_data(data2) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_EXCLUSIVE;
#endif
}
}else{ // Note Messages(0x00 < data0 < 0xff)
channel_number = (data0 & 0xc0)>>6;
is_channel_used[channel_number] = true;
#ifdef _DEBUG
octave_block = (data0 & 0x30)>>4;
note_number = (data0 & 0x0f);
printf("IN: ch = %d\toctave = %d\tnote = %s\n",channel_number,octave_block,mmf_note_str_table[note_number]);
#endif
// Gate Time傪屇傃旘偽偡丅
if(get_byte(&data1) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
if((data1 & 0x80) != 0x00){
if(get_byte(&data2) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
if((data2 & 0x80) != 0x00){
if(get_byte(&data3) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
if((data3 & 0x80) != 0x00) return MMF2MA1_E_ERROR; // 0xxxxxxx偱側偗傟偽側傜側偄丅
}
}
}
}
// MA1偺僷乕僩斣崋偐傜MMF偺僩儔僢僋乛僠儍儞僱儖斣崋傊偺懳墳昞傪嶌惉偡傞丅
for(ch=0;ch<MMF_MAX_CH_PER_TRACK;++ch){
if(is_channel_used[ch] == true){
if(ch_num >= MA1_MAX_PART){ // MA1偱昞尰偱偒側偄壒悢偱偁傞丅
return MMF2MA1_E_ERROR;
}
m_mmf_track_number[ch_num] = (UINT8)track;
m_mmf_channel_number[ch_num] = (UINT8)ch;
#ifdef _DEBUG
printf("IN: track#%d, channel#%d = part%d\n",m_mmf_track_number[ch_num],m_mmf_channel_number[ch_num],ch_num);
#endif
++m_ma1_max_part;
++ch_num;
}
}
}
return MMF2MA1_R_SUCCESSFUL;
}
#ifndef NO_MA1_EXCLUSIVE
/********************************************************************
* Name: exclusive_voice_para_store
* Function: Exclusive撪偺壒怓僷儔儊乕僞傪弴彉傪擖傟懼偊偰
* 撪晹偱偺壒怓僷儔儊乕僞偺宍幃偵偟偰曐懚偡傞丅
* Voice斣崋偑摨偠壒怓偑暋悢屄偁偭偨応崌偵偼嵟弶偺愝掕偑桳岠丅
********************************************************************/
MMF2MA1_RESULT MMF2MA1_CLASS_CC exclusive_voice_para_store(
UINT8 address, // 0 <= address <= 7
UINT8 *exc_data // pointer to 15 byte data
){
UINT16 i;
assert(0 <= address && address <= 7);
if(m_ma1_exclusive.is_voice_set[address] == false){
m_ma1_exclusive.is_voice_set[address] = true;
m_ma1_exclusive.voice_para_bank[address] = exc_data[0]; // bank
m_ma1_exclusive.voice_para_program[address] = exc_data[1]; // program change
for(i=0;i<12;++i){ // 4byte(modulator) + 4byte(carrier) + 4byte(multiple)
m_ma1_exclusive.voice_para[address][i] = exc_data[i+3];
}
m_ma1_exclusive.voice_para[address][12] = exc_data[2];
}
return MMF2MA1_R_SUCCESSFUL;
}
/********************************************************************
* Name: read_exclusive
* Function:
* Assumption: FF and F0 which means start of EXCLUSIVE have been
* already read. Size of exclusive has been read ,too.
********************************************************************/
MMF2MA1_RESULT MMF2MA1_CLASS_CC read_exclusive(UINT32 exclusive_size){
UINT16 exclusive_count;
UINT8 address; // YAMAHA MA-1 parameter address
UINT8 exc_data[15];
UINT16 k;
UINT8 data2; // 擖椡偐傜撉傒崬傫偩僨乕僞傪曐懚偡傞侾僶僀僩偺僶僢僼傽
exclusive_count = 0;
if(exclusive_size >= 1){
if(get_byte(&data2) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_EXCLUSIVE;
++exclusive_count;
if(data2 == MMF_EXCLUSIVE_ID_YAMAHA){
if(get_byte(&data2) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_EXCLUSIVE;
++exclusive_count;
if(data2 == MMF_EXCLUSIVE_ID_MA1){
while(exclusive_count < exclusive_size){
if(get_byte(&address) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_EXCLUSIVE;
++exclusive_count;
if(address == 0x80){ // tempo
if(get_byte(&(exc_data[0])) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_EXCLUSIVE;
m_ma1_exclusive.is_tempo_defined = true;
m_ma1_exclusive.tempo = exc_data[0];
++exclusive_count;
break;
}else if(0 <= address && address <= 7){
for(k=0;k<15;++k){
if(get_byte(&(exc_data[k])) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_EXCLUSIVE;
++exclusive_count;
}
if(exclusive_voice_para_store(address,exc_data) < MMF2MA1_R_SUCCESSFUL){
return MMF2MA1_E_EXCLUSIVE;
}
break;
}else{
// Undefined address. ignore this exclusive
break;
}
}
}
}
}
if(exclusive_count != exclusive_size){
// 搑拞偱YAMAHA,MA-1偱側偄偙偲偑傢偐偭偨偲偒偵偙偙偱巆傝傪僗僉僢僾偡傞丅
// Exclusive偺嵟屻偺F7傕偙偙偱撉傒崬傑傟傞丅
if (skip_data(exclusive_size - exclusive_count) < MMF2MA1_R_SUCCESSFUL)
return MMF2MA1_E_EXCLUSIVE;
}
return MMF2MA1_R_SUCCESSFUL;
}
#endif
/********************************************************************
* Name: pass3
* Function: 壒堟偺専弌丄壒怓曄峏忣曬偺専弌
********************************************************************/
MMF2MA1_RESULT MMF2MA1_CLASS_CC pass3(void){
UINT8 part_number;
UINT8 data0; // 擖椡偐傜撉傒崬傫偩僨乕僞傪曐懚偡傞侾僶僀僩偺僶僢僼傽
UINT8 data1; // 擖椡偐傜撉傒崬傫偩僨乕僞傪曐懚偡傞侾僶僀僩偺僶僢僼傽
UINT8 data2; // 擖椡偐傜撉傒崬傫偩僨乕僞傪曐懚偡傞侾僶僀僩偺僶僢僼傽
UINT8 i,j;
UINT8 track;
UINT8 prev_track_number;
UINT8 channel_number; // MMF忋偱偺僠儍儞僱儖斣崋
UINT8 octave_block;
UINT8 note_number;
int count0; // 0x00傪楢懕偟偰撉傒崬傫偩夞悢
UINT8 sub_id;
UINT8 key;
SINT16 vn;
UINT32 duration;
UINT32 gatetime;
UINT32 pos_abs;
for(i=0;i<m_ma1_max_part;++i){
track = m_mmf_track_number[i];
// 慜夞偲摨偠僩儔僢僋側傜偡偱偵張棟偼嵪傫偱偄傞偺偱師偺僠儍儞僱儖偵恑傓丅
if(i != 0 && prev_track_number == track) continue;
// 僔乕働儞僗僨乕僞偺愭摢偵摢弌偟
if(seek_data(m_sequence_start_pos_abs[track]) == false) return MMF2MA1_E_ERROR;
for(j=0;j<MA1_MAX_PART;++j){
m_program_octave_shift[j] = 0;
}
// 僨乕僞偺僄儞僪丄傑偨偼0x00偺係楢懕偑専弌偝傟傟偽儖乕僾偐傜敳偗傞丅
pos_abs = 0;
while(m_input_pos_abs < m_sequence_start_pos_abs[track]+m_sequence_size[track]){
// Duration偺撉傒崬傒
count0 = 0;
if(get_duration_gatetime(&duration) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
if(duration == 0) ++count0;
pos_abs += duration*m_timebase_d[track];
// Event僨乕僞偺撉傒崬傒
if(get_byte(&data0) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
if(data0 == 0x00){
// 僐儞僩儘乕儖僨乕僞(Control Data)
++count0;
if(get_byte(&data1) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
if(data1 == 0x00){ // 僔乕働儞僗僨乕僞廔椆偺応崌
if(get_byte(&data2) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
if((data1 == 0x00) && (data2 == 0x00) && (count0 == 2)){ // 0x00 0x00 0x00 0x00
break; // while(1) 儖乕僾偐傜敳偗傞
}
// duration != 0x00 && event = 0x00 0x00 0x00偼枹掕媊偱偁傞丅
// duration == 0x00 && event = 0x00 0x00 !0x00偼枹掕媊偱偁傞丅
}else{ // 捠忢偺Control Data偺応崌
// Octave Shift, 壒怓曄峏(Program Change)偺専弌
channel_number = (data1 & 0xc0)>>6;
if((data1 & 0x30) == 0x30){ // Sub ID偁傝偺応崌
if(get_byte(&data2) < MMF2MA1_R_SUCCESSFUL) return MMF2MA1_E_GET_DATA;
// Octave Shift抣偲庢摼
sub_id = (data1 & 0x0f);
if(sub_id == 0x02){ // xxxx0010 偼 Octave Shift
if((data2 & 0x80) == 0){
assert(data2 == 0 || data2 == 1 || data2 == 2 || data2 == 3 || data2 == 4);
m_program_octave_shift[get_part_number(track,channel_number)] = data2*12;
}else{
//assert((data2 & 0x7f) == 1 || (data2 & 0x7f) == 2 || (data2 & 0x7f) == 3 || (data2 & 0x7f) == 4);
m_program_octave_shift[get_part_number(track,channel_number)] = -12*(data2 & 0x7f);
}
#ifdef _DEBUG
printf("IN: ch = %d\toctave_shift = %d\n",
channel_number,m_program_octave_shift[get_part_number(track,channel_number)]);
#endif
}else if(sub_id == 0x00){ // xxx0000 偼Program Change
vn = get_part_number(track,channel_number);
#ifdef _DEBUG
printf("IN: voice change: track = %d, channel = %d, voice = %d\n",track,channel_number,data2);
#endif
// 嵟弶偺壒怓曄峏偺傒桳岠
if(m_program_change[vn] == 0xff){ // 枹愝掕偺偲偒偼0xff偵側偭偰偄傞
assert(data2 <= 0x7f);
m_program_change[vn] = data2;
}
}else if(sub_id == 0x01){ // xxx0001 偼Block Change
vn = get_part_number(track,channel_number);
#ifdef _DEBUG
printf("IN: bank change: track = %d, channel = %d, voice = %d\n",track,channel_number,data2);
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -