public int GetSsgFNum(partPage page, MML mml, int octave, char noteCmd, int shift, int pitchShift) { int o = octave - 1; int n = Const.NOTE.IndexOf(noteCmd) + shift; o += n / 12; o = Common.CheckRange(o, 0, 7); n %= 12; int f = o * 12 + n; if (f < 0) { f = 0; } if (f >= FNumTbl[0].Length) { f = FNumTbl[0].Length - 1; } return(FNumTbl[0][f] + pitchShift); }
public override void CmdInstrument(partWork pw, MML mml) { char type = (char)mml.args[0]; int n = (int)mml.args[1]; if (type == 'n' || type == 'N' || type == 'R' || type == 'A') { if (pw.Type == enmChannelType.FMOPNex) { pw.instrument = n; lstPartWork[2].instrument = n; lstPartWork[3].instrument = n; lstPartWork[4].instrument = n; lstPartWork[5].instrument = n; OutFmSetInstrument(pw, mml, n, pw.volume, type); return; } } base.CmdInstrument(pw, mml); }
public override void MultiChannelCommand(MML mml) { if (!use) { return; } int dat = 0; foreach (partWork pw in lstPartWork) { int p = pw.panL; dat |= (((p & 2) == 0 ? 0x00 : 0x10) | ((p & 1) == 0 ? 0x00 : 0x01)) << pw.ch; } if (beforePanData == dat) { return; } OutGGPsgStereoPort(mml, port[1], (byte)dat); beforePanData = dat; }
public override void CmdLfoSwitch(partPage page, MML mml) { base.CmdLfoSwitch(page, mml); int c = (char)mml.args[0] - 'P'; int n = (int)mml.args[1]; if (page.lfo[c].type == eLfoType.Hardware) { if (n == 0) { page.lfo[c].sw = false; } else { page.lfo[c].sw = true; page.lfo[c].depthWaitCounter = page.lfo[c].param[0]; page.lfo[c].depth = page.lfo[c].param[1]; } } }
public MML Copy() { MML n = new MML(); n.line = line.Copy(); n.column = column; n.type = type; if (args != null) { n.args = new List <object>(); for (int i = 0; i < args.Count; i++) { n.args.Add(args[i]); if (n.args[i].GetType() == typeof(Note)) { n.args[i] = ((Note)n.args[i]).Copy(); } } } return(n); }
/// <summary> /// MIDI CC:Volume をわりあてている /// </summary> public override void CmdTotalVolume(partPage page, MML mml) { int n = (int)mml.args[0]; page.volume = Common.CheckRange(n, 0, page.MaxVolume); MML vmml = new MML(); vmml.type = enmMMLType.TotalVolume; vmml.args = new List <object>(); vmml.args.Add(page.volume); vmml.line = mml.line; SetDummyData(page, vmml); if (page.beforeVolume == page.volume) { return; } page.beforeVolume = page.volume; OutMidiControlChange(page, mml, enmControlChange.Volume, (byte)page.volume); }
public override void SetKeyOn(partWork pw, MML mml) { if (pw.ch < 9) { OutFmKeyOn(pw, mml); } else if (pw.Type == enmChannelType.SSG) { OutSsgKeyOn(pw, mml); } else if (pw.Type == enmChannelType.RHYTHM) { pw.keyOn = true; pw.keyOff = false; SetDummyData(pw, mml); } else if (pw.Type == enmChannelType.ADPCM) { OutAdpcmKeyOn(mml, pw); } }
public override void SetKeyOff(partPage page, MML mml) { return; //for (byte i = 0; i < pw.ppg[pw.cpgNum].tblNoteOn.Length; i++) //{ // if (!pw.ppg[pw.cpgNum].tblNoteOn[i]) continue; // pw.ppg[pw.cpgNum].tblNoteOn[i] = false; // pw.ppg[pw.cpgNum].noteOns[i].Keyon = false; // pw.ppg[pw.cpgNum].noteOns[i].length = 0; // //MIDINote mn = new MIDINote(); // //mn.pw = pw; // //mn.mml = mml; // //mn.noteNumber = i; // //mn.velocity = 0; // //noteOffs.Add(mn); // //OutMidiNoteOn(pw, mml, i, 0); //} }
public void OutYM2612XPcmKeyOFF(MML mml, partPage page) { int id = 0; int ch = Math.Max(0, page.ch - 8); int priority = 0; byte[] cmd; if (parent.info.format == enmFormat.ZGM) { cmd = new byte[] { 0x54, 0x00 } } ; else { cmd = new byte[] { 0x54 } }; if (pcmKeyOnCh[ch & 0x3] == page.ch) { pcmKeyOnCh[ch & 0x3] = 0; pcmKeyOnInstNum[ch & 0x3] = -1; } SOutData( page, mml, cmd // original vgm command : YM2151 , (byte)(0x50 + ((priority & 0x3) << 2) + (ch & 0x3)) , (byte)id ); if (parent.info.vgmVsync == -1) { parent.info.samplesPerClock = parent.info.xgmSamplesPerSecond * 60.0 * 4.0 / (parent.info.tempo * parent.info.clockCount); } else { parent.info.samplesPerClock = parent.info.xgmSamplesPerSecond / parent.info.vgmVsync; } }
public override void CmdLfo(partWork pw, MML mml) { base.CmdLfo(pw, mml); if (mml.args[0] is string) { return; } int c = (char)mml.args[0] - 'P'; if (pw.lfo[c].type == enmLfoType.Hardware) { if (pw.lfo[c].param.Length < 4) { msgBox.setErrMsg(msg.get("E16002"));//, mml.line.Lp); return; } if (pw.lfo[c].param.Length > 5) { msgBox.setErrMsg(msg.get("E16003"));//, mml.line.Lp); return; } pw.lfo[c].param[0] = Common.CheckRange(pw.lfo[c].param[0], 0, 3); //Type pw.lfo[c].param[1] = Common.CheckRange(pw.lfo[c].param[1], 0, 255); //LFRQ pw.lfo[c].param[2] = Common.CheckRange(pw.lfo[c].param[2], 0, 127); //PMD pw.lfo[c].param[3] = Common.CheckRange(pw.lfo[c].param[3], 0, 127); //AMD if (pw.lfo[c].param.Length == 5) { pw.lfo[c].param[4] = Common.CheckRange(pw.lfo[c].param[4], 0, 1); } else { List <int> tmp = pw.lfo[c].param.ToList(); tmp.Add(0); pw.lfo[c].param = tmp.ToArray(); } } }
public override void CmdHardEnvelope(partWork pw, MML mml) { if (pw.Type != enmChannelType.SSG) { return; } string cmd = (string)mml.args[0]; int n = 0; switch (cmd) { case "EH": n = (int)mml.args[1]; if (pw.HardEnvelopeSpeed != n) { parent.OutData(pw.port0, 0x0b, (byte)(n & 0xff)); parent.OutData(pw.port0, 0x0c, (byte)((n >> 8) & 0xff)); pw.HardEnvelopeSpeed = n; } break; case "EHON": pw.HardEnvelopeSw = true; break; case "EHOF": pw.HardEnvelopeSw = false; break; case "EHT": n = (int)mml.args[1]; if (pw.HardEnvelopeType != n) { parent.OutData(pw.port0, 0x0d, (byte)(n & 0xf)); pw.HardEnvelopeType = n; } break; } }
public override void SetLfoAtKeyOn(partPage page, MML mml) { for (int lfo = 0; lfo < 4; lfo++) { clsLfo pl = page.lfo[lfo]; if (!pl.sw) { continue; } if (pl.type == eLfoType.Hardware) { continue; } if (pl.type == eLfoType.Wah) { continue; } if (pl.param[5] != 1) { continue; } pl.isEnd = false; pl.value = (pl.param[0] == 0) ? pl.param[6] : 0;//ディレイ中は振幅補正は適用されない pl.waitCounter = pl.param[0]; pl.direction = pl.param[2] < 0 ? -1 : 1; pl.depthWaitCounter = pl.param[7]; pl.depth = pl.param[3]; pl.depthV2 = pl.param[2]; if (pl.type == eLfoType.Vibrato) { SetFNum(page, mml); } if (pl.type == eLfoType.Tremolo) { SetVolume(page, mml); } } }
public int GetQSoundFNum(MML mml, partPage page, int octave, char noteCmd, int shift) { try { int o = octave - 1; int n = Const.NOTE.IndexOf(noteCmd) + shift; o += n / 12; n %= 12; if (n < 0) { n += 12; o = Common.CheckRange(--o, 0, 7); } if (page.instrument < 0 || !parent.instPCM.ContainsKey(page.instrument)) { return(0); } double freq = (double)parent.instPCM[page.instrument].Item2.samplerate; if (parent.instPCM[page.instrument].Item2.freq != -1) { freq = (double)parent.instPCM[page.instrument].Item2.freq; } return((int)( 4000000.0 * Const.pcmMTbl[n] * Math.Pow(2, o) * (freq / 8000.0) / Frequency * 166.0 //div )); } catch { return(0); } }
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 override void SetVolume(partWork pw, MML mml) { int vol = pw.volume; if (pw.envelopeMode) { vol = 0; if (pw.envIndex != -1) { vol = pw.envVolume - (pw.MaxVolume - pw.volume); } } //Console.WriteLine("{0} ", pw.envVolume); for (int lfo = 0; lfo < 4; lfo++) { if (!pw.lfo[lfo].sw) { continue; } if (pw.lfo[lfo].type != eLfoType.Tremolo) { continue; } vol += pw.lfo[lfo].value + pw.lfo[lfo].param[6]; } byte data = (byte)Common.CheckRange(vol, 0, 127); if (pw.beforeVolume != data) { byte adr = (byte)((pw.ch + 1) * 8 + 0x07); OutK053260Port(mml, port[0], pw , adr , data ); pw.beforeVolume = data; } SetDummyData(pw, mml); }
public virtual void CmdLyric(partWork pw, MML mml) { string str = (string)mml.args[0]; int ml = (int)mml.args[1]; if (ml < 1) { msgBox.setErrMsg(msg.get("E10013") , mml.line.Fn , mml.line.Num ); ml = (int)pw.length; } str = string.Format("[{0}]{1}", parent.dSample.ToString(), str); parent.lyric += str; //WaitClockの決定 pw.waitCounter = parent.GetWaitCounter(ml); pw.tie = false; //pw.clockCounter += pw.waitCounter; }
public int GetK053260FNum(MML mml, partPage page, int octave, char noteCmd, int shift) { try { int o = octave - 1; int n = Const.NOTE.IndexOf(noteCmd) + shift; o += n / 12; n %= 12; if (n < 0) { n += 12; o = Common.CheckRange(--o, 0, 7); } if (page.instrument < 0 || !parent.instPCM.ContainsKey(page.instrument)) { return(0); } double freq = (double)parent.instPCM[page.instrument].Item2.samplerate; if (parent.instPCM[page.instrument].Item2.freq != -1) { freq = (double)parent.instPCM[page.instrument].Item2.freq; } if (currentBaseFreq != freq) { MakeFreqTable(freq); currentBaseFreq = freq; } return(n2f[(o + 1) * 12 + n]);//0xe41; } catch { return(0); } }
public override void SetVolume(partWork pw, MML mml) { int vol = pw.volume; if (pw.envelopeMode) { vol = 0; if (pw.envIndex != -1) { vol = pw.envVolume - (pw.MaxVolume - pw.volume); } } //Console.WriteLine("{0} ", pw.envVolume); for (int lfo = 0; lfo < 4; lfo++) { if (!pw.lfo[lfo].sw) { continue; } if (pw.lfo[lfo].type != eLfoType.Tremolo) { continue; } vol += pw.lfo[lfo].value + pw.lfo[lfo].param[6]; } int data = Common.CheckRange(vol, 0, 65535); if (pw.beforeVolume != data) { byte adr = (byte)((pw.ch << 3) + 0x06); OutQSoundPort(mml, port[0], pw , adr , (ushort)data ); pw.beforeVolume = data; } }
public override void CmdInstrument(partPage page, MML mml) { char type; bool re = false; int n; if (mml.args[0] is bool) { type = (char)mml.args[1]; re = true; n = (int)mml.args[2]; } else { type = (char)mml.args[0]; n = (int)mml.args[1]; } if (type == 'n' || type == 'N' || type == 'R' || type == 'A') { if (page.Type == enmChannelType.FMOPNex) { if (re) { n = page.instrument + n; } n = Common.CheckRange(n, 0, 255); page.instrument = n; lstPartWork[2].cpg.instrument = n; lstPartWork[3].cpg.instrument = n; lstPartWork[4].cpg.instrument = n; lstPartWork[5].cpg.instrument = n; OutFmSetInstrument(page, mml, n, page.volume, type); return; } } base.CmdInstrument(page, mml); }
public override void CmdPan(partWork pw, MML mml) { int n = (int)mml.args[0]; if (pw.Type == enmChannelType.FMOPN || pw.Type == enmChannelType.FMOPNex) { n = Common.CheckRange(n, 0, 3); pw.pan.val = n; ((ClsOPN)pw.chip).OutOPNSetPanAMSPMS(mml, pw, n, pw.ams, pw.fms); } else if (pw.Type == enmChannelType.ADPCMA) { n = Common.CheckRange(n, 0, 3); pw.pan.val = n; } else if (pw.Type == enmChannelType.ADPCMB) { n = Common.CheckRange(n, 0, 3); ((YM2610B)pw.chip).SetAdpcmBPan(mml, pw, n); } SetDummyData(pw, mml); }
public override void CmdPan(partWork pw, MML mml) { int n = (int)mml.args[0]; n = Common.CheckRange(n, 0, 3); pw.pan.val = (n == 1) ? 2 : (n == 2 ? 1 : n); if (pw.instrument < 0) { msgBox.setErrMsg(msg.get("E16004") , mml.line.Lp); } else { ((YM2151)pw.chip).OutSetPanFeedbackAlgorithm( mml, pw , (int)pw.pan.val , parent.instFM[pw.instrument][46] , parent.instFM[pw.instrument][45] ); } }
public override void CmdPan(partPage page, MML mml) { int n = (int)mml.args[0]; n = Common.CheckRange(n, 0, 3); page.pan = (n == 1) ? 2 : (n == 2 ? 1 : n); if (page.instrument < 0) { msgBox.setErrMsg(msg.get("E16004") , mml.line.Lp); } else { ((YM2151)page.chip).OutSetPanFeedbackAlgorithm( mml, page , (int)page.pan , parent.instOPM[page.instrument].Item2[46] , parent.instOPM[page.instrument].Item2[45] ); } }
public int GetSsgHsFNum(partPage page, MML mml, int octave, char noteCmd, int shift) { int o = octave - 1; int n = Const.NOTE.IndexOf(noteCmd) + shift; o += n / 12; o = Common.CheckRange(o, 1, 6); n %= 12; int f = o * 12 + n; if (f < 0) { f = 0; } if (f >= hsFnumTbl.Length) { f = hsFnumTbl.Length - 1; } return(hsFnumTbl[f]); }
public void SetLFOParamFromInstrument(partWork pw, int n, MML mml) { if (!parent.instSSG.ContainsKey(n)) { msgBox.setErrMsg(string.Format(msg.get("E10000"), n) , mml.line.Fn , mml.line.Num); return; } if (parent.instSSG[n].M == null || parent.instSSG[n].M.Length < 1) { return; } pw.lfo[0].type = enmLfoType.Vibrato; pw.lfo[0].sw = true; for (int i = 0; i < Math.Min(parent.instSSG[n].M.Length, 4); i++) { pw.lfo[0].param[i] = parent.instSSG[n].M[i]; } }
public override void SetVolume(partPage page, MML mml) { int vol = page.volume; if (page.envelopeMode) { vol = 0; if (page.envIndex != -1) { vol = page.envVolume - (page.MaxVolume - page.volume); } } for (int lfo = 0; lfo < 4; lfo++) { if (!page.lfo[lfo].sw) { continue; } if (page.lfo[lfo].type != eLfoType.Tremolo) { continue; } vol += page.lfo[lfo].value + page.lfo[lfo].param[6]; } if (page.varpeggioMode) { vol += page.varpDelta; } vol = Common.CheckRange(vol, 0, 255); if (page.beforeVolume != vol) { SetRf5c164Envelope(mml, page, vol); page.beforeVolume = vol; } }
protected override void SetInstAtOneOpeWithoutKslTl(partPage page, MML mml, int opeNum, int ar, int dr, int sl, int rr, int mt, int am, int vib, int eg, int kr, int ws ) { // % 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; SOutData(page, mml, port[0], (byte)(0x80 + adr), (byte)(((sl & 0xf) << 4) | (rr & 0xf))); SOutData(page, mml, port[0], (byte)(0x60 + adr), (byte)(((ar & 0xf) << 4) | (dr & 0xf))); SetInstAtOneOpeAmVibEgKsMl(page, mml, port[0], (byte)(0x20 + adr), mt, am, vib, eg, kr); //SOutData(page, mml, port, (byte)(0xe0 + adr), (byte)(ws & 0x3)); Y8950はOPL(YM3526)なのでwsなし }
public override void SetVolume(partPage page, MML mml) { base.SetVolume(page, mml); if (page.Type == enmChannelType.ADPCMA) { } else if (page.Type == enmChannelType.ADPCMB) { SetAdpcmBVolume(mml, page); } if (mml != null) { MML vmml = new MML(); vmml.type = enmMMLType.Volume; vmml.args = new List <object>(); vmml.args.Add(page.volume); vmml.line = mml.line; SetDummyData(page, vmml); } }
public void SetSsgFNum(partWork pw, MML mml) { int f = GetSsgFNum(pw, mml, pw.octaveNow, pw.noteCmd, pw.shift + pw.keyShift);// if (pw.bendWaitCounter != -1) { f = pw.bendFnum; } f = f + pw.detune; for (int lfo = 0; lfo < 4; lfo++) { if (!pw.lfo[lfo].sw) { continue; } if (pw.lfo[lfo].type != eLfoType.Vibrato) { continue; } f += pw.lfo[lfo].value + pw.lfo[lfo].param[6]; } f = Common.CheckRange(f, 0, 0xfff); if (pw.freq == f) { return; } pw.freq = f; byte data = 0; data = (byte)(f & 0xff); parent.OutData(mml, port[0], (byte)(0 + pw.ch * 2), data); data = (byte)((f & 0xf00) >> 8); parent.OutData(mml, port[0], (byte)(1 + pw.ch * 2), data); }
public override void MultiChannelCommand(MML mml) { foreach (partWork pw in lstPartWork) { partPage page = pw.cpg; CurrentChannel = 255; if (page.keyOff) { page.keyOff = false; OutHuC6280KeyOff(mml, page); } if (page.keyOn) { page.keyOn = false; OutHuC6280KeyOn(mml, page); } SetFNum(page, null); OutHuC6280FNum(page, mml); if (page.keyOff) { if (!page.envelopeMode && !page.varpeggioMode) { page.beforeVolume = 0; } } OutHuC6280Volume(page, mml); } //PCMをストリームの機能を使用し再生するため、1Frame毎にカレントチャンネル情報が破壊される。よって次のフレームでリセットできるようにする。 if (use) { CurrentChannel = 255; } }
public virtual void CmdEnvelope(partWork pw, MML mml) { pw.envInstrument = -1; pw.envIndex = -1; pw.envCounter = -1; for (int i = 0; i < mml.args.Count; i++) { pw.envelope[i] = (int)mml.args[i]; } pw.envelopeMode = true; //if (!(mml.args[0] is string)) //{ // msgBox.setErrMsg(msg.get("E10010") // , mml.line.Fn // , mml.line.Num); // return; //} //string cmd = (string)mml.args[0]; //switch (cmd) //{ // case "EON": // pw.envelopeMode = true; // break; // case "EOF": // pw.envelopeMode = false; // if (pw.Type == enmChannelType.SSG) // { // pw.beforeVolume = -1; // } // break; //} //return; }