/// <summary> /// pcmモード切り替え /// </summary> public override void CmdMode(partPage page, MML mml) { int n = (int)mml.args[0]; n = Common.CheckRange(n, 0, 1); OPXchInfo info = new OPXchInfo(page); //groupが0/4/8以外はsync3(pcm only)を使えないようにする if ((info.group & 3) != 0) { return;//無視して終わり(エラーを出さない) } page.pcm = n != 0; parent.OutData(mml, port[0], 0x06, (byte)(0x00 + info.groupAdr), (byte)((page.pcm ? 0x80 : 00) | page.sync));//PFM | Sync }
/// <summary> /// sync切り替えコマンド 's' (本来はSusコマンド) /// </summary> public override void CmdSusOnOff(partPage page, MML mml) { int n = (int)mml.args[0]; n = Common.CheckRange(n, 0, 3); OPXchInfo info = new OPXchInfo(page); //groupが0/4/8以外はsync3(pcm only)を使えないようにする if (n == 3 && (info.group & 3) != 0) { msgBox.setErrMsg(string.Format(msg.get("E31004"), page.ch + 1), mml.line.Lp); return; } page.sync = n; parent.OutData(mml, port[0], 0x06, (byte)(0x00 + info.groupAdr), (byte)((page.pcm ? 0x80 : 00) | page.sync));//PFM | Sync }
public override void MultiChannelCommand(MML mml) { foreach (partWork pw in lstPartWork) { foreach (partPage page in pw.pg) { OPXchInfo info = new OPXchInfo(page); if (page.beforeVolume != page.volume && parent.instOPX.ContainsKey(page.instrument)) { page.beforeVolume = page.volume; OutFmSetVolume(page, mml, page.volume); } SetFmTL(page, mml); if (page.keyOff) { page.keyOff = false; SOutData(page, mml, port[0], (byte)info.bank, (byte)(0x00 + info.groupAdr), 0x00); } if (page.keyOn) { page.keyOn = false; SOutData(page, mml, port[0], (byte)info.bank, (byte)(0x00 + info.groupAdr), 0x01); } if (page.beforeFNum != page.freq) { page.beforeFNum = page.freq; int f = page.freq & 0xfff; int o = (page.freq >> 12) & 0xf; SOutData(page, mml, port[0], (byte)info.bank, (byte)(0xa0 + info.groupAdr), (byte)((o << 4) | ((f >> 8) & 0xf))); SOutData(page, mml, port[0], (byte)info.bank, (byte)(0x90 + info.groupAdr), (byte)f); } } } }
public void OutFmSetVolume(partPage page, MML mml, int vol) { int n = page.instrument; if (!parent.instOPX.ContainsKey(n)) { msgBox.setWrnMsg(string.Format(msg.get("E11000"), n), mml == null?null:mml.line.Lp); return; } OPXchInfo info = new OPXchInfo(page); int opeTL; byte[] inst = parent.instOPX[n].Item2; switch (page.sync) { case 0: //4ope if (inst[0] != 4) //4ope音色のみ { msgBox.setErrMsg( string.Format(msg.get("E31009") , page.sync , n) , mml == null ? null : mml.line.Lp); return; } for (int ope = 0; ope < 4; ope++) { byte opeN = (byte)(ope == 1 ? 2 : (ope == 2 ? 1 : ope)); int opeP = 2 + ope * 15; if (tblCM4[page.algo][ope] == 0) { continue; } opeTL = (127 - vol) + (inst[opeP + 5] & 0x7f); opeTL = Common.CheckRange(opeTL, 0, 127); SOutData(page, mml, port[0], opeN, (byte)(0x40 + info.groupAdr) //TL(7) , (byte)opeTL); } break; case 1: //2ope x 2ope if (inst[0] != 2) //2ope音色のみ { msgBox.setErrMsg( string.Format(msg.get("E31009") , page.sync , n) , mml == null ? null : mml.line.Lp); return; } for (int ope = 0; ope < 2; ope++) { byte opeN = (byte)((ope == 1 ? 2 : (ope == 2 ? 1 : ope)) + info.bankB); int opeP = 2 + ope * 15; if (tblCM2[page.algo][ope] == 0) { continue; } opeTL = (127 - vol) + (inst[opeP + 5] & 0x7f); opeTL = Common.CheckRange(opeTL, 0, 127); SOutData(page, mml, port[0], opeN, (byte)(0x40 + info.groupAdr) //TL(7) , (byte)opeTL); } break; case 2: //3ope if (inst[0] != 3) //3ope音色のみ { msgBox.setErrMsg( string.Format(msg.get("E31009") , page.sync , n) , mml == null ? null : mml.line.Lp); return; } for (int ope = 0; ope < 3; ope++) { byte opeN = (byte)(ope == 1 ? 2 : (ope == 2 ? 1 : ope)); int opeP = 2 + ope * 15; if (tblCM3[page.algo][ope] == 0) { continue; } opeTL = (127 - vol) + (inst[opeP + 5] & 0x7f); opeTL = Common.CheckRange(opeTL, 0, 127); SOutData(page, mml, port[0], opeN, (byte)(0x40 + info.groupAdr) //TL(7) , (byte)opeTL); } break; } }
private void SetInst2Operator(partPage page, MML mml, int n, int modeBeforeSend, int vch) { //sync チェック if (page.sync != 1) { msgBox.setErrMsg(string.Format(msg.get("E31006"), n), mml.line.Lp); return; } byte[] inst = parent.instOPX[n].Item2; OPXchInfo info = new OPXchInfo(vch); switch (modeBeforeSend) { case 0: // N)one break; case 1: // R)R only SOutData(page, mml, port[0], (byte)(0x00 + info.bankB), (byte)(0x80 + info.groupAdr), 0x0f); //SL RR bank1 SOutData(page, mml, port[0], (byte)(0x02 + info.bankB), (byte)(0x80 + info.groupAdr), 0x0f); //SL RR bank3 break; case 2: // A)ll //TBD break; } // AR DR SR RR SL TL KS ML DT WF ACC FB LFO AMS PMS //'@ 031,001,001,001,005,026,000,001,002,000,000,000,000,000,000 ;S1 page.algo = inst[32] & 0xf; page.algo = Common.CheckRange(page.algo, 0, 3); SOutData(page, mml, port[0], (byte)info.bankB, (byte)(0xc0 + info.groupAdr)//ALG , (byte)page.algo); for (int ope = 0; ope < 2; ope++) { byte opeN = (byte)((ope == 1 ? 2 : (ope == 2 ? 1 : ope)) + info.bankB); int opeP = 2 + ope * 15; SOutData(page, mml, port[0], opeN, (byte)(0x10 + info.groupAdr) //LFO(8) , (byte)(inst[opeP + 12] & 0xff)); SOutData(page, mml, port[0], opeN, (byte)(0x20 + info.groupAdr) //AMS(2) PMS(3) LFOWF(2) , (byte)(((inst[opeP + 13] & 0x3) << 6) | (inst[opeP + 14] & 0x3))); SOutData(page, mml, port[0], opeN, (byte)(0x30 + info.groupAdr) //DT(3) ML(4) , (byte)(((inst[opeP + 8] & 0x7) << 4) | (inst[opeP + 7] & 0xf))); SOutData(page, mml, port[0], opeN, (byte)(0x50 + info.groupAdr) //KS(3) AR(5) , (byte)(((inst[opeP + 6] & 0x7) << 5) | (inst[opeP + 0] & 0x1f))); SOutData(page, mml, port[0], opeN, (byte)(0x60 + info.groupAdr) //DR(5) , (byte)(inst[opeP + 1] & 0x1f)); SOutData(page, mml, port[0], opeN, (byte)(0x70 + info.groupAdr) //SR(5) , (byte)(inst[opeP + 2] & 0x1f)); SOutData(page, mml, port[0], opeN, (byte)(0x80 + info.groupAdr) //SL(4) RR(4) , (byte)(((inst[opeP + 4] & 0xf) << 4) | (inst[opeP + 3] & 0xf))); SOutData(page, mml, port[0], opeN, (byte)(0xb0 + info.groupAdr) //ACC(1) FB(3) WF(3) , (byte)(((inst[opeP + 10] & 0x1) << 7) | ((inst[opeP + 11] & 0x7) << 4) | (inst[opeP + 9] & 0x7))); //TLはvolumeの設定と一緒に行うがキャリアのみである。 //そのため、algからモジュレータのパラメータをセットする必要がある if (tblCM2[page.algo][ope] != 0) { continue; } SOutData(page, mml, port[0], opeN, (byte)(0x40 + info.groupAdr)//TL(7) , (byte)(inst[opeP + 5] & 0x7f)); } page.beforeVolume = -1; }
private void SetInst4Operator(partPage page, MML mml, int n, int modeBeforeSend, int vch) { if (page.sync != 0) { msgBox.setErrMsg(string.Format(msg.get("E31003"), n), mml.line.Lp); return; } byte[] inst = parent.instOPX[n].Item2; OPXchInfo info = new OPXchInfo(vch); //byte targetBaseReg = ChnToBaseReg(vch); //byte[] port = getPortFromCh(vch); switch (modeBeforeSend) { case 0: // N)one break; case 1: // R)R only //if (page.opMode == 4) //{ SOutData(page, mml, port[0], 0x00, (byte)(0x80 + info.groupAdr), 0x0f); //SL RR bank1 SOutData(page, mml, port[0], 0x02, (byte)(0x80 + info.groupAdr), 0x0f); //SL RR bank3 SOutData(page, mml, port[0], 0x01, (byte)(0x80 + info.groupAdr), 0x0f); //SL RR bank2 SOutData(page, mml, port[0], 0x03, (byte)(0x80 + info.groupAdr), 0x0f); //SL RR bank4 //} //else if (page.opMode == 3) //{ // SOutData(page, mml, port[0], 0x00, (byte)(0x80 + grpAdr), 0x0f);//SL RR bank1 // SOutData(page, mml, port[0], 0x02, (byte)(0x80 + grpAdr), 0x0f);//SL RR bank3 // SOutData(page, mml, port[0], 0x01, (byte)(0x80 + grpAdr), 0x0f);//SL RR bank2 //} //else if (page.opMode == 2) //{ // SOutData(page, mml, port[0], (byte)(0x00 + bnkB), (byte)(0x80 + grpAdr), 0x0f);//SL RR bank1/2 // SOutData(page, mml, port[0], (byte)(0x02 + bnkB), (byte)(0x80 + grpAdr), 0x0f);//SL RR bank3/4 //} break; case 2: // A)ll //TBD break; } // AR DR SR RR SL TL KS ML DT WF ACC FB LFO AMS PMS //'@ 031,001,001,001,005,026,000,001,002,000,000,000,000,000,000 ;S1 page.algo = inst[62] & 0xf; SOutData(page, mml, port[0], 0, (byte)(0xc0 + info.groupAdr)//ALG , (byte)page.algo); for (int ope = 0; ope < 4; ope++) { byte opeN = (byte)(ope == 1 ? 2 : (ope == 2 ? 1 : ope)); int opeP = 2 + ope * 15; SOutData(page, mml, port[0], opeN, (byte)(0x10 + info.groupAdr) //LFO(8) , (byte)(inst[opeP + 12] & 0xff)); SOutData(page, mml, port[0], opeN, (byte)(0x20 + info.groupAdr) //AMS(2) PMS(3) LFOWF(2) , (byte)(((inst[opeP + 13] & 0x3) << 6) | (inst[opeP + 14] & 0x3))); SOutData(page, mml, port[0], opeN, (byte)(0x30 + info.groupAdr) //DT(3) ML(4) , (byte)(((inst[opeP + 8] & 0x7) << 4) | (inst[opeP + 7] & 0xf))); SOutData(page, mml, port[0], opeN, (byte)(0x50 + info.groupAdr) //KS(3) AR(5) , (byte)(((inst[opeP + 6] & 0x7) << 5) | (inst[opeP + 0] & 0x1f))); SOutData(page, mml, port[0], opeN, (byte)(0x60 + info.groupAdr) //DR(5) , (byte)(inst[opeP + 1] & 0x1f)); SOutData(page, mml, port[0], opeN, (byte)(0x70 + info.groupAdr) //SR(5) , (byte)(inst[opeP + 2] & 0x1f)); SOutData(page, mml, port[0], opeN, (byte)(0x80 + info.groupAdr) //SL(4) RR(4) , (byte)(((inst[opeP + 4] & 0xf) << 4) | (inst[opeP + 3] & 0xf))); SOutData(page, mml, port[0], opeN, (byte)(0xb0 + info.groupAdr) //ACC(1) FB(3) WF(3) , (byte)(((inst[opeP + 10] & 0x1) << 7) | ((inst[opeP + 11] & 0x7) << 4) | (inst[opeP + 9] & 0x7))); //TLはvolumeの設定と一緒に行うがキャリアのみである。 //そのため、algからモジュレータのパラメータをセットする必要がある if (tblCM4[page.algo][ope] != 0) { continue; } SOutData(page, mml, port[0], opeN, (byte)(0x40 + info.groupAdr)//TL(7) , (byte)(inst[opeP + 5] & 0x7f)); } page.beforeVolume = -1; }