bool HeartBeatPS1Seq::ReadEvent(void) { uint32_t beginOffset = curOffset; // in this format, end of track (FF 2F 00) comes without delta-time. // so handle that crazy sequence the first. if (curOffset + 3 <= rawfile->size()) { if (GetByte(curOffset) == 0xff && GetByte(curOffset + 1) == 0x2f && GetByte(curOffset + 2) == 0x00) { curOffset += 3; AddEndOfTrack(beginOffset, curOffset-beginOffset); return false; } } uint32_t delta = ReadVarLen(curOffset); if (curOffset >= rawfile->size()) return false; AddTime(delta); uint8_t status_byte = GetByte(curOffset++); if (status_byte <= 0x7F) // Running Status { status_byte = runningStatus; curOffset--; } else runningStatus = status_byte; channel = status_byte&0x0F; SetCurTrack(channel); switch (status_byte & 0xF0) { case 0x80 : //note off key = GetByte(curOffset++); vel = GetByte(curOffset++); AddNoteOff(beginOffset, curOffset-beginOffset, key); break; case 0x90 : //note event key = GetByte(curOffset++); vel = GetByte(curOffset++); if (vel > 0) //if the velocity is > 0, it's a note on AddNoteOn(beginOffset, curOffset-beginOffset, key, vel); else //otherwise it's a note off AddNoteOff(beginOffset, curOffset-beginOffset, key); break; case 0xA0 : AddUnknown(beginOffset, curOffset-beginOffset); return false; case 0xB0 : { uint8_t controlNum = GetByte(curOffset++); uint8_t value = GetByte(curOffset++); switch (controlNum) //control number { case 1: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Modulation", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 2: // identical to CC#11? AddGenericEvent(beginOffset, curOffset-beginOffset, L"Breath Controller?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 4: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Foot Controller?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 5: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Portamento Time?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 6 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"NRPN Data Entry", NULL, CLR_MISC); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 7 : //volume AddVol(beginOffset, curOffset-beginOffset, value); break; case 9: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Control 9", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 10 : //pan AddPan(beginOffset, curOffset-beginOffset, value); break; case 11 : //expression AddExpression(beginOffset, curOffset-beginOffset, value); break; case 20: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Control 20", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 21: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Control 21", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 22: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Control 22", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 23: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Control 23", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 32: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Bank LSB?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 52: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Control 52", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 53: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Control 53", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 54: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Control 54", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 55: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Control 55", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 56: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Control 56", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 64: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Hold 1?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 69: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Hold 2?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 71: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Resonance?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 72: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Release Time?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 73: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Attack Time?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 74: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Cut Off Frequency?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 75: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Decay Time?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 76: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Vibrato Rate?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 77: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Vibrato Depth?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 78: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Vibrato Delay?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 79: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Control 79", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 91: AddReverb(beginOffset, curOffset-beginOffset, value); break; case 92: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Tremolo Depth?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 98: switch (value) { case 20 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"NRPN 1 #20", NULL, CLR_MISC); break; case 30 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"NRPN 1 #30", NULL, CLR_MISC); break; default: AddGenericEvent(beginOffset, curOffset-beginOffset, L"NRPN 1", NULL, CLR_MISC); break; } if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 99 : //(0x63) nrpn msb switch (value) { case 20 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"Loop Start", NULL, CLR_LOOP); break; case 30 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"Loop End", NULL, CLR_LOOP); break; default: AddGenericEvent(beginOffset, curOffset-beginOffset, L"NRPN 2", NULL, CLR_MISC); break; } if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 121: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Reset All Controllers", NULL, CLR_MISC); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 126: AddGenericEvent(beginOffset, curOffset-beginOffset, L"MONO?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 127: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Poly?", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; default: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Control Event", NULL, CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; } } break; case 0xC0 : { uint8_t progNum = GetByte(curOffset++); AddProgramChange(beginOffset, curOffset-beginOffset, progNum); } break; case 0xD0 : AddUnknown(beginOffset, curOffset-beginOffset); return false; case 0xE0 : { uint8_t hi = GetByte(curOffset++); uint8_t lo = GetByte(curOffset++); AddPitchBendMidiFormat(beginOffset, curOffset-beginOffset, hi, lo); } break; case 0xF0 : { if (status_byte == 0xFF) { if (curOffset + 1 > rawfile->size()) return false; uint8_t metaNum = GetByte(curOffset++); uint32_t metaLen = ReadVarLen(curOffset); if (curOffset + metaLen > rawfile->size()) return false; switch (metaNum) { case 0x51 : AddTempo(beginOffset, curOffset+metaLen-beginOffset, (GetShortBE(curOffset) << 8) | GetByte(curOffset + 2)); curOffset += metaLen; break; case 0x58 : { uint8_t numer = GetByte(curOffset); uint8_t denom = GetByte(curOffset + 1); AddTimeSig(beginOffset, curOffset+metaLen-beginOffset, numer, 1<<denom, (uint8_t)GetPPQN()); curOffset += metaLen; break; } case 0x2F : // apparently not used, but just in case. AddEndOfTrack(beginOffset, curOffset+metaLen-beginOffset); curOffset += metaLen; return false; default : AddUnknown(beginOffset, curOffset+metaLen-beginOffset); curOffset += metaLen; break; } } else { AddUnknown(beginOffset, curOffset-beginOffset); return false; } } break; } return true; }
bool PS1Seq::ReadEvent(void) { uint32_t beginOffset = curOffset; uint32_t delta = ReadVarLen(curOffset); if (curOffset >= rawfile->size()) return false; AddTime(delta); uint8_t status_byte = GetByte(curOffset++); //if (status_byte == 0) //Jump Relative //{ // short relOffset = (short)GetShortBE(curOffset); // AddGenericEvent(beginOffset, 4, L"Jump Relative", NULL, BG_CLR_PINK); // curOffset += relOffset; // curOffset += 4; //skip the first 4 bytes (no idea) // SetPPQN(GetShortBE(curOffset)); // curOffset += 2; // AddTempo(curOffset, 3, GetWordBE(curOffset-1) & 0xFFFFFF); // curOffset += 3; // uint8_t numer = GetByte(curOffset++); // uint8_t denom = GetByte(curOffset++); // if (numer == 0 || numer > 32) //sanity check // return false; // AddTimeSig(curOffset-2, 2, numer, 1<<denom, GetPPQN()); // SetEventsOffset(offset() + 0x0F); //} // else if (status_byte <= 0x7F) // Running Status { if (status_byte == 0) // some games were ripped to PSF with the EndTrack event missing, so { if (GetWord(curOffset) == 0) //if we read a sequence of four 0 bytes, then just treat that return false; //as the end of the track } status_byte = runningStatus; curOffset--; } else runningStatus = status_byte; channel = status_byte&0x0F; SetCurTrack(channel); switch (status_byte & 0xF0) { case 0x90 : //note event key = GetByte(curOffset++); vel = GetByte(curOffset++); if (vel > 0) //if the velocity is > 0, it's a note on AddNoteOn(beginOffset, curOffset-beginOffset, key, vel); else //otherwise it's a note off AddNoteOff(beginOffset, curOffset-beginOffset, key); break; case 0xB0 : { uint8_t controlNum = GetByte(curOffset++); uint8_t value = GetByte(curOffset++); switch (controlNum) //control number { case 0 : //bank select AddGenericEvent(beginOffset, curOffset-beginOffset, L"Bank Select", L"", CLR_MISC); AddBankSelectNoItem(value); break; case 6 : //data entry AddGenericEvent(beginOffset, curOffset-beginOffset, L"NRPN Data Entry", L"", CLR_MISC); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 7 : //volume AddVol(beginOffset, curOffset-beginOffset, value); break; case 10 : //pan AddPan(beginOffset, curOffset-beginOffset, value); break; case 11 : //expression AddExpression(beginOffset, curOffset-beginOffset, value); break; case 64 : //damper (hold) AddSustainEvent(beginOffset, curOffset-beginOffset, value); break; case 91 : //reverb depth (_SsContExternal) AddReverb(beginOffset, curOffset-beginOffset, value); break; case 98 : //(0x62) NRPN 1 (LSB) switch (value) { case 20 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"NRPN 1 #20", L"", CLR_MISC); break; case 30 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"NRPN 1 #30", L"", CLR_MISC); break; default: AddGenericEvent(beginOffset, curOffset-beginOffset, L"NRPN 1", L"", CLR_MISC); break; } if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 99 : //(0x63) NRPN 2 (MSB) switch (value) { case 20 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"Loop Start", L"", CLR_LOOP); break; case 30 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"Loop End", L"", CLR_LOOP); break; default: AddGenericEvent(beginOffset, curOffset-beginOffset, L"NRPN 2", L"", CLR_MISC); break; } if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 100 : //(0x64) RPN 1 (LSB), no effect? AddGenericEvent(beginOffset, curOffset-beginOffset, L"RPN 1", L"", CLR_MISC); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 101 : //(0x65) RPN 2 (MSB), no effect? AddGenericEvent(beginOffset, curOffset-beginOffset, L"RPN 2", L"", CLR_MISC); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; case 121 : //reset all controllers AddGenericEvent(beginOffset, curOffset-beginOffset, L"Reset All Controllers", L"", CLR_MISC); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; default: AddGenericEvent(beginOffset, curOffset-beginOffset, L"Control Event", L"", CLR_UNKNOWN); if (VGMSeq::readMode == READMODE_CONVERT_TO_MIDI) { pMidiTrack->AddControllerEvent(channel, controlNum, value); } break; } } break; case 0xC0 : { uint8_t progNum = GetByte(curOffset++); AddProgramChange(beginOffset, curOffset-beginOffset, progNum); } break; case 0xE0 : { uint8_t hi = GetByte(curOffset++); uint8_t lo = GetByte(curOffset++); AddPitchBendMidiFormat(beginOffset, curOffset-beginOffset, hi, lo); } break; case 0xF0 : { if (status_byte == 0xFF) { switch (GetByte(curOffset++)) { case 0x51 : //tempo. This is different from SMF, where we'd expect a 51 then 03. Also, supports //a string of tempo events AddTempo(beginOffset, curOffset+3-beginOffset, (GetShortBE(curOffset) << 8) | GetByte(curOffset + 2)); curOffset += 3; break; case 0x2F : AddEndOfTrack(beginOffset, curOffset-beginOffset); return false; default : AddUnknown(beginOffset, curOffset-beginOffset, L"Meta Event"); return false; } } else { AddUnknown(beginOffset, curOffset-beginOffset); return false; } } break; default: AddUnknown(beginOffset, curOffset-beginOffset); return false; } return true; }
//-------------------------------------------------- //Revisions: // 2009. 6.17(Wed.) : Re-make by "Sound tester 774" in "内蔵音源をMIDI変換するスレ(in http://www.2ch.net)" // Add un-known command(op-code). //-------------------------------------------------- bool AkaoTrack::ReadEvent(void) { ULONG beginOffset = curOffset; BYTE status_byte = GetByte(curOffset++); int i, k; if (status_byte < 0x9A) //it's either a note-on message, a tie message, or a rest message { //looking at offset 8005E5C8 in the FFO FF2 exe for this delta time table code 4294967296 0x100000000/0xBA2E8BA3 = 1.374999... = 11/8 //0x68 after eq = 9 /*i = ((status_byte * 0xBA2E8BA3) & 0xFF00000000) >> 32; // emulating multu and mfhi instruction //i >>= 3; //srl 3 */ i = status_byte / 11; k = i*2; //sll 1 - aka multiply by 2 k += i; //addu $v0, $v1 k *= 4; //sll 2 - aka multiply by 4 k -= i; //subu $v0, $v1 k = status_byte - k; //subu $v0, $s1, $v0 //k now equals the table index value //relative key calculation found at 8005E6F8 in FFO FF2 exe if (status_byte < 0x83) // it's a note-on message { relative_key = status_byte / 11; base_key = octave*12; if (bNotePlaying) { AddNoteOffNoItem(prevKey); bNotePlaying = false; } //if (bAssociatedWithSSTable) // FindNoteInstrAssoc(hFile, base_key + relative_key); AddNoteOn(beginOffset, curOffset-beginOffset, base_key + relative_key, vel); bNotePlaying = true; AddTime(delta_time_table[k]); } else if (status_byte < 0x8F) //if it's between 0x83 and 0x8E it is a tie event { AddTime(delta_time_table[k]); if (loop_counter[loop_layer] == 0 && loop_layer == 0) //do this so we don't repeat this for every single time it loops AddGenericEvent(beginOffset, curOffset-beginOffset, L"Tie", NULL, CLR_TIE); } else //otherwise, it's between 0x8F and 0x99 and it's a rest message { if (bNotePlaying) { AddNoteOff(beginOffset, curOffset-beginOffset, prevKey); bNotePlaying = false; } AddRest(beginOffset, curOffset-beginOffset, delta_time_table[k]); } } else if ((status_byte >= 0xF0) && (status_byte <= 0xFB)) { relative_key = status_byte-0xF0; base_key = octave*12; if (bNotePlaying) { AddNoteOffNoItem(prevKey); bNotePlaying = false; } bNotePlaying = true; AddNoteOn(beginOffset, curOffset-beginOffset+1, base_key + relative_key, vel); AddTime(GetByte(curOffset++)); } else switch (status_byte) { case 0xA0 : // ----[ 2009. 6.12 change ]----- // AddUnknown(beginOffset, curOffset-beginOffset); // break; AddEndOfTrack(beginOffset, curOffset-beginOffset); return false; case 0xA1 : // change program to articulation number { ((AkaoSeq*)parentSeq)->bUsesIndividualArts = true; BYTE artNum = GetByte(curOffset++); BYTE progNum = ((AkaoSeq*)parentSeq)->instrset->aInstrs.size() + artNum; AddProgramChange(beginOffset, curOffset-beginOffset, progNum); } break; case 0xA2 : // set next note length [ticks] curOffset++; AddGenericEvent(beginOffset, curOffset-beginOffset, L"Next note length", NULL, CLR_CHANGESTATE); break; case 0xA3 : //set track volume vol = GetByte(curOffset++); //expression value AddVol(beginOffset, curOffset-beginOffset, vol); break; case 0xA4: // pitch slide half steps. (Portamento) { BYTE dur = GetByte(curOffset++); //first byte is duration of slide BYTE steps = GetByte(curOffset++); //second byte is number of halfsteps to slide... not sure if signed or not, only seen positive //AddPitchBendSlide( AddGenericEvent(beginOffset, curOffset-beginOffset, L"Portamento", NULL, CLR_PORTAMENTO); } break; case 0xA5 : //set octave octave = GetByte(curOffset++); AddSetOctave(beginOffset, curOffset-beginOffset, octave); break; case 0xA6 : //set octave + 1 AddIncrementOctave(beginOffset, curOffset-beginOffset); break; case 0xA7 : //set octave - 1 AddDecrementOctave(beginOffset, curOffset-beginOffset); break; case 0xA8 : //set expression (USED TO BE VELOCITY, may go back after testing, as this is messy) { //vel = GetByte(curOffset++); //vel = Convert7bitPercentVolValToStdMidiVal(vel); //I THINK THIS APPLIES, BUT NOT POSITIVE //AddGenericEvent(beginOffset, curOffset-beginOffset, L"Set Velocity", NULL, BG_CLR_CYAN); BYTE cExpression = GetByte(curOffset++); //// こっちのlog演算は要らない //// vel = Convert7bitPercentVolValToStdMidiVal(vel); //I THINK THIS APPLIES, BUT NOT POSITIVE vel = 127; //とりあえず 127 にしておく AddExpression(beginOffset, curOffset-beginOffset, cExpression); } break; case 0xA9 : //set Expression fade { BYTE dur = GetByte(curOffset++); BYTE targExpr = GetByte(curOffset++); //reads the target velocity value - the velocity value we are fading toward AddExpressionSlide(beginOffset, curOffset-beginOffset, dur, targExpr); } break; case 0xAA : //set pan { BYTE pan = GetByte(curOffset++); AddPan(beginOffset, curOffset-beginOffset, pan); } break; case 0xAB : //set pan fade { BYTE dur = GetByte(curOffset++); BYTE targPan = GetByte(curOffset++); //reads the target velocity value - the velocity value we are fading toward AddPanSlide(beginOffset, curOffset-beginOffset, dur, targPan); } break; case 0xAC : //unknown curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; /*AD = set attack AE = set decay AF = set sustain level B0 = AE then AF <CBongo> B1 = set sustain release B2 = set release B7 might be set A,D,S,R values all at once B3 appears to be "reset ADSR to the initial values from the instrument/sample data"*/ case 0xAD : curOffset++; AddGenericEvent(beginOffset, curOffset-beginOffset, L"ADSR", NULL, CLR_ADSR); break; case 0xAE : curOffset++; AddGenericEvent(beginOffset, curOffset-beginOffset, L"ADSR", NULL, CLR_ADSR); break; case 0xAF : curOffset++; AddGenericEvent(beginOffset, curOffset-beginOffset, L"ADSR", NULL, CLR_ADSR); break; case 0xB0 : curOffset++; curOffset++; AddGenericEvent(beginOffset, curOffset-beginOffset, L"ADSR", NULL, CLR_ADSR); break; case 0xB1 : curOffset++; AddGenericEvent(beginOffset, curOffset-beginOffset, L"ADSR", NULL, CLR_ADSR); break; case 0xB2 : curOffset++; AddGenericEvent(beginOffset, curOffset-beginOffset, L"ADSR", NULL, CLR_ADSR); break; case 0xB3 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"ADSR", NULL, CLR_ADSR); break; // // 0xB4 to 0xB7 LFO Pitch bend // 0xB8 to 0xBC LFO Expression // 0xBC to 0xBF LFO Panpot // case 0xB4 : //unknown curOffset += 3; AddGenericEvent(beginOffset, curOffset-beginOffset, L"LFO(Pitch bend) Length, cycle", NULL, CLR_LFO); break; case 0xB5 : curOffset++; AddGenericEvent(beginOffset, curOffset-beginOffset, L"LFO(Pitch bend) Depth", NULL, CLR_LFO); break; case 0xB6 : //unknown AddGenericEvent(beginOffset, curOffset-beginOffset, L"LFO(Pitch bend) off", NULL, CLR_LFO); break; case 0xB7 : curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0xB8 : //unknown curOffset += 3; AddGenericEvent(beginOffset, curOffset-beginOffset, L"LFO(Expression) Length, cycle", NULL, CLR_LFO); break; case 0xB9 : curOffset++; AddGenericEvent(beginOffset, curOffset-beginOffset, L"LFO(Expression) Depth", NULL, CLR_LFO); break; case 0xBA : //unknown AddGenericEvent(beginOffset, curOffset-beginOffset, L"LFO(Expression) off", NULL, CLR_LFO); break; case 0xBB : curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0xBC : //unknown curOffset += 2; AddGenericEvent(beginOffset, curOffset-beginOffset, L"LFO(Panpot) Length, cycle", NULL, CLR_LFO); break; case 0xBD : curOffset++; AddGenericEvent(beginOffset, curOffset-beginOffset, L"LFO(Panpot) Depth", NULL, CLR_LFO); break; case 0xBE : //unknown AddGenericEvent(beginOffset, curOffset-beginOffset, L"LFO(Panpot) off", NULL, CLR_LFO); break; case 0xBF : curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0xC0 : { char cTranspose = GetByte(curOffset++); AddTranspose(beginOffset, curOffset-beginOffset,cTranspose); } break; case 0xC1 : { BYTE cTranspose = GetByte(curOffset++); AddGenericEvent(beginOffset, curOffset-beginOffset, L"Transpose move", NULL, CLR_TRANSPOSE); } break; case 0xC2 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"Reverb On", NULL, CLR_REVERB); break; case 0xC3 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"Reverb Off", NULL, CLR_REVERB); break; case 0xC4 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"Noise On", NULL, CLR_UNKNOWN); break; case 0xC5 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"Noise Off", NULL, CLR_UNKNOWN); break; case 0xC6 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"FM Modulation On", NULL, CLR_UNKNOWN); break; case 0xC7 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"FM Modulation Off", NULL, CLR_UNKNOWN); break; case 0xC8 : // set loop begin marker AddGenericEvent(beginOffset, curOffset-beginOffset, L"Repeat Start", NULL, CLR_LOOP); loop_begin_layer++; loop_begin_loc[loop_begin_layer] = curOffset; //bInLoop = true; break; case 0xC9 : { BYTE value1 = GetByte(curOffset++); AddGenericEvent(beginOffset, curOffset-beginOffset, L"Repeat End", NULL, CLR_LOOP); if (loop_begin_layer == 0) //if loop_begin_layer == 0, then there was never a matching loop begin event! this is seen in ff9 402 and ff9 hunter's chance break; if (loopID[loop_layer] != curOffset) { loop_layer++; loopID[loop_layer] = curOffset; curOffset = loop_begin_loc[loop_begin_layer]; loop_counter[loop_layer] = value1-2; bInLoop = true; } else if (loop_counter[loop_layer] > 0) { loop_counter[loop_layer]--; curOffset = loop_begin_loc[loop_begin_layer]; //if (loop_counter[loop_layer] == 0 && loop_layer == 1) // bInLoop = false; } else { loopID[loop_layer]=0; loop_layer--; loop_begin_layer--; if (loop_layer == 0) bInLoop = false; } } break; case 0xCA : { BYTE value1 = 2; AddGenericEvent(beginOffset, curOffset-beginOffset, L"Repeat End", NULL, CLR_LOOP); if (loop_begin_layer == 0) break; if (loopID[loop_layer] != curOffset) { loop_layer++; loopID[loop_layer] = curOffset; curOffset = loop_begin_loc[loop_begin_layer]; loop_counter[loop_layer] = value1-2; bInLoop = true; } else if (loop_counter[loop_layer] > 0) { loop_counter[loop_layer]--; curOffset = loop_begin_loc[loop_begin_layer]; //if (loop_counter[loop_layer] == 0 && loop_layer == 1) // bInLoop = false; } else { loopID[loop_layer]=0; loop_layer--; loop_begin_layer--; if (loop_layer == 0) bInLoop = false; } } break; case 0xCC : AddGenericEvent(beginOffset, curOffset-beginOffset, L"Slur On", NULL, CLR_PORTAMENTO); break; case 0xCD : AddGenericEvent(beginOffset, curOffset-beginOffset, L"Slur Off", NULL, CLR_PORTAMENTO); break; case 0xD0 : AddNoteOff(beginOffset, curOffset-beginOffset, prevKey); break; case 0xD1 : // unknown AddGenericEvent(beginOffset, curOffset-beginOffset, L"Deactivate Notes?", NULL, CLR_UNKNOWN); break; case 0xD2 : curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0xD3 : curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0xD8 : //pitch bend { BYTE cValue = GetByte(curOffset++); //signed data byte. range of 1 octave (0x7F = +1 octave 0x80 = -1 octave) int fullValue = (int)(cValue * 64.503937007874015748031496062992); fullValue += 0x2000; BYTE lo = fullValue & 0x7F; BYTE hi = (fullValue & 0x3F80) >> 7; AddPitchBendMidiFormat(beginOffset, curOffset-beginOffset, lo, hi); } break; case 0xD9 : curOffset++; AddGenericEvent(beginOffset, curOffset-beginOffset, L"Pitch bend move", NULL, CLR_UNKNOWN); break; case 0xDA : curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0xDC : curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0xDD : curOffset += 2; AddGenericEvent(beginOffset, curOffset-beginOffset, L"LFO(Pitch bend) times", NULL, CLR_UNKNOWN); break; case 0xDE : curOffset += 2; AddGenericEvent(beginOffset, curOffset-beginOffset, L"LFO(Expression) times", NULL, CLR_UNKNOWN); break; case 0xDF : curOffset += 2; AddGenericEvent(beginOffset, curOffset-beginOffset, L"LFO(Panpot) times", NULL, CLR_UNKNOWN); break; case 0xE1 : curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0xE6 : curOffset += 2; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0xFC : //tie time //if (nVersion == VERSION_1 || nVersion == VERSION_2) // goto MetaEvent; //rest_time += pDoc->GetByte(j++); AddTime(GetByte(curOffset++)); AddGenericEvent(beginOffset, curOffset-beginOffset, L"Tie (custom)", NULL, CLR_TIE); break; case 0xFD : { if (bNotePlaying) { AddNoteOffNoItem(prevKey); bNotePlaying = false; } BYTE restTime = GetByte(curOffset++); AddRest(beginOffset, curOffset-beginOffset, restTime); } break; case 0xFE : //meta event //MetaEvent: switch (GetByte(curOffset++)) { case 0x00 : //tempo { BYTE value1 = GetByte(curOffset++); BYTE value2 = GetByte(curOffset++); double dValue1 = ((value2<<8) + value1)/218.4555555555555555555555555; //no clue how this magic number is properly derived AddTempoBPM(beginOffset, curOffset-beginOffset, dValue1); } break; case 0x01 : //tempo slide { BYTE value1 = GetByte(curOffset++); //NEED TO ADDRESS value 1 BYTE value2 = GetByte(curOffset++); //AddTempoSlide( //RecordMidiSetTempo(current_delta_time, value2); } break; case 0x02 : //reverb curOffset++; curOffset++; AddGenericEvent(beginOffset, curOffset-beginOffset, L"Reverb Level", NULL, CLR_REVERB); break; case 0x03 : //reverb curOffset++; curOffset++; AddGenericEvent(beginOffset, curOffset-beginOffset, L"Reverb Fade", NULL, CLR_REVERB); break; case 0x04 : //signals this track uses the drum kit AddProgramChange(beginOffset, curOffset-beginOffset, 127, L"Drum kit On"); //channel = 9; break; case 0x05 : //reverb AddGenericEvent(beginOffset, curOffset-beginOffset, L"Drum kit Off", NULL, CLR_UNKNOWN); break; case 0x06 : //Branch Relative { ULONG dest = (S16)GetShort(curOffset) + curOffset; curOffset += 2; ULONG eventLength = curOffset - beginOffset; bool bContinue = false; curOffset = dest; // Check the remaining area that will be processed by CPU-controlled jump. for (vector<ULONG>::iterator itAddr = vCondJumpAddr.begin(); itAddr != vCondJumpAddr.end(); ++itAddr) { if (!IsOffsetUsed(*itAddr)) { // There is an area not visited yet, VGMTrans must try to go there. bContinue = true; break; } } if (readMode == READMODE_FIND_DELTA_LENGTH) deltaLength = GetTime(); AddGenericEvent(beginOffset, eventLength, L"Dal Segno.(Loop)", NULL, CLR_LOOP); return bContinue; /*USHORT siValue = GetShort(pDoc, j); if (nScanMode == MODE_CONVERT_MIDI) //if we are converting the midi, the actually branch { if (seq_repeat_counter-- > 0) curOffset += siValue; else curOffset += 2; } else curOffset += 2; //otherwise, just skip over the relative branch offset*/ } break; case 0x07 : //Permanence Loop break with conditional. { BYTE condValue = GetByte(curOffset++); ULONG dest = (S16)GetShort(curOffset) + curOffset; curOffset += 2; ULONG eventLength = curOffset - beginOffset; // This event performs conditional jump if certain CPU variable matches to the condValue. // VGMTrans will simply try to parse all events as far as possible, instead. // (Test case: FF9 416 Final Battle) if (!IsOffsetUsed(beginOffset)) { // For the first time, VGMTrans just skips the event, // but remembers the destination address for future jump. vCondJumpAddr.push_back(dest); } else { // For the second time, VGMTrans jumps to the destination address. curOffset = dest; } AddGenericEvent(beginOffset, eventLength, L"Dal Segno (Loop) Break", NULL, CLR_LOOP); } break; case 0x09 : //Repeat break with conditional. curOffset++; curOffset++; curOffset++; AddGenericEvent(beginOffset, curOffset-beginOffset, L"Repeat Break", NULL, CLR_LOOP); break; //case 0x0E : //call subroutine //case 0x0F : //return from subroutine case 0x10 : //unknown curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0x14 : //program change { BYTE curProgram = GetByte(curOffset++); //if (!bAssociatedWithSSTable) // RecordMidiProgramChange(current_delta_time, curProgram, hFile); AddProgramChange(beginOffset, curOffset-beginOffset, curProgram); } break; case 0x15 : //Time Signature { BYTE denom = 4; curOffset++;//(192 / GetByte(curOffset++)); BYTE numer = GetByte(curOffset++); //AddTimeSig(beginOffset, curOffset-beginOffset, numer, denom, parentSeq->GetPPQN()); } break; case 0x16 : //Maker curOffset += 2; AddGenericEvent(beginOffset, curOffset-beginOffset, L"Maker", NULL, CLR_UNKNOWN); break; case 0x1C : //unknown curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; default : AddGenericEvent(beginOffset, curOffset-beginOffset, L"UNKNOWN META EVENT", NULL, CLR_UNRECOGNIZED); break; } break; default : AddGenericEvent(beginOffset, curOffset-beginOffset, L"UNKNOWN EVENT", NULL, CLR_UNRECOGNIZED); break; } return true; }