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