예제 #1
0
void CChannelHandlerVRC6::HandleCustomEffects(int EffNum, int EffParam)
{
	if (!CheckCommonEffects(EffNum, EffParam)) {
		switch (EffNum) {
			case EF_DUTY_CYCLE:
				m_iDefaultDuty = m_iDutyPeriod = EffParam;
				break;
			case EF_SLIDE_UP:
			case EF_SLIDE_DOWN:
				m_iPostEffect = EffNum;
				m_iPostEffectParam = EffParam;
				SetupSlide(EffNum, EffParam);
				break;
		}
	}
}
예제 #2
0
void CChannelHandlerVRC7::PlayChannelNote(stChanNote *pNoteData, int EffColumns)
{
	int PostEffect = 0, PostEffectParam;
	int Patch = -1;
	CInstrumentVRC7 *pInstrument = NULL;
#if 0
	int Instrument = pNoteData->Instrument;

	if (Instrument != MAX_INSTRUMENTS/* && Instrument != m_iInstrument*/) {
//		m_iLastInstrument = m_iInstrument;
		m_iInstrument = Instrument;
	}
	else
		Instrument = m_iInstrument;

	if (Instrument != MAX_INSTRUMENTS)
		pInstrument = (CInstrumentVRC7*)m_pDocument->GetInstrument(Instrument);
#endif

	if (pNoteData->Instrument != MAX_INSTRUMENTS)
		m_iInstrument = pNoteData->Instrument;

	if (m_iInstrument != MAX_INSTRUMENTS)
		pInstrument = (CInstrumentVRC7*)m_pDocument->GetInstrument(m_iInstrument);

/*
	if (Instrument != MAX_INSTRUMENTS) {
		// Get the instrument
		if ((pInstrument = (CInstrumentVRC7*)m_pDocument->GetInstrument(Instrument)) == NULL)
			return;

		if (pInstrument->GetType() != INST_VRC7)
			return;
	}
*/

	if (pNoteData->Note != NONE)
	{
		if (pInstrument)
		{
			// Patch number
			m_iPatch = pInstrument->GetPatch();

			// Load custom parameters
			if (m_iPatch == 0)
			{
				for (int i = 0; i < 8; i++)
					m_iRegs[i] = pInstrument->GetCustomReg(i);
			}
		}
	}

	// Evaluate effects
	for (int i = 0; i < EffColumns; i++)
	{
		int EffCmd	 = pNoteData->EffNumber[i];
		int EffParam = pNoteData->EffParam[i];

		if (EffCmd == EF_PORTA_DOWN)
		{
			m_iEffect = EF_PORTA_UP;
			m_iPortaSpeed = EffParam;
		}
		else if (EffCmd == EF_PORTA_UP)
		{
			m_iEffect = EF_PORTA_DOWN;
			m_iPortaSpeed = EffParam;
		}
		else
		{
			if (!CheckCommonEffects(EffCmd, EffParam))
			{
				switch (EffCmd)
				{
					case EF_SLIDE_UP:
					case EF_SLIDE_DOWN:
						PostEffect = EffCmd;
						PostEffectParam = EffParam;
						//SetupSlide(EffCmd, EffParam);
						break;
					case EF_DUTY_CYCLE:
						Patch = EffParam;
						break;
/*
					case EF_VRC7_MODULATOR:
						switch (EffParam & 0xF0) {
							case 0x00:	// Amplitude modulation on/off
								break;
							case 0x10:	// Vibrato on/off
								break;
							case 0x20:	// Sustain on/off
								break;
							case 0x30:	// Wave rectification on/off
								break;
							case 0x40:	// Key rate scaling on/off
								break;
							case 0x50:	// Key rate level
								break;
							case 0x60:	// Mult factor
								break;
							case 0x70:	// Attack
								break;
							case 0x80:	// Decay
								break;
							case 0x90:	// Sustain
								break;
							case 0xA0:	// Release
								break;
						}
						break;
					case EF_VRC7_CARRIER:
						break;
					case EF_VRC7_LEVELS:
						if (EffParam & 0x80)	// Feedback
							m_iRegs[0x03] = (m_iRegs[0x03] & 0xF8) | (EffParam & 0x07);
						else
							m_iRegs[0x02] = (m_iRegs[0x02] & 0xC0) | (EffParam & 0x3F);
						bRegsDirty = true;
						break;
						*/
				}
			}
		}
	}

	// Volume
	if (pNoteData->Vol < 0x10)
	{
		m_iVolume = pNoteData->Vol << VOL_SHIFT;
	}

	if (pNoteData->Note == HALT)
	{
		// Halt
		m_iCommand = CMD_NOTE_HALT;
		// TODO - dan
//		theApp.RegisterKeyState(m_iChannelID, -1);
	}
	else if (pNoteData->Note == RELEASE)
	{
		// Release
		m_iCommand = CMD_NOTE_RELEASE;
		// TODO - dan
//		theApp.RegisterKeyState(m_iChannelID, -1);
	}
	else if (pNoteData->Note != NONE)
	{
		// Check instrument
//		if (!pInstrument)
//			return;

		if (pInstrument) {
			// Only allow VRC7 instruments
			if (pInstrument->GetType() != INST_VRC7)
				return;
		}

		int OldNote = m_iNote;
		int OldOctave = m_iOctave;

		// Portamento fix
		if (m_iCommand == CMD_NOTE_HALT)
			m_iPeriod = 0;

		// Trigger note
		m_iNote		= CChannelHandler::RunNote(pNoteData->Octave, pNoteData->Note);
		m_bEnabled	= true;
		m_bHold		= true;

//		if (m_iInstrument != m_iLastInstrument /*|| m_iCommand != CMD_NOTE_ON*/)

		if ((m_iEffect != EF_PORTAMENTO || m_iPortaSpeed == 0) || m_iCommand == CMD_NOTE_HALT)
			m_iCommand = CMD_NOTE_TRIGGER;

		if (m_iPortaSpeed > 0 && m_iEffect == EF_PORTAMENTO && m_iCommand != CMD_NOTE_HALT)
		{
			// Set current frequency to the one with highest octave
			if (m_iOctave > OldOctave)
			{
				m_iPeriod >>= (m_iOctave - OldOctave);
			}
			else if (OldOctave > m_iOctave)
			{
				// Do nothing
				m_iPortaTo >>= (OldOctave - m_iOctave);
				m_iOctave = OldOctave;
			}
예제 #3
0
void CChannelHandlerVRC6::PlayChannelNote(stChanNote *pNoteData, int EffColumns)
{
	CInstrumentVRC6 *pInstrument;
	int PostEffect = 0, PostEffectParam;

	int LastInstrument = m_iInstrument;

	if (!CChannelHandler::CheckNote(pNoteData, INST_VRC6))
		return;

	unsigned int Note, Octave;
	unsigned int Volume;

	Note	= pNoteData->Note;
	Octave	= pNoteData->Octave;
	Volume	= pNoteData->Vol;

	if (Note != 0)
	{
		m_bRelease = false;
	}
	else
	{
		if (pNoteData->Instrument != MAX_INSTRUMENTS)
			m_iInstrument = pNoteData->Instrument;
	}

	if (Note == RELEASE)
	{
		m_bRelease = true;
		m_iInstrument = LastInstrument;
	}
	else if (Note == HALT)
	{
		m_iInstrument	= LastInstrument;
	}

	// Evaluate effects
	for (int n = 0; n < EffColumns; n++) {
		int EffCmd	 = pNoteData->EffNumber[n];
		int EffParam = pNoteData->EffParam[n];

		if (!CheckCommonEffects(EffCmd, EffParam)) {
			switch (EffCmd) {
				case EF_DUTY_CYCLE:
					m_iDefaultDuty = m_iDutyPeriod = EffParam;
					break;
				case EF_SLIDE_UP:
				case EF_SLIDE_DOWN:
					PostEffect = EffCmd;
					PostEffectParam = EffParam;
					SetupSlide(EffCmd, EffParam);
					break;
			}
		}
	}

	pInstrument = (CInstrumentVRC6*)m_pDocument->GetInstrument(m_iInstrument);

	if (!pInstrument)
		return;

	if ((LastInstrument != m_iInstrument) || (Note > 0 && Note != HALT && Note != RELEASE))
	{
		// Setup instrument
		for (int i = 0; i < CInstrumentVRC6::SEQUENCE_COUNT; i++)
		{
			m_iSeqEnabled[i] = pInstrument->GetSeqEnable(i);
			m_iSeqIndex[i]	 = pInstrument->GetSeqIndex(i);
			m_iSeqPointer[i] = 0;
		}
	}

	// Get volume
	if (Volume < 0x10)
		m_iVolume = Volume << VOL_SHIFT;

	if (Note == HALT)
	{
		KillChannel();
		return;
	}

	// No note
	if (!Note)
		return;

	if (!m_bRelease)
	{
		// Get the note
		m_iNote				= RunNote(Octave, Note);
		m_iSeqVolume		= 0xF;
		m_iDutyPeriod		= m_iDefaultDuty;
		m_bEnabled			= true;
		m_iLastInstrument	= m_iInstrument;
	}
	else
	{
		ReleaseNote();
		ReleaseSequences(SNDCHIP_VRC6);
	}

	if (PostEffect && (m_iEffect == EF_SLIDE_UP || m_iEffect == EF_SLIDE_DOWN))
		SetupSlide(PostEffect, PostEffectParam);
	else if (m_iEffect == EF_SLIDE_DOWN || m_iEffect == EF_SLIDE_UP)
		m_iEffect = EF_NONE;
}