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; }
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; }