Пример #1
0
void CompileSnesTrack::AddInitialMidiEvents(int trackNum)
{
	SeqTrack::AddInitialMidiEvents(trackNum);

	double volumeScale;
	AddProgramChangeNoItem(spcSRCN, true);
	AddVolNoItem(Convert7bitPercentVolValToStdMidiVal(spcVolume / 2));
	AddPanNoItem(Convert7bitLinearPercentPanValToStdMidiVal((uint8_t)(spcPan + 0x80) / 2, &volumeScale));
	AddExpressionNoItem(ConvertPercentAmpToStdMidiVal(volumeScale));
	AddReverbNoItem(0);
}
Пример #2
0
bool WDInstr::LoadInstr()
{
	wostringstream	strStr;
	ULONG j=0;
	long startAddress = 0;
	BOOL notSampleStart = false;

	//Read region data 
	

	bool bSecondToLastRgn = 0;
	bool bLastRgn = 0;

	unsigned int k = 0;
	while (k*0x20 < unLength)
	{
		if (bSecondToLastRgn)
			bLastRgn = true;

		WDRgn* rgn = new WDRgn(this, k*0x20  + dwOffset);
		aRgns.push_back(rgn);

		rgn->AddSimpleItem(k*0x20 + dwOffset, 1, L"Stereo Region Flag");
		rgn->AddSimpleItem(k*0x20 + 1 + dwOffset, 1, L"First/Last Region Flags");
		rgn->AddSimpleItem(k*0x20 + 2 + dwOffset, 2, L"Unknown Flag");
		rgn->AddSimpleItem(k*0x20 + 0x4 + dwOffset, 4, L"Sample Offset");
		rgn->AddSimpleItem(k*0x20 + 0x8 + dwOffset, 4, L"Loop Start");
		rgn->AddSimpleItem(k*0x20 + 0xC + dwOffset, 2, L"ADSR1");
		rgn->AddSimpleItem(k*0x20 + 0xE + dwOffset, 2, L"ADSR2");
		rgn->AddSimpleItem(k*0x20 + 0x12 + dwOffset, 1, L"Finetune");
		rgn->AddSimpleItem(k*0x20 + 0x13 + dwOffset, 1, L"UnityKey");
		rgn->AddSimpleItem(k*0x20 + 0x14 + dwOffset, 1, L"Key High");
		rgn->AddSimpleItem(k*0x20 + 0x15 + dwOffset, 1, L"Velocity High");
		rgn->AddSimpleItem(k*0x20 + 0x16 + dwOffset, 1, L"Attenuation");
		rgn->AddSimpleItem(k*0x20 + 0x17 + dwOffset, 1, L"Pan");

		rgn->bStereoRegion =  GetByte(k*0x20 + dwOffset) & 0x1;
		rgn->bUnknownFlag2 =  GetByte(k*0x20 + 2 + dwOffset) & 0x1;
		rgn->bFirstRegion =  GetByte(k*0x20 + 1 + dwOffset) & 0x1;
		rgn->bLastRegion =  (GetByte(k*0x20 + 1 + dwOffset) & 0x2) >> 1;
		//rgn->sample_offset =  GetWord(k*0x20 + 0x4 + dwOffset);
		rgn->sampOffset = GetWord(k*0x20 + 0x4 + dwOffset) & 0xFFFFFFF0;	//The & is there because FFX points to 0x----C offsets for some very odd reason
		rgn->loop.loopStart =  GetWord(k*0x20 + 0x8 + dwOffset);
		rgn->ADSR1 =  GetShort(k*0x20 + 0xC + dwOffset);
		rgn->ADSR2 =  GetShort(k*0x20 + 0xE + dwOffset);
		rgn->fineTune =  GetByte(k*0x20 + 0x12 + dwOffset);
		rgn->unityKey =  0x3A - GetByte(k*0x20 + 0x13 + dwOffset);
		rgn->keyHigh =  GetByte(k*0x20 + 0x14 + dwOffset);
		rgn->velHigh = Convert7bitPercentVolValToStdMidiVal( GetByte(k*0x20 + 0x15 + dwOffset) );

		BYTE vol = GetByte(k*0x20 + 0x16 + dwOffset);
		rgn->SetVolume((double)vol / 127.0);

		rgn->pan =  (double)GetByte(k*0x20 + 0x17 + dwOffset);		//need to convert

		if (rgn->pan == 255)
			rgn->pan = 1.0;
		else if (rgn->pan == 128)
			rgn->pan = 0;
		else if (rgn->pan == 192)
			rgn->pan = 0.5;
		else if (rgn->pan > 127)
			rgn->pan = (double)(rgn->pan-128)/(double)127;
		else
			rgn->pan = 0.5;

		rgn->fineTune = (short)ceil(((finetune_table[rgn->fineTune] - 0x10000) * 0.025766555011594949755217727389848) - 50);
		PSXConvADSR<WDRgn>(rgn, rgn->ADSR1, rgn->ADSR2, true);

		if (rgn->bLastRegion)
		{
			if (rgn->bStereoRegion)
				bSecondToLastRgn = true;
			else
				bLastRgn = true;
		}
		k++;
	}

	//First, do key and velocity ranges
	BYTE prevKeyHigh = 0;
	BYTE prevVelHigh = 0;
	for (UINT k=0; k<aRgns.size(); k++)
	{
		// Key Ranges
		if (((WDRgn*)aRgns[k])->bFirstRegion) //&& !instrument[i].region[k].bLastRegion) //used in ffx2 0049 YRP battle 1.  check out first instrument, flags are weird
			aRgns[k]->keyLow = 0;
		else if (k > 0)
		{
			if (aRgns[k]->keyHigh == aRgns[k-1]->keyHigh)
				aRgns[k]->keyLow = aRgns[k-1]->keyLow;//hDLSFile.aInstrs.back()->aRgns.back()->usKeyLow;
			else
				aRgns[k]->keyLow = aRgns[k-1]->keyHigh+1;
		}
		else
			aRgns[k]->keyLow = 0;

		if (((WDRgn*)aRgns[k])->bLastRegion)
			aRgns[k]->keyHigh = 0x7F;


		// Velocity ranges
		if (aRgns[k]->velHigh == prevVelHigh)
			aRgns[k]->velLow = aRgns[k-1]->velLow;
		else
			aRgns[k]->velLow = prevVelHigh + 1;
		prevVelHigh = aRgns[k]->velHigh;

		if (k == 0) //if it's the first region of the instrument
			aRgns[k]->velLow = 0;
		else if (aRgns[k]->velHigh == aRgns[k-1]->velHigh)
		{
			aRgns[k]->velLow = aRgns[k-1]->velLow;
			aRgns[k]->velHigh = 0x7F;		//FFX 0022, aka sight of spira, was giving me problems, hence this
			aRgns[k-1]->velHigh = 0x7F; //hDLSFile.aInstrs.back()->aRgns.back()->usVelHigh = 0x7F;
		}
		else if (aRgns[k-1]->velHigh == 0x7F)
			aRgns[k]->velLow = 0;
		else
			aRgns[k]->velLow = aRgns[k-1]->velHigh+1;
	}
	return TRUE;
}
Пример #3
0
bool CompileSnesTrack::ReadEvent(void)
{
	CompileSnesSeq* parentSeq = (CompileSnesSeq*)this->parentSeq;

	uint32_t beginOffset = curOffset;
	if (curOffset >= 0x10000) {
		return false;
	}

	uint8_t statusByte = GetByte(curOffset++);
	bool bContinue = true;

	std::wstringstream desc;

	CompileSnesSeqEventType eventType = (CompileSnesSeqEventType)0;
	std::map<uint8_t, CompileSnesSeqEventType>::iterator pEventType = parentSeq->EventMap.find(statusByte);
	if (pEventType != parentSeq->EventMap.end()) {
		eventType = pEventType->second;
	}

	switch (eventType)
	{
	case EVENT_UNKNOWN0:
		desc << L"Event: 0x" << std::hex << std::setfill(L'0') << std::setw(2) << std::uppercase << (int)statusByte;
		AddUnknown(beginOffset, curOffset-beginOffset, L"Unknown Event", desc.str().c_str());
		break;

	case EVENT_UNKNOWN1:
	{
		uint8_t arg1 = GetByte(curOffset++);
		desc << L"Event: 0x" << std::hex << std::setfill(L'0') << std::setw(2) << std::uppercase << (int)statusByte
			<< std::dec << std::setfill(L' ') << std::setw(0)
			<< L"  Arg1: " << (int)arg1;
		AddUnknown(beginOffset, curOffset-beginOffset, L"Unknown Event", desc.str().c_str());
		break;
	}

	case EVENT_UNKNOWN2:
	{
		uint8_t arg1 = GetByte(curOffset++);
		uint8_t arg2 = GetByte(curOffset++);
		desc << L"Event: 0x" << std::hex << std::setfill(L'0') << std::setw(2) << std::uppercase << (int)statusByte
			<< std::dec << std::setfill(L' ') << std::setw(0)
			<< L"  Arg1: " << (int)arg1
			<< L"  Arg2: " << (int)arg2;
		AddUnknown(beginOffset, curOffset-beginOffset, L"Unknown Event", desc.str().c_str());
		break;
	}

	case EVENT_UNKNOWN3:
	{
		uint8_t arg1 = GetByte(curOffset++);
		uint8_t arg2 = GetByte(curOffset++);
		uint8_t arg3 = GetByte(curOffset++);
		desc << L"Event: 0x" << std::hex << std::setfill(L'0') << std::setw(2) << std::uppercase << (int)statusByte
			<< std::dec << std::setfill(L' ') << std::setw(0)
			<< L"  Arg1: " << (int)arg1
			<< L"  Arg2: " << (int)arg2
			<< L"  Arg3: " << (int)arg3;
		AddUnknown(beginOffset, curOffset-beginOffset, L"Unknown Event", desc.str().c_str());
		break;
	}

	case EVENT_UNKNOWN4:
	{
		uint8_t arg1 = GetByte(curOffset++);
		uint8_t arg2 = GetByte(curOffset++);
		uint8_t arg3 = GetByte(curOffset++);
		uint8_t arg4 = GetByte(curOffset++);
		desc << L"Event: 0x" << std::hex << std::setfill(L'0') << std::setw(2) << std::uppercase << (int)statusByte
			<< std::dec << std::setfill(L' ') << std::setw(0)
			<< L"  Arg1: " << (int)arg1
			<< L"  Arg2: " << (int)arg2
			<< L"  Arg3: " << (int)arg3
			<< L"  Arg4: " << (int)arg4;
		AddUnknown(beginOffset, curOffset-beginOffset, L"Unknown Event", desc.str().c_str());
		break;
	}

	case EVENT_UNKNOWN5:
	{
		uint8_t arg1 = GetByte(curOffset++);
		uint8_t arg2 = GetByte(curOffset++);
		uint8_t arg3 = GetByte(curOffset++);
		uint8_t arg4 = GetByte(curOffset++);
		uint8_t arg5 = GetByte(curOffset++);
		desc << L"Event: 0x" << std::hex << std::setfill(L'0') << std::setw(2) << std::uppercase << (int)statusByte
			<< std::dec << std::setfill(L' ') << std::setw(0)
			<< L"  Arg1: " << (int)arg1
			<< L"  Arg2: " << (int)arg2
			<< L"  Arg3: " << (int)arg3
			<< L"  Arg4: " << (int)arg4
			<< L"  Arg5: " << (int)arg5;
		AddUnknown(beginOffset, curOffset-beginOffset, L"Unknown Event", desc.str().c_str());
		break;
	}

	case EVENT_GOTO:
	{
		uint16_t dest = GetShort(curOffset); curOffset += 2;
		desc << L"Destination: $" << std::hex << std::setfill(L'0') << std::setw(4) << std::uppercase << (int)dest;
		uint32_t length = curOffset - beginOffset;

		curOffset = dest;
		if (!IsOffsetUsed(dest)) {
			AddGenericEvent(beginOffset, length, L"Jump", desc.str().c_str(), CLR_LOOPFOREVER);
		}
		else {
			bContinue = AddLoopForever(beginOffset, length, L"Jump");
		}
		break;
	}

	case EVENT_LOOP_END:
	{
		uint8_t repeatNest = GetByte(curOffset++);
		uint16_t dest = GetShort(curOffset); curOffset += 2;

		desc << L"Nest Level: " << (int)repeatNest << L"  Destination: $" << std::hex << std::setfill(L'0') << std::setw(4) << std::uppercase << (int)dest;
		AddGenericEvent(beginOffset, curOffset - beginOffset, L"Repeat End", desc.str().c_str(), CLR_LOOP, ICON_ENDREP);

		repeatCount[repeatNest]--;
		if (repeatCount[repeatNest] != 0) {
			curOffset = dest;
		}
		break;
	}

	case EVENT_END:
	{
		AddEndOfTrack(beginOffset, curOffset-beginOffset);
		bContinue = false;
		break;
	}

	case EVENT_VIBRATO:
	{
		uint8_t envelopeIndex = GetByte(curOffset++);
		desc << L"Envelope Index: " << (int)envelopeIndex;
		AddGenericEvent(beginOffset, curOffset - beginOffset, L"Vibrato", desc.str().c_str(), CLR_MODULATION, ICON_CONTROL);
		break;
	}

	case EVENT_PORTAMENTO_TIME:
	{
		uint8_t rate = GetByte(curOffset++);
		desc << L"Rate: " << (int)rate;
		AddGenericEvent(beginOffset, curOffset - beginOffset, L"Portamento Time", desc.str().c_str(), CLR_PORTAMENTOTIME, ICON_CONTROL);
		break;
	}

	case EVENT_VOLUME:
	{
		uint8_t newVolume = GetByte(curOffset++);
		spcVolume = newVolume;
		uint8_t midiVolume = Convert7bitPercentVolValToStdMidiVal(spcVolume / 2);
		AddVol(beginOffset, curOffset - beginOffset, midiVolume);
		break;
	}

	case EVENT_VOLUME_ENVELOPE:
	{
		uint8_t envelopeIndex = GetByte(curOffset++);
		desc << L"Envelope Index: " << (int)envelopeIndex;
		AddGenericEvent(beginOffset, curOffset - beginOffset, L"Volume Envelope", desc.str().c_str(), CLR_VOLUME, ICON_CONTROL);
		break;
	}

	case EVENT_TRANSPOSE:
	{
		int8_t delta = (int8_t)GetByte(curOffset++);
		spcTranspose += delta;
		AddTranspose(beginOffset, curOffset - beginOffset, spcTranspose, L"Transpose (Relative)");
		break;
	}

	case EVENT_VOLUME_REL:
	{
		int8_t delta = (int8_t)GetByte(curOffset++);
		spcVolume += delta;
		uint8_t midiVolume = Convert7bitPercentVolValToStdMidiVal(spcVolume / 2);
		AddVol(beginOffset, curOffset - beginOffset, midiVolume, L"Volume (Relative)");
		break;
	}

	case EVENT_NOTE:
	{
		bool rest = (statusByte == 0x00);

		uint8_t duration;
		bool hasDuration = ReadDurationBytes(curOffset, duration);
		if (hasDuration) {
			spcNoteDuration = duration;
			desc << L"Duration: " << (int)duration;
		}

		if (rest) {
			AddRest(beginOffset, curOffset - beginOffset, spcNoteDuration);
		}
		else {
			uint8_t noteNumber = statusByte - 1;
			AddNoteByDur(beginOffset, curOffset - beginOffset, noteNumber, 100, spcNoteDuration,
				hasDuration ? L"Note with Duration" : L"Note");
			AddTime(spcNoteDuration);
		}
		break;
	}

	case EVENT_LOOP_COUNT:
	{
		uint8_t repeatNest = GetByte(curOffset++);
		uint8_t times = GetByte(curOffset++);
		int actualTimes = (times == 0) ? 256 : times;

		desc << L"Nest Level: " << (int)repeatNest << L"  Times: " << actualTimes;
		AddGenericEvent(beginOffset, curOffset - beginOffset, L"Loop Count", desc.str().c_str(), CLR_LOOP, ICON_STARTREP);

		repeatCount[repeatNest] = times;
		break;
	}

	case EVENT_FLAGS:
	{
		uint8_t flags = GetByte(curOffset++);
		spcFlags = flags;
		AddGenericEvent(beginOffset, curOffset - beginOffset, L"Flags", desc.str().c_str(), CLR_CHANGESTATE, ICON_CONTROL);
		break;
	}

	case EVENT_TEMPO:
	{
		uint8_t newTempo = GetByte(curOffset++);
		spcTempo = newTempo;
		AddTempoBPM(beginOffset, curOffset - beginOffset, parentSeq->GetTempoInBPM(newTempo));
		break;
	}

	case EVENT_TUNING:
	{
		int16_t newTuning;
		if (parentSeq->version == COMPILESNES_ALESTE || parentSeq->version == COMPILESNES_JAKICRUSH) {
			newTuning = (int8_t)GetByte(curOffset++);
		}
		else {
			newTuning = (int16_t)GetShort(curOffset); curOffset += 2;
		}

		desc << L"Pitch Register Delta: " << (int)newTuning;
		AddGenericEvent(beginOffset, curOffset - beginOffset, L"Tuning", desc.str().c_str(), CLR_CHANGESTATE, ICON_CONTROL);
		break;
	}

	case EVENT_CALL:
	{
		uint16_t dest = GetShort(curOffset); curOffset += 2;
		desc << L"Destination: $" << std::hex << std::setfill(L'0') << std::setw(4) << std::uppercase << (int)dest;

		AddGenericEvent(beginOffset, curOffset - beginOffset, L"Pattern Play", desc.str().c_str(), CLR_LOOP, ICON_STARTREP);

		subReturnAddress = curOffset;
		curOffset = dest;
		break;
	}

	case EVENT_RET:
	{
		AddGenericEvent(beginOffset, curOffset - beginOffset, L"End Pattern", desc.str().c_str(), CLR_TRACKEND, ICON_ENDREP);
		curOffset = subReturnAddress;
		break;
	}

	case EVENT_PROGCHANGE:
	{
		uint8_t newProg = GetByte(curOffset++);
		AddProgramChange(beginOffset, curOffset - beginOffset, newProg, true);
		break;
	}

	case EVENT_ADSR:
	{
		uint8_t envelopeIndex = GetByte(curOffset++);
		desc << L"Envelope Index: " << (int)envelopeIndex;
		AddGenericEvent(beginOffset, curOffset - beginOffset, L"ADSR", desc.str().c_str(), CLR_VOLUME, ICON_CONTROL);
		break;
	}

	case EVENT_PORTAMENTO_ON:
	{
		spcFlags |= COMPILESNES_FLAGS_PORTAMENTO;
		AddGenericEvent(beginOffset, curOffset - beginOffset, L"Portamento On", desc.str().c_str(), CLR_PORTAMENTO, ICON_CONTROL);
		break;
	}

	case EVENT_PORTAMENTO_OFF:
	{
		spcFlags &= ~COMPILESNES_FLAGS_PORTAMENTO;
		AddGenericEvent(beginOffset, curOffset - beginOffset, L"Portamento Off", desc.str().c_str(), CLR_PORTAMENTO, ICON_CONTROL);
		break;
	}

	case EVENT_PANPOT_ENVELOPE:
	{
		uint8_t envelopeIndex = GetByte(curOffset++);
		desc << L"Envelope Index: " << (int)envelopeIndex;
		AddGenericEvent(beginOffset, curOffset - beginOffset, L"Panpot Envelope", desc.str().c_str(), CLR_PAN, ICON_CONTROL);
		break;
	}

	case EVENT_PAN:
	{
		int8_t newPan = GetByte(curOffset++);
		spcPan = newPan;

		double volumeScale;
		uint8_t midiPan = Convert7bitLinearPercentPanValToStdMidiVal((uint8_t)(newPan + 0x80) / 2, &volumeScale);
		AddExpressionNoItem(ConvertPercentAmpToStdMidiVal(volumeScale));
		AddPan(beginOffset, curOffset - beginOffset, midiPan);
		break;
	}

	case EVENT_LOOP_BREAK:
	{
		uint8_t repeatNest = GetByte(curOffset++);
		uint16_t dest = GetShort(curOffset); curOffset += 2;

		desc << L"Nest Level: " << (int)repeatNest << L"  Destination: $" << std::hex << std::setfill(L'0') << std::setw(4) << std::uppercase << (int)dest;
		AddGenericEvent(beginOffset, curOffset - beginOffset, L"Repeat Break", desc.str().c_str(), CLR_LOOP, ICON_ENDREP);

		repeatCount[repeatNest]--;
		if (repeatCount[repeatNest] == 0) {
			curOffset = dest;
		}
		break;
	}

	case EVENT_DURATION_DIRECT:
	{
		uint8_t duration;
		if (!ReadDurationBytes(curOffset, duration)) {
			// address out of range
			return false;
		}
		spcNoteDuration = duration;

		desc << L"Duration: " << (int)duration;
		AddGenericEvent(beginOffset, curOffset - beginOffset, L"Duration (Direct)", desc.str().c_str(), CLR_DURNOTE, ICON_CONTROL);
		break;
	}

	case EVENT_DURATION:
	{
		uint8_t duration;
		if (!ReadDurationBytes(curOffset, duration)) {
			// address out of range
			return false;
		}
		spcNoteDuration = duration;

		desc << L"Duration: " << (int)duration;
		AddGenericEvent(beginOffset, curOffset - beginOffset, L"Duration", desc.str().c_str(), CLR_DURNOTE, ICON_CONTROL);
		break;
	}

	case EVENT_PERCUSSION_NOTE:
	{
		uint8_t duration;
		bool hasDuration = ReadDurationBytes(curOffset, duration);
		if (hasDuration) {
			spcNoteDuration = duration;
			desc << L"Duration: " << (int)duration;
		}

		uint8_t percNoteNumber = statusByte - parentSeq->STATUS_PERCUSSION_NOTE_MIN;
		AddPercNoteByDur(beginOffset, curOffset - beginOffset, percNoteNumber, 100, spcNoteDuration,
			hasDuration ? L"Percussion Note with Duration" : L"Percussion Note");
		AddTime(spcNoteDuration);
		break;
	}

	default:
		desc << L"Event: 0x" << std::hex << std::setfill(L'0') << std::setw(2) << std::uppercase << (int)statusByte;
		AddUnknown(beginOffset, curOffset-beginOffset, L"Unknown Event", desc.str().c_str());
		pRoot->AddLogItem(new LogItem((std::wstring(L"Unknown Event - ") + desc.str()).c_str(), LOG_LEVEL_ERR, L"CompileSnesSeq"));
		bContinue = false;
		break;
	}

	//wostringstream ssTrace;
	//ssTrace << L"" << std::hex << std::setfill(L'0') << std::setw(8) << std::uppercase << beginOffset << L": " << std::setw(2) << (int)statusByte  << L" -> " << std::setw(8) << curOffset << std::endl;
	//OutputDebugString(ssTrace.str().c_str());

	return bContinue;
}