protected virtual void SetInst1Operator(partWork pw, int n, int modeBeforeSend, int opeNum) { mucomVoice inst = parent.instFM[n]; int targetBaseReg = (opeNum / 6) * 8 + (opeNum % 6); byte port = this.port[opeNum / 18]; int ope = (opeNum % 6) / 3; switch (modeBeforeSend) { case 0: // N)one break; case 1: // R)R only pw.OutData(port, (byte)(targetBaseReg + ope * 3 + 0x80) , ((0 & 0xf) << 4) | (15 & 0xf)); //SL RR break; case 2: // A)ll SetInstAtOneOpeWithoutKslTl(pw, opeNum , 15, 15, 0, 15, 0, 0, 0, 0, 0, 0); pw.OutData(port, (byte)(targetBaseReg + ope * 3 + 0x40) , ((0 & 0x3) << 6) | 0x3f); //KL(M) TL break; } SetInstAtOneOpeWithoutKslTl(pw, opeNum, inst.data[ope * 12 + 1 + 0], //AR inst.data[ope * 12 + 1 + 1], //DR inst.data[ope * 12 + 1 + 2], //SL inst.data[ope * 12 + 1 + 3], //RR inst.data[ope * 12 + 1 + 6], //MT inst.data[ope * 12 + 1 + 7], //AM inst.data[ope * 12 + 1 + 8], //VIB inst.data[ope * 12 + 1 + 9], //EGT inst.data[ope * 12 + 1 + 10], //KSR inst.data[ope * 12 + 1 + 11] //WS ); int cnt = inst.data[25]; if (cnt == 0 || pw.Type == enmChannelType.RHYTHM) { if (ope == 0) { //OP1 pw.OutData(port, (byte)(0x40 + targetBaseReg + 0) , (byte)(((inst.data[12 * 0 + 5] & 0x3) << 6) | (inst.data[12 * 0 + 6] & 0x3f))); //KL(M) TL } } SetInstAtChannelPanFbCnt(pw, (opeNum % 6) % 3 + (opeNum / 6) * 3, (int)pw.ipan, inst.data[26], inst.data[25]); pw.beforeVolume = -1; }
public override void SetToneDoubler(partWork pw, MML mml) { return; int i = pw.instrument; if (i < 0) { return; } pw.toneDoublerKeyShift = 0; mucomVoice instFM = parent.instFM[i]; if (instFM == null || instFM.data.Length < 1) { return; } Note note = (Note)mml.args[0]; if (pw.TdA == -1) { //resetToneDoubler //ML if (pw.op1ml != instFM.data[0 * Const.INSTRUMENT_M_OPERATOR_SIZE + 7 + 3]) { ((YM2151)pw.chip).OutSetDtMl(pw, 0, instFM.data[0 * Const.INSTRUMENT_M_OPERATOR_SIZE + 8 + 3], instFM.data[0 * Const.INSTRUMENT_M_OPERATOR_SIZE + 7 + 3]); pw.op1ml = instFM.data[0 * Const.INSTRUMENT_M_OPERATOR_SIZE + 7 + 3]; } if (pw.op2ml != instFM.data[1 * Const.INSTRUMENT_M_OPERATOR_SIZE + 7 + 3]) { ((YM2151)pw.chip).OutSetDtMl(pw, 1, instFM.data[1 * Const.INSTRUMENT_M_OPERATOR_SIZE + 8 + 3], instFM.data[1 * Const.INSTRUMENT_M_OPERATOR_SIZE + 7 + 3]); pw.op2ml = instFM.data[1 * Const.INSTRUMENT_M_OPERATOR_SIZE + 7 + 3]; } if (pw.op3ml != instFM.data[2 * Const.INSTRUMENT_M_OPERATOR_SIZE + 7 + 3]) { ((YM2151)pw.chip).OutSetDtMl(pw, 2, instFM.data[2 * Const.INSTRUMENT_M_OPERATOR_SIZE + 8 + 3], instFM.data[2 * Const.INSTRUMENT_M_OPERATOR_SIZE + 7 + 3]); pw.op3ml = instFM.data[2 * Const.INSTRUMENT_M_OPERATOR_SIZE + 7 + 3]; } if (pw.op4ml != instFM.data[3 * Const.INSTRUMENT_M_OPERATOR_SIZE + 7 + 3]) { ((YM2151)pw.chip).OutSetDtMl(pw, 3, instFM.data[3 * Const.INSTRUMENT_M_OPERATOR_SIZE + 8 + 3], instFM.data[3 * Const.INSTRUMENT_M_OPERATOR_SIZE + 7 + 3]); pw.op4ml = instFM.data[3 * Const.INSTRUMENT_M_OPERATOR_SIZE + 7 + 3]; } //DT2 if (pw.op1dt2 != instFM.data[0 * Const.INSTRUMENT_M_OPERATOR_SIZE + 9 + 3]) { ((YM2151)pw.chip).OutSetDt2Sr(pw, 0, instFM.data[0 * Const.INSTRUMENT_M_OPERATOR_SIZE + 9 + 3], instFM.data[0 * Const.INSTRUMENT_M_OPERATOR_SIZE + 2 + 3]); pw.op1dt2 = instFM.data[0 * Const.INSTRUMENT_M_OPERATOR_SIZE + 9 + 3]; } if (pw.op2dt2 != instFM.data[1 * Const.INSTRUMENT_M_OPERATOR_SIZE + 9 + 3]) { ((YM2151)pw.chip).OutSetDt2Sr(pw, 1, instFM.data[1 * Const.INSTRUMENT_M_OPERATOR_SIZE + 9 + 3], instFM.data[1 * Const.INSTRUMENT_M_OPERATOR_SIZE + 2 + 3]); pw.op2dt2 = instFM.data[1 * Const.INSTRUMENT_M_OPERATOR_SIZE + 9 + 3]; } if (pw.op3dt2 != instFM.data[2 * Const.INSTRUMENT_M_OPERATOR_SIZE + 9 + 3]) { ((YM2151)pw.chip).OutSetDt2Sr(pw, 2, instFM.data[2 * Const.INSTRUMENT_M_OPERATOR_SIZE + 9 + 3], instFM.data[2 * Const.INSTRUMENT_M_OPERATOR_SIZE + 2 + 3]); pw.op3dt2 = instFM.data[2 * Const.INSTRUMENT_M_OPERATOR_SIZE + 9 + 3]; } if (pw.op4dt2 != instFM.data[3 * Const.INSTRUMENT_M_OPERATOR_SIZE + 9 + 3]) { ((YM2151)pw.chip).OutSetDt2Sr(pw, 3, instFM.data[3 * Const.INSTRUMENT_M_OPERATOR_SIZE + 9 + 3], instFM.data[3 * Const.INSTRUMENT_M_OPERATOR_SIZE + 2 + 3]); pw.op4dt2 = instFM.data[3 * Const.INSTRUMENT_M_OPERATOR_SIZE + 9 + 3]; } } else { //setToneDoubler int oct = pw.octaveNow; foreach (MML octMml in note.tDblOctave) { switch (octMml.type) { case enmMMLType.Octave: oct = (int)octMml.args[0]; break; case enmMMLType.OctaveUp: oct++; break; case enmMMLType.OctaveDown: oct--; break; } } oct = Common.CheckRange(oct, 1, 8); pw.octaveNew = oct; int TdB = oct * 12 + Const.NOTE.IndexOf(note.tDblCmd) + note.tDblShift + pw.keyShift; // + pw.arpDelta; int s = TdB - pw.TdA; // - TdB; int us = Math.Abs(s); int n = pw.toneDoubler; clsToneDoubler instToneDoubler = parent.instToneDoubler[n]; if (us >= instToneDoubler.lstTD.Count) { return; } pw.toneDoublerKeyShift = ((s < 0) ? s : 0) + instToneDoubler.lstTD[us].KeyShift; //ML if (pw.op1ml != instToneDoubler.lstTD[us].OP1ML) { ((YM2151)pw.chip).OutSetDtMl(pw, 0, instFM.data[0 * Const.INSTRUMENT_M_OPERATOR_SIZE + 8 + 3], instToneDoubler.lstTD[us].OP1ML); pw.op1ml = instToneDoubler.lstTD[us].OP1ML; } if (pw.op2ml != instToneDoubler.lstTD[us].OP2ML) { ((YM2151)pw.chip).OutSetDtMl(pw, 1, instFM.data[1 * Const.INSTRUMENT_M_OPERATOR_SIZE + 8 + 3], instToneDoubler.lstTD[us].OP2ML); pw.op2ml = instToneDoubler.lstTD[us].OP2ML; } if (pw.op3ml != instToneDoubler.lstTD[us].OP3ML) { ((YM2151)pw.chip).OutSetDtMl(pw, 2, instFM.data[2 * Const.INSTRUMENT_M_OPERATOR_SIZE + 8 + 3], instToneDoubler.lstTD[us].OP3ML); pw.op3ml = instToneDoubler.lstTD[us].OP3ML; } if (pw.op4ml != instToneDoubler.lstTD[us].OP4ML) { ((YM2151)pw.chip).OutSetDtMl(pw, 3, instFM.data[3 * Const.INSTRUMENT_M_OPERATOR_SIZE + 8 + 3], instToneDoubler.lstTD[us].OP4ML); pw.op4ml = instToneDoubler.lstTD[us].OP4ML; } //DT2 if (pw.op1dt2 != instToneDoubler.lstTD[us].OP1DT2) { ((YM2151)pw.chip).OutSetDt2Sr(pw, 0, instToneDoubler.lstTD[us].OP1DT2, instFM.data[0 * Const.INSTRUMENT_M_OPERATOR_SIZE + 2 + 3]); pw.op1dt2 = instToneDoubler.lstTD[us].OP1DT2; } if (pw.op2dt2 != instToneDoubler.lstTD[us].OP2DT2) { ((YM2151)pw.chip).OutSetDt2Sr(pw, 1, instToneDoubler.lstTD[us].OP2DT2, instFM.data[1 * Const.INSTRUMENT_M_OPERATOR_SIZE + 2 + 3]); pw.op2dt2 = instToneDoubler.lstTD[us].OP2DT2; } if (pw.op3dt2 != instToneDoubler.lstTD[us].OP3DT2) { ((YM2151)pw.chip).OutSetDt2Sr(pw, 2, instToneDoubler.lstTD[us].OP3DT2, instFM.data[2 * Const.INSTRUMENT_M_OPERATOR_SIZE + 2 + 3]); pw.op3dt2 = instToneDoubler.lstTD[us].OP3DT2; } if (pw.op4dt2 != instToneDoubler.lstTD[us].OP4DT2) { ((YM2151)pw.chip).OutSetDt2Sr(pw, 3, instToneDoubler.lstTD[us].OP4DT2, instFM.data[3 * Const.INSTRUMENT_M_OPERATOR_SIZE + 2 + 3]); pw.op4dt2 = instToneDoubler.lstTD[us].OP4DT2; } //pw.ppg[pw.cpgNum].TdA = -1; } }
protected virtual void SetInst4Operator(partWork pw, int n, int modeBeforeSend, int vch) { if (!pw.isOp4Mode) { msgBox.setErrMsg(string.Format(msg.get("E26000"), n));//, mml.line.Lp); return; } mucomVoice inst = parent.instFM[n]; byte targetBaseReg = ChnToBaseReg(vch); byte port = getPortFromCh(vch); switch (modeBeforeSend) { case 0: // N)one break; case 1: // R)R only for (int ope = 0; ope < 2; ope++) { pw.OutData(port, (byte)(targetBaseReg + ope * 3 + 0x80) , ((0 & 0xf) << 4) | (15 & 0xf));//SL RR } break; case 2: // A)ll for (byte ope = 0; ope < 2; ope++) { SetInstAtOneOpeWithoutKslTl(pw, (vch / 3 * 6) + (vch % 3) + ope * 3 , 15, 15, 0, 15, 0, 0, 0, 0, 0, 0); pw.OutData(port, (byte)(targetBaseReg + ope * 3 + 0x40) , ((0 & 0x3) << 6) | 0x3f); //KL(M) TL } break; } int slot1_operatorNumber = (vch / 3 * 6) + (vch % 3) + 0; for (int ope = 0; ope < 4; ope++) { SetInstAtOneOpeWithoutKslTl(pw, slot1_operatorNumber + ope * 3, inst.data[ope * 12 + 1 + 0], inst.data[ope * 12 + 1 + 1], inst.data[ope * 12 + 1 + 2], inst.data[ope * 12 + 1 + 3], inst.data[ope * 12 + 1 + 6], inst.data[ope * 12 + 1 + 7], inst.data[ope * 12 + 1 + 8], inst.data[ope * 12 + 1 + 9], inst.data[ope * 12 + 1 + 10], inst.data[ope * 12 + 1 + 11] ); } //TLはvolumeの設定と一緒に行うがキャリアのみである。 //そのため、CNT0の場合はモジュレータのパラメータをセットする必要がある int cnt1 = inst.data[49]; int cnt2 = inst.data[50]; bool op1 = false; bool op2 = false; bool op3 = false; if (cnt1 == 0 && cnt2 == 0) { op1 = true; op2 = true; op3 = true; } else if (cnt1 == 0 && cnt2 == 1) { op1 = true; op3 = true; } else if (cnt1 == 1 && cnt2 == 0) { op2 = true; op3 = true; } else if (cnt1 == 1 && cnt2 == 1) { op2 = true; } if (op1) { pw.OutData(port, (byte)(0x40 + ChnToBaseReg(vch) + 0) , (byte)(((inst.data[12 * 0 + 5] & 0x3) << 6) | (inst.data[12 * 0 + 6] & 0x3f))); //KL(M) TL } if (op2) { pw.OutData(port, (byte)(0x40 + ChnToBaseReg(vch) + 3) , (byte)(((inst.data[12 * 1 + 5] & 0x3) << 6) | (inst.data[12 * 1 + 6] & 0x3f))); //KL(M) TL } if (op3) { pw.OutData(port, (byte)(0x40 + ChnToBaseReg(vch) + 8) , (byte)(((inst.data[12 * 2 + 5] & 0x3) << 6) | (inst.data[12 * 2 + 6] & 0x3f))); //KL(M) TL } SetInstAtChannelPanFbCnt(pw, vch, (int)pw.ipan, inst.data[51], cnt1); SetInstAtChannelPanFbCnt(pw, vch + 3, (int)pw.ipan, inst.data[51], cnt2); pw.beforeVolume = -1; }
protected virtual void SetInst2Operator(partWork pw, int n, int modeBeforeSend, int vch) { mucomVoice inst = parent.instFM[n]; byte targetBaseReg = ChnToBaseReg(vch); byte port = getPortFromCh(vch); switch (modeBeforeSend) { case 0: // N)one break; case 1: // R)R only for (int ope = 0; ope < 2; ope++) { pw.OutData(port, (byte)(targetBaseReg + ope * 3 + 0x80) , ((0 & 0xf) << 4) | (15 & 0xf));//SL RR } break; case 2: // A)ll for (byte ope = 0; ope < 2; ope++) { SetInstAtOneOpeWithoutKslTl(pw, (vch / 3 * 6) + (vch % 3) + ope * 3 , 15, 15, 0, 15, 0, 0, 0, 0, 0, 0); pw.OutData(port, (byte)(targetBaseReg + ope * 3 + 0x40) , ((0 & 0x3) << 6) | 0x3f); //KL(M) TL } break; } int slot1_operatorNumber = (vch / 3 * 6) + (vch % 3) + 0; for (int ope = 0; ope < 2; ope++) { SetInstAtOneOpeWithoutKslTl(pw, slot1_operatorNumber + ope * 3, inst.data[ope * 12 + 3 + 0], inst.data[ope * 12 + 3 + 1], inst.data[ope * 12 + 3 + 2], inst.data[ope * 12 + 3 + 3], inst.data[ope * 12 + 3 + 6], inst.data[ope * 12 + 3 + 7], inst.data[ope * 12 + 3 + 8], inst.data[ope * 12 + 3 + 9], inst.data[ope * 12 + 3 + 10], inst.data[ope * 12 + 3 + 11] ); } //TLはvolumeの設定と一緒に行うがキャリアのみである。 //そのため、CNT0の場合はモジュレータのパラメータをセットする必要がある int cnt = inst.data[1]; if (cnt == 0) { //OP1 pw.OutData(port, (byte)(0x40 + ChnToBaseReg(vch) + 0) , (byte)(((inst.data[12 * 0 + 3 + 4] & 0x3) << 6) | (inst.data[12 * 0 + 3 + 5] & 0x3f))); //KL(M) TL } SetInstAtChannelPanFbCnt(pw, vch, (int)pw.ipan, inst.data[2], inst.data[1]); pw.beforeVolume = -1; }