protected virtual void SetInstAtOneOpeWithoutKslTl(partWork pw, int opeNum, int ar, int dr, int sl, int rr, int mt, int am, int vib, int eg, int kr, int ws ) { //portは18operator毎に切り替わる byte port = this.port[opeNum / 18]; // % 18 ... port毎のoperator番号を得る --- (1) // / 6 ) * 8 ... (1) に対応するアドレスは6opeごとに8アドレス毎に分けられ、 // % 6 ... 0~5アドレスに割り当てられている int adr = ((opeNum % 18) / 6) * 8 + (opeNum % 6); ////slot1かslot2を求める //// % 6 ... slotは6opeの範囲で0か1を繰り返す //// / 3 ... slotは3ope毎に0か1を繰り返す //int slot = (opeNum % 6) / 3; pw.OutData(port, (byte)(0x80 + adr), (byte)(((sl & 0xf) << 4) | (rr & 0xf))); pw.OutData(port, (byte)(0x60 + adr), (byte)(((ar & 0xf) << 4) | (dr & 0xf))); SetInstAtOneOpeAmVibEgKsMl(pw, port, (byte)(0x20 + adr), mt, am, vib, eg, kr); //SOutData(page,mml, port, (byte)(0xe0 + adr), (byte)(ws & 0x7)); }
public void OutSetFnum(partWork pw, int octave, int note, int kf) { octave &= 0x7; note &= 0xf; note = note < 3 ? note : (note < 6 ? (note + 1) : (note < 9 ? (note + 2) : (note + 3))); pw.OutData(pw.port0, (byte)(0x28 + pw.ch), (byte)((octave << 4) | note)); pw.OutData(pw.port0, (byte)(0x30 + pw.ch), (byte)(kf << 2)); }
public void OutKeyOff(partWork pw) { //key off pw.OutData(pw.port0, 0x08, (byte)(0x00 + (pw.ch & 7))); if (pw.ch == 7 && pw.mixer == 1) { pw.OutData(pw.port0, 0x0f, 0x00); } }
public void OutKeyOn(partWork pw) { if (pw.ch == 7 && pw.mixer == 1) { pw.OutData(pw.port0, 0x0f, (byte)((pw.mixer << 7) | (pw.noise & 0x1f))); } //key on pw.OutData(pw.port0, 0x08, (byte)((pw.slots << 3) + pw.ch)); }
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 CmdY(partWork pw, MML mml) { if (mml.args[0] is string toneparamName) { byte op = (byte)(int)mml.args[1]; op = (byte)(op == 1 ? 2 : (op == 2 ? 1 : op)); byte dat = (byte)(int)mml.args[2]; switch (toneparamName) { case "PANFBAL": case "PANFLCON": pw.OutData(pw.port0, (byte)(0x20 + pw.ch), dat); break; case "PMSAMS": pw.OutData(pw.port0, (byte)(0x38 + pw.ch), dat); break; case "DTML": case "DTMUL": case "DT1ML": case "DT1MUL": pw.OutData(pw.port0, (byte)(0x40 + pw.ch + op * 8), dat); break; case "TL": pw.OutData(pw.port0, (byte)(0x60 + pw.ch + op * 8), dat); break; case "KSAR": pw.OutData(pw.port0, (byte)(0x80 + pw.ch + op * 8), dat); break; case "AMDR": case "AMED1R": pw.OutData(pw.port0, (byte)(0xa0 + pw.ch + op * 8), dat); break; case "DT2SR": case "DT2D2R": pw.OutData(pw.port0, (byte)(0xc0 + pw.ch + op * 8), dat); break; case "SLRR": case "D1LRR": pw.OutData(pw.port0, (byte)(0xe0 + pw.ch + op * 8), dat); break; } } else { byte adr = (byte)(int)mml.args[0]; byte dat = (byte)(int)mml.args[1]; pw.OutData(pw.port0, adr, dat); } }
public void OutPsgPort(partWork pw, byte data) { pw.OutData( (byte)(pw.isSecondary ? 0x30 : 0x50) , data ); }
public void OutGGPsgStereoPort(partWork pw, byte data) { pw.OutData( (byte)(pw.isSecondary ? 0x3f : 0x4f) , data ); }
public void OutSetCh6PCMMode(partWork pw, bool sw) { pw.OutData( pw.port0 , 0x2b , (byte)((sw ? 0x80 : 0)) ); }
public void OutSetPMSAMS(partWork pw, int PMS, int AMS) { pw.OutData( pw.port0 , (byte)(0x38 + pw.ch) , (byte)(((PMS & 0x7) << 4) | (AMS & 0x3)) ); }
public void OutSetHardLfoFreq(partWork pw, int freq) { pw.OutData( pw.port0 , 0x18 , (byte)(freq & 0xff) ); }
public void OutSetDt2Sr(partWork pw, int ope, int dt2, int sr) { ope = (ope == 1) ? 2 : ((ope == 2) ? 1 : ope); dt2 &= 3; sr &= 31; pw.OutData(pw.port0, (byte)(0xc0 + pw.ch + ope * 8), (byte)((dt2 << 6) | sr)); }
public virtual void SetInstAtOneOpeAmVibEgKsMl(partWork pw, byte port, byte adr, int ml, int am, int vib, int eg, int kr) { // 0x20 pw.OutData(port, adr, (byte)((am != 0 ? 0x80 : 0) + (vib != 0 ? 0x40 : 0) + (eg != 0 ? 0x20 : 0) + (kr != 0 ? 0x10 : 0) + (ml & 0xf)) ); }
public void OutSetSlRr(partWork pw, int ope, int sl, int rr) { ope = (ope == 1) ? 2 : ((ope == 2) ? 1 : ope); sl &= 15; rr &= 15; pw.OutData(pw.port0, (byte)(0xe0 + pw.ch + ope * 8), (byte)((sl << 4) | rr)); }
public void OutSetKsAr(partWork pw, int ope, int ks, int ar) { ope = (ope == 1) ? 2 : ((ope == 2) ? 1 : ope); ks &= 3; ar &= 31; pw.OutData(pw.port0, (byte)(0x80 + pw.ch + ope * 8), (byte)((ks << 6) | ar)); }
public void OutSetAmDr(partWork pw, int ope, int am, int dr) { ope = (ope == 1) ? 2 : ((ope == 2) ? 1 : ope); am &= 1; dr &= 31; pw.OutData(pw.port0, (byte)(0xa0 + pw.ch + ope * 8), (byte)((am << 7) | dr)); }
public void OutSetPanFeedbackAlgorithm(partWork pw, int pan, int fb, int alg) { pan &= 3; fb &= 7; alg &= 7; pw.OutData(pw.port0, (byte)(0x20 + pw.ch), (byte)((pan << 6) | (fb << 3) | alg)); }
public void OutSetDtMl(partWork pw, int ope, int dt, int ml) { ope = (ope == 1) ? 2 : ((ope == 2) ? 1 : ope); dt &= 7; ml &= 15; pw.OutData(pw.port0, (byte)(0x40 + pw.ch + ope * 8), (byte)((dt << 4) | ml)); }
public void OutSetHardLfoDepth(partWork pw, bool isPMD, int depth) { pw.OutData( pw.port0 , 0x19 , (byte)((isPMD ? 0x80 : 0x00) | (depth & 0x7f)) ); }
public void OutSetTl(partWork pw, int ope, int tl) { ope = (ope == 1) ? 2 : ((ope == 2) ? 1 : ope); tl &= 0x7f; pw.OutData( pw.port0 , (byte)(0x60 + pw.ch + ope * 8) , (byte)tl ); }
protected virtual void SetInstAtChannelPanFbCnt(partWork pw, int chNum, int pan, int fb, int cnt) { //portは9channel毎に切り替わる byte port = this.port[chNum / 9]; pw.OutData(port, (byte)(chNum % 9 + 0xC0), (byte)( ((fb & 0x07) << 1) | (cnt & 0x01) | (pan * 0x10) // PAN(CHA,CHB (CHC,CHDは未使用)) ) ); }
public override void CmdY(partWork pw, MML mml) { if (mml.args[0] is string) { return; } byte adr = (byte)(int)mml.args[0]; byte dat = (byte)(int)mml.args[1]; int p = 0; pw.OutData(pw.port0, adr, dat); }
public override void CmdY(partWork pw, MML mml) { base.CmdY(pw, mml); if (mml.args[0] is string) { return; } byte adr = (byte)mml.args[0]; byte dat = (byte)mml.args[1]; pw.OutData((pw.ch > 2 && pw.ch < 6) ? pw.port1 : pw.port0, adr, dat); }
public void OutSetHardLfo(partWork pw, bool sw, List <int> param) { if (sw) { pw.OutData(pw.port0, 0x1b, (byte)(param[0] & 0x3)); //type pw.OutData(pw.port0, 0x18, (byte)(param[1] & 0xff)); //LFRQ pw.OutData(pw.port0, 0x19, (byte)((param[2] & 0x7f) | 0x80)); //PMD pw.OutData(pw.port0, 0x19, (byte)((param[3] & 0x7f) | 0x00)); //AMD } else { pw.OutData(pw.port0, 0x1b, 0); //type pw.OutData(pw.port0, 0x18, 0); //LFRQ pw.OutData(pw.port0, 0x19, 0x80); //PMD pw.OutData(pw.port0, 0x19, 0x00); //AMD } }
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; }