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 TriAcePS1Track::ReadEvent(void) { uint32_t beginOffset = curOffset; uint8_t status_byte = GetByte(curOffset++); uint8_t event_dur = 0; //0-0x7F is a note event if (status_byte <= 0x7F) { event_dur = GetByte(curOffset++); //Delta time from "Note on" to "Next command(op-code)". uint8_t note_dur; uint8_t velocity; if (!impliedNoteDur) note_dur = GetByte(curOffset++); //Delta time from "Note on" to "Note off". else note_dur = impliedNoteDur; if (!impliedVelocity) velocity = GetByte(curOffset++); else velocity = impliedVelocity; AddNoteByDur_Extend(beginOffset, curOffset-beginOffset, status_byte, velocity, note_dur); } else switch (status_byte) { case 0x80 : AddGenericEvent(beginOffset, curOffset-beginOffset, L"Score Pattern End", NULL, CLR_TRACKEND); return false; case 0x81 : //unknown event_dur = GetByte(curOffset++); curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0x82 : //unknown event_dur = GetByte(curOffset++); curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0x83 : //program change { event_dur = GetByte(curOffset++); uint8_t progNum = GetByte(curOffset++); uint8_t bankNum = GetByte(curOffset++); //ATLTRACE("PROGRAM CHANGE ProgNum: %X BankNum: %X", progNum, bankNum); uint8_t bank = (bankNum*2) + ((progNum > 0x7F) ? 1 : 0); if (progNum > 0x7F) progNum -= 0x80; //ATLTRACE(" SELECTING: prog %X bank %X\n", progNum, bank); AddBankSelectNoItem(bank); AddProgramChange(beginOffset, curOffset-beginOffset, progNum); } break; case 0x84 : //pitch bend { event_dur = GetByte(curOffset++); short bend = ((char)GetByte(curOffset++)) << 7; AddPitchBend(beginOffset, curOffset-beginOffset, bend); } break; case 0x85 : //volume { event_dur = GetByte(curOffset++); uint8_t val = GetByte(curOffset++); AddVol(beginOffset, curOffset-beginOffset, val); } break; case 0x86 : //expression { event_dur = GetByte(curOffset++); uint8_t val = GetByte(curOffset++); AddExpression(beginOffset, curOffset-beginOffset, val); } break; case 0x87 : //pan { event_dur = GetByte(curOffset++); uint8_t pan = GetByte(curOffset++); AddPan(beginOffset, curOffset-beginOffset, pan); } break; case 0x88 : //unknown event_dur = GetByte(curOffset++); curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0x89 : //damper pedal { event_dur = GetByte(curOffset++); uint8_t val = GetByte(curOffset++); AddSustainEvent(beginOffset, curOffset-beginOffset, val); } break; case 0x8A : //unknown (tempo?) { event_dur = GetByte(curOffset++); uint8_t val = GetByte(curOffset++); AddUnknown(beginOffset, curOffset-beginOffset, L"Unknown Event (tempo?)"); } break; case 0x8D : //Dal Segno: start point AddGenericEvent(beginOffset, curOffset-beginOffset, L"Dal Segno: start point", NULL, CLR_UNKNOWN); break; case 0x8E : //Dal Segno: end point curOffset++; AddGenericEvent(beginOffset, curOffset-beginOffset, L"Dal Segno: end point", NULL, CLR_UNKNOWN); break; case 0x8F : //rest { uint8_t rest = GetByte(curOffset++); AddRest(beginOffset, curOffset-beginOffset, rest); } break; case 0x90 : //unknown event_dur = GetByte(curOffset++); curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0x92 : //unknown event_dur = GetByte(curOffset++); curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0x93 : //unknown event_dur = GetByte(curOffset++); curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0x94 : //unknown event_dur = GetByte(curOffset++); curOffset += 3; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0x95 : //unknown event_dur = GetByte(curOffset++); curOffset++; AddUnknown(beginOffset, curOffset-beginOffset, L"Unknown Event (Tie?)"); break; case 0x96 : //Pitch Bend Range { event_dur = GetByte(curOffset++); uint8_t semitones = GetByte(curOffset++); AddPitchBendRange(beginOffset, curOffset-beginOffset, semitones); } break; case 0x97 : //unknown event_dur = GetByte(curOffset++); curOffset += 4; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0x99 : //unknown event_dur = GetByte(curOffset++); curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0x9A : //unknown event_dur = GetByte(curOffset++); curOffset++; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0x9B : //unknown event_dur = GetByte(curOffset++); curOffset += 5; AddUnknown(beginOffset, curOffset-beginOffset); break; case 0x9E : //imply note params impliedNoteDur = GetByte(curOffset++); impliedVelocity = GetByte(curOffset++); AddGenericEvent(beginOffset, curOffset-beginOffset, L"Imply Note Params", NULL, CLR_CHANGESTATE); break; default : Alert(L"Unknown event opcode %X at %X", status_byte, beginOffset); AddUnknown(beginOffset, curOffset-beginOffset); return false; } if (event_dur) AddTime(event_dur); return true; }