incPos() public method

解析位置を一つ進める(重い!)
public incPos ( ) : void
return void
Esempio n. 1
0
 private void cmdRepeatEnd(partWork pw)
 {
     int n;
     pw.incPos();
     if (!pw.getNum(out n))
     {
         n = 2;
     }
     n = checkRange(n, 1, 255);
     try
     {
         clsRepeat re = pw.stackRepeat.Pop();
         if (re.repeatCount == -1)
         {
             //初回
             re.repeatCount = n;
         }
         re.repeatCount--;
         if (re.repeatCount > 0)
         {
             pw.stackRepeat.Push(re);
             pw.setPos(re.pos);
         }
     }
     catch
     {
         msgBox.setWrnMsg("[と]の数があいません。", lineNumber);
     }
 }
Esempio n. 2
0
 private void cmdGatetime2(partWork pw)
 {
     int n;
     pw.incPos();
     if (!pw.getNum(out n))
     {
         msgBox.setErrMsg("不正なゲートタイム指定'Q'が指定されています。", lineNumber);
         n = 1;
     }
     n = checkRange(n, 1, 8);
     pw.gatetime = n;
     pw.gatetimePmode = true;
 }
Esempio n. 3
0
        private void cmdPan(partWork pw)
        {
            int n;
            int vch = pw.ch;

            pw.incPos();
            if (pw.chip is YM2610B)
            {
                if (pw.Type == enmChannelType.FMOPN || pw.Type == enmChannelType.FMOPNex)
                {
                    //効果音モードのチャンネル番号を指定している場合は3chへ変更する
                    if (pw.ch >= 6 && pw.ch <= 8)
                    {
                        vch = 2;
                    }

                    if (!pw.getNum(out n))
                    {
                        msgBox.setErrMsg("不正なパン'p'が指定されています。", lineNumber);
                        n = 3;
                    }
                    //強制的にモノラルにする
                    if (monoPart != null && monoPart.Contains(ym2612[0].Ch[5].Name))
                    {
                        n = 3;
                    }
                    n = checkRange(n, 1, 3);
                    pw.pan = n;
                    outOPNSetPanAMSFMS(pw, n, pw.ams, pw.fms);
                }
                else if (pw.Type == enmChannelType.ADPCMA)
                {
                    if (!pw.getNum(out n))
                    {
                        msgBox.setErrMsg("不正なパン'p'が指定されています。", lineNumber);
                        n = 3;
                    }
                    n = checkRange(n, 0, 3);
                    pw.pan = n;
                }
                else if (pw.Type == enmChannelType.ADPCMB)
                {
                    if (!pw.getNum(out n))
                    {
                        msgBox.setErrMsg("不正なパン'p'が指定されています。", lineNumber);
                        n = 3;
                    }
                    n = checkRange(n, 0, 3);
                    setAdpcmBPan(pw, n);
                }
            }
            else if (pw.chip is YM2612)
            {
                //効果音モードのチャンネル番号を指定している場合は3chへ変更する
                if (pw.ch >= 6 && pw.ch <= 8)
                {
                    vch = 2;
                }

                if (!pw.getNum(out n))
                {
                    msgBox.setErrMsg("不正なパン'p'が指定されています。", lineNumber);
                    n = 10;
                }
                //強制的にモノラルにする
                if (monoPart != null && monoPart.Contains(ym2612[0].Ch[5].Name))
                {
                    n = 3;
                }
                n = checkRange(n, 1, 3);
                pw.pan = n;
                outOPNSetPanAMSFMS(pw, n, pw.ams, pw.fms);
            }
            else if (pw.chip is SN76489)
            {
                pw.getNum(out n);
                msgBox.setWrnMsg("PSGパートでは、pコマンドは無視されます。", lineNumber);
            }
            else if (pw.chip is RF5C164)
            {
                int l;
                int r;
                if (!pw.getNum(out l))
                {
                    msgBox.setErrMsg("不正なパン'p'が指定されています。", lineNumber);
                    l = 15;
                }
                if (pw.getChar() != ',')
                {
                    msgBox.setErrMsg("不正なパン'p'が指定されています。", lineNumber);
                    l = 15;
                    r = 15;
                }
                pw.incPos();
                if (!pw.getNum(out r))
                {
                    msgBox.setErrMsg("不正なパン'p'が指定されています。", lineNumber);
                    r = 15;
                }
                l = checkRange(l, 0, 15);
                r = checkRange(r, 0, 15);
                pw.pan = (r << 4) | l;
                setRf5c164CurrentChannel(pw);
                setRf5c164Pan(pw, pw.pan);
            }
        }
Esempio n. 4
0
 private void commander(partWork pw, char cmd)
 {
     switch (cmd)
     {
         case ' ':
         case '\t':
             pw.incPos();
             break;
         case '!': // CompileSkip
             pw.dataEnd = true;
             pw.waitCounter = -1;
             break;
         case 'T': // tempo
             cmdTempo(pw);
             break;
         case '@': // instrument
             cmdInstrument(pw);
             break;
         case 'v': // volume
             cmdVolume(pw);
             break;
         case 'V': // totalVolume(Adpcm-A / Rhythm)
             cmdTotalVolume(pw);
             break;
         case 'o': // octave
             cmdOctave(pw);
             break;
         case '>': // octave Up
             cmdOctaveUp(pw);
             break;
         case '<': // octave Down
             cmdOctaveDown(pw);
             break;
         case ')': // volume Up
             cmdVolumeUp(pw);
             break;
         case '(': // volume Down
             cmdVolumeDown(pw);
             break;
         case 'l': // length
             cmdLength(pw);
             break;
         case '#': // length(clock)
             cmdClockLength(pw);
             break;
         case 'p': // pan
             cmdPan(pw);
             break;
         case 'D': // Detune
             cmdDetune(pw);
             break;
         case 'm': // pcm mode
             cmdMode(pw);
             break;
         case 'q': // gatetime
             cmdGatetime(pw);
             break;
         case 'Q': // gatetime
             cmdGatetime2(pw);
             break;
         case 'E': // envelope
             cmdEnvelope(pw);
             break;
         case 'L': // loop point
             cmdLoop(pw);
             break;
         case '[': // repeat
             cmdRepeatStart(pw);
             break;
         case ']': // repeat
             cmdRepeatEnd(pw);
             break;
         case '/': // repeat
             cmdRepeatExit(pw);
             break;
         case 'M': // lfo
             cmdLfo(pw);
             break;
         case 'S': // lfo switch
             cmdLfoSwitch(pw);
             break;
         case 'y': // y
             cmdY(pw);
             break;
         case 'w': // noise
             cmdNoise(pw);
             break;
         case 'P': // noise or tone mixer
             cmdMixer(pw);
             break;
         case 'K': // key shift
             cmdKeyShift(pw);
             break;
         case 'c':
         case 'd':
         case 'e':
         case 'f':
         case 'g':
         case 'a':
         case 'b':
         case 'r':
             cmdNote(pw, cmd);
             break;
         default:
             msgBox.setErrMsg(string.Format("未知のコマンド{0}を検出しました。", cmd), pw.getLineNumber());
             pw.incPos();
             break;
     }
 }
Esempio n. 5
0
 private void cmdDetune(partWork pw)
 {
     int n;
     pw.incPos();
     if (!pw.getNum(out n))
     {
         msgBox.setErrMsg("不正なディチューン'D'が指定されています。", lineNumber);
         n = 0;
     }
     n = checkRange(n, -127, 127);
     pw.detune = n;
 }
Esempio n. 6
0
 private void cmdTempo(partWork pw)
 {
     int n;
     pw.incPos();
     if (!pw.getNum(out n))
     {
         msgBox.setErrMsg("不正なテンポが指定されています。", lineNumber);
         n = 120;
     }
     n = checkRange(n, 1, 255);
     tempo = n;
     samplesPerClock = vgmSamplesPerSecond * 60 * 4 / (tempo * clockCount);
 }
Esempio n. 7
0
 private void cmdVolumeUp(partWork pw)
 {
     int n;
     pw.incPos();
     if (!pw.getNum(out n))
     {
         msgBox.setErrMsg("不正な音量')'が指定されています。", lineNumber);
         n = 10;
     }
     n = checkRange(n, 1, pw.MaxVolume);
     pw.volume += n;
     n = checkRange(n, 0, pw.MaxVolume);
 }
Esempio n. 8
0
        private void cmdMixer(partWork pw)
        {
            int n = -1;
            pw.incPos();

            if (pw.Type == enmChannelType.SSG)
            {
                if (pw.getNum(out n))
                {
                    n = checkRange(n, 0, 3);
                    pw.mixer = n;
                }
                else
                {
                    msgBox.setErrMsg("wコマンドに指定された値が不正です。", lineNumber);
                    return;

                }
            }
            else
            {
                msgBox.setErrMsg("このチャンネルではPコマンドは使用できません。", lineNumber);
                return;
            }
        }
Esempio n. 9
0
 private void cmdMode(partWork pw)
 {
     int n;
     pw.incPos();
     if (pw.chip is YM2612 && pw.Type == enmChannelType.FMPCM)
     {
         if (!pw.getNum(out n))
         {
             msgBox.setErrMsg("不正なPCMモード指定'm'が指定されています。", lineNumber);
             n = 0;
         }
         n = checkRange(n, 0, 1);
         pw.pcm = (n == 1);
         pw.freq = -1;//freqをリセット
         outYM2612SetCh6PCMMode(pw, pw.pcm);
     }
     else
     {
         pw.getNum(out n);
         msgBox.setWrnMsg("このパートは6chではないため、mコマンドは無視されます。", lineNumber);
     }
 }
Esempio n. 10
0
        private void cmdLfoSwitch(partWork pw)
        {
            pw.incPos();
            char c = pw.getChar();
            if (c < 'P' && c > 'S')
            {
                msgBox.setErrMsg("指定できるLFOのチャネルはP,Q,R,Sの4種類です。", lineNumber);
                return;
            }
            c -= 'P';

            int n = -1;
            pw.incPos();
            if (!pw.getNum(out n))
            {
                msgBox.setErrMsg("LFOの設定値に不正な値が指定されました。", lineNumber);
                return;
            }
            n = checkRange(n, 0, 2);

            //解析 ここまで

            pw.lfo[c].sw = (n == 0) ? false : true;
            if (pw.lfo[c].type == eLfoType.Hardware && pw.lfo[c].param != null)
            {
                if (pw.chip is YM2612)
                {
                    if (pw.lfo[c].param[4] == 0)
                    {
                        outOPNSetHardLfo(pw, (n == 0) ? false : true, pw.lfo[c].param[1]);
                    }
                    else
                    {
                        outOPNSetHardLfo(pw, false, pw.lfo[c].param[1]);
                    }
                }
            }
        }
Esempio n. 11
0
        private void cmdLoop(partWork pw)
        {
            pw.incPos();
            loopOffset = (long)dat.Count;
            loopSamples = lSample;

            foreach (clsChip chip in chips)
            {
                foreach (partWork p in chip.lstPartWork)
                {
                    p.freq = -1;

                    if (p.chip is RF5C164 && rf5c164[p.isSecondary ? 1 : 0].use)
                    {
                        //rf5c164の設定済み周波数値を初期化(ループ時に直前の周波数を引き継いでしまうケースがあるため)
                        p.rf5c164AddressIncrement = -1;
                        int n = p.instrument;
                        p.pcmStartAddress = -1;
                        p.pcmLoopAddress = -1;
                        if (n != -1)
                        {
                            setRf5c164CurrentChannel(p);
                            setRf5c164SampleStartAddress(p, (int)instPCM[n].stAdr);
                            setRf5c164LoopAddress(p, (int)(instPCM[n].loopAdr));
                        }
                    }
                }
            }
        }
Esempio n. 12
0
        private void cmdLfo(partWork pw)
        {
            pw.incPos();
            char c = pw.getChar();
            if (c < 'P' && c > 'S')
            {
                msgBox.setErrMsg("指定できるLFOのチャネルはP,Q,R,Sの4種類です。", lineNumber);
                return;
            }
            c -= 'P';

            pw.incPos();
            char t = pw.getChar();
            if (t != 'T' && t != 'V' && t != 'H')
            {
                msgBox.setErrMsg("指定できるLFOの種類はT,V,Hの3種類です。", lineNumber);
                return;
            }
            pw.lfo[c].type = (t == 'T') ? eLfoType.Tremolo : ((t == 'V') ? eLfoType.Vibrato : eLfoType.Hardware);

            pw.lfo[c].sw = false;
            pw.lfo[c].isEnd = true;

            pw.lfo[c].param = new List<int>();
            int n = -1;
            do
            {
                pw.incPos();
                if (pw.getNum(out n))
                {
                    pw.lfo[c].param.Add(n);
                }
                else
                {
                    msgBox.setErrMsg("LFOの設定値に不正な値が指定されました。", lineNumber);
                    return;
                }

                while (pw.getChar() == '\t' || pw.getChar() == ' ') { pw.incPos(); }

            } while (pw.getChar() == ',');
            if (pw.lfo[c].type == eLfoType.Tremolo || pw.lfo[c].type == eLfoType.Vibrato)
            {
                if (pw.lfo[c].param.Count < 4)
                {
                    msgBox.setErrMsg("LFOの設定に必要なパラメータが足りません。", lineNumber);
                    return;
                }
                if (pw.lfo[c].param.Count > 7)
                {
                    msgBox.setErrMsg("LFOの設定に可能なパラメータ数を超えて指定されました。", lineNumber);
                    return;
                }

                pw.lfo[c].param[0] = checkRange(pw.lfo[c].param[0], 0, (int)clockCount);
                pw.lfo[c].param[1] = checkRange(pw.lfo[c].param[1], 1, 255);
                pw.lfo[c].param[2] = checkRange(pw.lfo[c].param[2], -32768, 32787);
                pw.lfo[c].param[3] = Math.Abs(checkRange(pw.lfo[c].param[3], -32768, 32787));
                if (pw.lfo[c].param.Count > 4)
                {
                    pw.lfo[c].param[4] = checkRange(pw.lfo[c].param[4], 0, 4);
                }
                else
                {
                    pw.lfo[c].param.Add(0);
                }
                if (pw.lfo[c].param.Count > 5)
                {
                    pw.lfo[c].param[5] = checkRange(pw.lfo[c].param[5], 0, 1);
                }
                else
                {
                    pw.lfo[c].param.Add(1);
                }
                if (pw.lfo[c].param.Count > 6)
                {
                    pw.lfo[c].param[6] = checkRange(pw.lfo[c].param[6], -32768, 32787);
                }
                else
                {
                    pw.lfo[c].param.Add(0);
                }

            }
            else
            {
                if (pw.lfo[c].param.Count < 4)
                {
                    msgBox.setErrMsg("LFOの設定に必要なパラメータが足りません。", lineNumber);
                    return;
                }
                if (pw.lfo[c].param.Count > 5)
                {
                    msgBox.setErrMsg("LFOの設定に可能なパラメータ数を超えて指定されました。", lineNumber);
                    return;
                }

                pw.lfo[c].param[0] = checkRange(pw.lfo[c].param[0], 0, (int)clockCount);
                pw.lfo[c].param[1] = checkRange(pw.lfo[c].param[1], 0, 7);
                pw.lfo[c].param[2] = checkRange(pw.lfo[c].param[2], 0, 7);
                pw.lfo[c].param[3] = checkRange(pw.lfo[c].param[3], 0, 3);
                if (pw.lfo[c].param.Count == 5)
                {
                    pw.lfo[c].param[4] = checkRange(pw.lfo[c].param[4], 0, 1);
                }
                else
                {
                    pw.lfo[c].param.Add(1);
                }

            }
            //解析 ここまで

            pw.lfo[c].sw = true;
            pw.lfo[c].isEnd = false;
            pw.lfo[c].value = (pw.lfo[c].param[0] == 0) ? pw.lfo[c].param[6] : 0;//ディレイ中は振幅補正は適用されない
            pw.lfo[c].waitCounter = pw.lfo[c].param[0];
            pw.lfo[c].direction = pw.lfo[c].param[2] < 0 ? -1 : 1;
        }
Esempio n. 13
0
        private void cmdKeyShift(partWork pw)
        {
            int n = -1;
            pw.incPos();

            if (pw.getNum(out n))
            {
                pw.keyShift = checkRange(n, -128, 128);
            }
            else
            {
                msgBox.setErrMsg("Kコマンドに指定された値が不正です。", lineNumber);
                return;

            }
        }
Esempio n. 14
0
        private void cmdInstrument(partWork pw)
        {
            int n;
            pw.incPos();

            if (pw.chip is YM2610B)
            {
                if (pw.ch < 9)
                {
                    if (!pw.getNum(out n))
                    {
                        msgBox.setErrMsg("不正な音色番号が指定されています。", lineNumber);
                        n = 0;
                    }
                    n = checkRange(n, 0, 255);
                    if (pw.instrument != n)
                    {
                        pw.instrument = n;
                        if (pw.Type == enmChannelType.FMOPNex)
                        {
                            ym2610b[pw.chip.ChipID].lstPartWork[2].instrument = n;
                            ym2610b[pw.chip.ChipID].lstPartWork[6].instrument = n;
                            ym2610b[pw.chip.ChipID].lstPartWork[7].instrument = n;
                            ym2610b[pw.chip.ChipID].lstPartWork[8].instrument = n;
                        }
                        if (!pw.pcm)
                        {
                            outFmSetInstrument(pw, n, pw.volume);
                        }
                        else
                        {
                            if (!instPCM.ContainsKey(n))
                            {
                                msgBox.setErrMsg(string.Format("PCM定義に指定された音色番号({0})が存在しません。", n), lineNumber);
                            }
                            else
                            {
                                if (instPCM[n].chip != enmChipType.YM2610B)
                                {
                                    msgBox.setErrMsg(string.Format("指定された音色番号({0})はYM2610B向けPCMデータではありません。", n), lineNumber);
                                }
                            }
                        }
                    }
                }
                else if (pw.Type == enmChannelType.SSG)
                {
                    n = setEnvelopParamFromInstrument(pw);
                }
                else if (pw.Type == enmChannelType.ADPCMA)
                {
                    if (pw.getChar() != 'E')
                    {
                        if (!pw.getNum(out n))
                        {
                            msgBox.setErrMsg("不正な音色番号が指定されています。", lineNumber);
                            n = 0;
                        }
                        n = checkRange(n, 0, 255);
                        if (!instPCM.ContainsKey(n))
                        {
                            msgBox.setErrMsg(string.Format("PCM定義に指定された音色番号({0})が存在しません。", n), lineNumber);
                        }
                        else
                        {
                            if (instPCM[n].chip != enmChipType.YM2610B || instPCM[n].loopAdr != 0)
                            {
                                msgBox.setErrMsg(string.Format("指定された音色番号({0})はYM2610B向けPCMデータではありません。", n), lineNumber);
                            }
                            pw.instrument = n;
                            setYM2610BADPCMAAddress(pw, (int)instPCM[n].stAdr, (int)instPCM[n].edAdr);
                        }
                    }
                    else
                    {
                        pw.incPos();
                        n = setEnvelopParamFromInstrument(pw);
                    }
                }
                else if (pw.Type == enmChannelType.ADPCMB)
                {
                    if (pw.getChar() != 'E')
                    {
                        if (!pw.getNum(out n))
                        {
                            msgBox.setErrMsg("不正な音色番号が指定されています。", lineNumber);
                            n = 0;
                        }
                        n = checkRange(n, 0, 255);
                        if (!instPCM.ContainsKey(n))
                        {
                            msgBox.setErrMsg(string.Format("PCM定義に指定された音色番号({0})が存在しません。", n), lineNumber);
                        }
                        else
                        {
                            if (instPCM[n].chip != enmChipType.YM2610B || instPCM[n].loopAdr != 1)
                            {
                                msgBox.setErrMsg(string.Format("指定された音色番号({0})はYM2610B向けPCMデータではありません。", n), lineNumber);
                            }
                            pw.instrument = n;
                            setYM2610BADPCMBAddress(pw, (int)instPCM[n].stAdr, (int)instPCM[n].edAdr);
                        }
                    }
                    else
                    {
                        pw.incPos();
                        n = setEnvelopParamFromInstrument(pw);
                    }
                }
            }
            else if (pw.chip is YM2612)
            {
                if (!pw.getNum(out n))
                {
                    msgBox.setErrMsg("不正な音色番号が指定されています。", lineNumber);
                    n = 0;
                }
                n = checkRange(n, 0, 255);
                if (pw.instrument != n)
                {
                    pw.instrument = n;
                    if (pw.Type == enmChannelType.FMOPNex)
                    {
                        ym2612[pw.chip.ChipID].lstPartWork[2].instrument = n;
                        ym2612[pw.chip.ChipID].lstPartWork[6].instrument = n;
                        ym2612[pw.chip.ChipID].lstPartWork[7].instrument = n;
                        ym2612[pw.chip.ChipID].lstPartWork[8].instrument = n;
                    }
                    if (!pw.pcm)
                    {
                        outFmSetInstrument(pw, n, pw.volume);
                    }
                    else
                    {
                        if (!instPCM.ContainsKey(n))
                        {
                            msgBox.setErrMsg(string.Format("PCM定義に指定された音色番号({0})が存在しません。", n), lineNumber);
                        }
                        else
                        {
                            if (instPCM[n].chip != enmChipType.YM2612)
                            {
                                msgBox.setErrMsg(string.Format("指定された音色番号({0})はYM2612向けPCMデータではありません。", n), lineNumber);
                            }
                        }
                    }
                }
            }
            else if (pw.chip is SN76489)
            {
                //pw.incPos();
                n = setEnvelopParamFromInstrument(pw);
            }
            else if (pw.chip is RF5C164)
            {
                if (pw.getChar() != 'E')
                {
                    if (!pw.getNum(out n))
                    {
                        msgBox.setErrMsg("不正な音色番号が指定されています。", lineNumber);
                        n = 0;
                    }
                    n = checkRange(n, 0, 255);
                    if (!instPCM.ContainsKey(n))
                    {
                        msgBox.setErrMsg(string.Format("PCM定義に指定された音色番号({0})が存在しません。", n), lineNumber);
                    }
                    else
                    {
                        if (instPCM[n].chip != enmChipType.RF5C164)
                        {
                            msgBox.setErrMsg(string.Format("指定された音色番号({0})はRF5C164向けPCMデータではありません。", n), lineNumber);
                        }
                        pw.instrument = n;
                        setRf5c164CurrentChannel(pw);
                        setRf5c164SampleStartAddress(pw, (int)instPCM[n].stAdr);
                        setRf5c164LoopAddress(pw, (int)(instPCM[n].loopAdr));
                    }
                }
                else
                {
                    pw.incPos();
                    n = setEnvelopParamFromInstrument(pw);
                }
            }
        }
Esempio n. 15
0
 private void cmdRepeatExit(partWork pw)
 {
     int n = -1;
     pw.incPos();
     clsRepeat rx = pw.stackRepeat.Pop();
     if (rx.repeatCount == 1)
     {
         int i = 0;
         while (true)
         {
             char c = pw.getChar();
             if (c == ']')
             {
                 if (i == 0)
                 {
                     break;
                 }
                 else
                     i--;
             }
             else if (c == '[')
             {
                 i++;
             }
             pw.incPos();
         }
         pw.incPos();
         pw.getNum(out n);
     }
     else
     {
         pw.stackRepeat.Push(rx);
     }
 }
Esempio n. 16
0
        private void cmdNoise(partWork pw)
        {
            int n = -1;
            pw.incPos();

            if (pw.Type == enmChannelType.DCSGNOISE || pw.Type == enmChannelType.SSG)
            {
                if (pw.getNum(out n))
                {
                    n = checkRange(n, 0, pw.Type == enmChannelType.DCSGNOISE ? 7 : 31);
                    if (pw.Type == enmChannelType.DCSGNOISE)
                    {
                        pw.noise = n; // DCSGの場合は4Chに保存
                    }
                    else
                    {
                        pw.chip.lstPartWork[0].noise = n;//その他SSGの場合は、そのChipの1Chに保存
                        outSsgNoise(pw, n);
                    }
                }
                else
                {
                    msgBox.setErrMsg("wコマンドに指定された値が不正です。", lineNumber);
                    return;

                }
            }
            else
            {
                msgBox.setErrMsg("このチャンネルではwコマンドは使用できません。", lineNumber);
                return;
            }
        }
Esempio n. 17
0
 private void cmdRepeatStart(partWork pw)
 {
     pw.incPos();
     clsRepeat rs = new clsRepeat();
     rs.pos = pw.getPos();
     rs.repeatCount = -1;//初期値
     pw.stackRepeat.Push(rs);
 }
Esempio n. 18
0
        private void cmdNote(partWork pw, char cmd)
        {
            pw.incPos();

            //+ -の解析
            int shift = 0;
            while (pw.getChar() == '+' || pw.getChar() == '-')
            {
                shift += pw.getChar() == '+' ? 1 : -1;
                pw.incPos();
            }
            if (cmd == 'r' && shift != 0)
            {
                msgBox.setWrnMsg("休符での+、-の指定は無視されます。", lineNumber);
            }

            int ml = 0;
            int n = -1;
            bool isMinus = false;
            bool isSecond = false;
            do
            {
                int m = 0;

                //数値の解析
                if (!pw.getNum(out n))
                {
                    if (!isSecond)
                        n = (int)pw.length;
                    else if (!isMinus)
                    {
                        //タイとして'&'が使用されている
                        pw.tie = true;
                    }
                }
                else
                {
                    if ((int)clockCount % n != 0)
                    {
                        msgBox.setWrnMsg(string.Format("割り切れない音長({0})の指定があります。音長は不定になります。", n), lineNumber);
                    }
                    n = (int)clockCount / n;
                }

                if (!pw.tie)
                {
                    m += n;

                    //符点の解析
                    while (pw.getChar() == '.')
                    {
                        if (n % 2 != 0)
                        {
                            msgBox.setWrnMsg("割り切れない.の指定があります。音長は不定です。", lineNumber);
                        }
                        n = n / 2;
                        m += n;
                        pw.incPos();
                    }

                    if (isMinus) ml -= m;
                    else ml += m;
                }

                //ベンドの解析
                int bendDelayCounter = 0;
                int bendShift = 0;
                if (pw.getChar() == '_')
                {
                    pw.incPos();
                    pw.octaveNow = pw.octaveNew;
                    pw.bendOctave = pw.octaveNow;
                    pw.bendNote = 'r';
                    pw.bendWaitCounter = -1;
                    bool loop = true;
                    while (loop)
                    {
                        char bCmd = pw.getChar();
                        switch (bCmd)
                        {
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                            case 'g':
                            case 'a':
                            case 'b':
                                loop = false;
                                pw.incPos();
                                //+ -の解析
                                bendShift = 0;
                                while (pw.getChar() == '+' || pw.getChar() == '-')
                                {
                                    bendShift += pw.getChar() == '+' ? 1 : -1;
                                    pw.incPos();
                                }
                                pw.bendShift = bendShift;
                                bendDelayCounter = 0;
                                n = -1;
                                isMinus = false;
                                isSecond = false;
                                do
                                {
                                    m = 0;

                                    //数値の解析
                                    if (!pw.getNum(out n))
                                    {
                                        if (!isSecond)
                                        {
                                            n = 0;
                                            break;
                                        }
                                        else if (!isMinus)
                                        {
                                            //タイとして'&'が使用されている
                                            pw.tie = true;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        if ((int)clockCount % n != 0)
                                        {
                                            msgBox.setWrnMsg(string.Format("割り切れない音長({0})の指定があります。音長は不定になります。", n), lineNumber);
                                        }
                                        n = (int)clockCount / n;
                                    }

                                    if (!pw.tie)
                                    {
                                        bendDelayCounter += n;

                                        //符点の解析
                                        while (pw.getChar() == '.')
                                        {
                                            if (n % 2 != 0)
                                            {
                                                msgBox.setWrnMsg("割り切れない.の指定があります。音長は不定です。", lineNumber);
                                            }
                                            n = n / 2;
                                            m += n;
                                            pw.incPos();
                                        }

                                        if (isMinus) bendDelayCounter -= m;
                                        else bendDelayCounter += m;
                                    }

                                    if (pw.getChar() == '&')
                                    {
                                        isMinus = false;
                                    }
                                    else if (pw.getChar() == '~')
                                    {
                                        isMinus = true;
                                    }
                                    else
                                    {
                                        break;
                                    }

                                    isSecond = true;
                                    pw.incPos();

                                } while (true);

                                if (cmd != 'r')
                                {
                                    pw.bendNote = bCmd;
                                    bendDelayCounter = checkRange(bendDelayCounter, 0, ml);
                                    pw.bendWaitCounter = bendDelayCounter;
                                }
                                else
                                {
                                    msgBox.setErrMsg("休符にベンドの指定はできません。", lineNumber);
                                }

                                break;
                            case 'o':
                                pw.incPos();
                                if (!pw.getNum(out n))
                                {
                                    msgBox.setErrMsg("不正なオクターブが指定されています。", lineNumber);
                                    n = 110;
                                }
                                n = checkRange(n, 1, 8);
                                pw.bendOctave = n;
                                break;
                            case '>':
                                pw.incPos();
                                pw.bendOctave++;
                                pw.bendOctave = checkRange(pw.bendOctave, 1, 8);
                                break;
                            case '<':
                                pw.incPos();
                                pw.bendOctave--;
                                pw.bendOctave = checkRange(pw.bendOctave, 1, 8);
                                break;
                            default:
                                loop = false;
                                break;
                        }
                    }

                    //音符の変化量
                    int ed = note.IndexOf(pw.bendNote) + 1 + (pw.bendOctave - 1) * 12 + pw.bendShift;
                    ed = checkRange(ed, 0, 8 * 12 - 1);
                    int st = note.IndexOf(cmd) + 1 + (pw.octaveNow - 1) * 12 + shift;//
                    st = checkRange(st, 0, 8 * 12 - 1);

                    int delta = ed - st;
                    if (delta == 0 || bendDelayCounter == ml)
                    {
                        pw.bendNote = 'r';
                        pw.bendWaitCounter = -1;
                    }
                    else
                    {
                        //1音符当たりのウエイト
                        float wait = (ml - bendDelayCounter - 1) / (float)delta;
                        float tl = 0;
                        float bf = Math.Sign(wait);
                        List<int> lstBend = new List<int>();
                        for (int i = 0; i < Math.Abs(delta); i++)
                        {
                            bf += wait;
                            tl += wait;
                            int a = getPsgFNum(pw.octaveNow, cmd, shift + (i + 0) * Math.Sign(delta));//
                            int b = getPsgFNum(pw.octaveNow, cmd, shift + (i + 1) * Math.Sign(delta));//
                            if (
                                (pw.chip is YM2610B && pw.ch < 9)
                                || (pw.chip is YM2612))
                            {
                                int[] ftbl = (pw.chip is YM2612) ? OPN_FNumTbl_7670454 : OPN_FNumTbl_8000000;

                                a = getFmFNum(ftbl, pw.octaveNow, cmd, shift + (i + 0) * Math.Sign(delta));//
                                b = getFmFNum(ftbl, pw.octaveNow, cmd, shift + (i + 1) * Math.Sign(delta));//
                                int oa = (a & 0xf000) / 0x1000;
                                int ob = (b & 0xf000) / 0x1000;
                                if (oa != ob)
                                {
                                    if ((a & 0xfff) == ftbl[0])
                                    {
                                        oa += Math.Sign(ob - oa);
                                        a = (a & 0xfff) * 2 + oa * 0x1000;
                                    }
                                    else if ((b & 0xfff) == ftbl[0])
                                    {
                                        ob += Math.Sign(oa - ob);
                                        b = (b & 0xfff) * ((delta > 0) ? 2 : 1) + ob * 0x1000;
                                    }
                                }
                            }
                            else if (pw.chip is YM2610B && pw.Type == enmChannelType.SSG)
                            {
                                a = getSsgFNum(pw.octaveNow, cmd, shift + (i + 0) * Math.Sign(delta));//
                                b = getSsgFNum(pw.octaveNow, cmd, shift + (i + 1) * Math.Sign(delta));//
                            }
                            else if (pw.chip is SN76489)
                            {
                                a = getPsgFNum(pw.octaveNow, cmd, shift + (i + 0) * Math.Sign(delta));//
                                b = getPsgFNum(pw.octaveNow, cmd, shift + (i + 1) * Math.Sign(delta));//
                            }
                            else if (pw.chip is RF5C164)
                            {
                                a = getRf5c164PcmNote(pw.octaveNow, cmd, shift + (i + 0) * Math.Sign(delta));//
                                b = getRf5c164PcmNote(pw.octaveNow, cmd, shift + (i + 1) * Math.Sign(delta));//
                            }

                            if (Math.Abs(bf) >= 1.0f)
                            {
                                for (int j = 0; j < (int)Math.Abs(bf); j++)
                                {
                                    int c = b - a;
                                    int d = (int)Math.Abs(bf);
                                    lstBend.Add((int)(a + ((float)c / (float)d) * (float)j));
                                }
                                bf -= (int)bf;
                            }

                        }
                        Stack<Tuple<int, int>> lb = new Stack<Tuple<int, int>>();
                        int of = -1;
                        int cnt = 1;
                        foreach (int f in lstBend)
                        {
                            if (of == f)
                            {
                                cnt++;
                                continue;
                            }
                            lb.Push(new Tuple<int, int>(f, cnt));
                            of = f;
                            cnt = 1;
                        }
                        pw.bendList = new Stack<Tuple<int, int>>();
                        foreach (Tuple<int, int> lbt in lb)
                        {
                            pw.bendList.Push(lbt);
                        }
                        Tuple<int, int> t = pw.bendList.Pop();
                        pw.bendFnum = t.Item1;
                        pw.bendWaitCounter = t.Item2;
                    }
                }

                if (pw.getChar() == '&')
                {
                    isMinus = false;
                }
                else if (pw.getChar() == '~')
                {
                    isMinus = true;
                }
                else
                {
                    break;
                }

                isSecond = true;
                pw.incPos();

            } while (true);

            if (ml < 1)
            {
                msgBox.setErrMsg("負の音長が指定されました。", lineNumber);
                ml = (int)pw.length;
            }

            //装飾の解析完了

            //WaitClockの決定
            pw.waitCounter = ml;

            if (cmd != 'r')
            {

                //発音周波数
                if (pw.bendWaitCounter == -1)
                {
                    pw.octaveNow = pw.octaveNew;
                    pw.noteCmd = cmd;
                    pw.shift = shift;
                }
                else
                {
                    pw.octaveNew = pw.bendOctave;//
                    pw.octaveNow = pw.bendOctave;//
                    pw.noteCmd = pw.bendNote;
                    pw.shift = pw.bendShift;
                }

                //発音周波数の決定とキーオン
                if (pw.chip is YM2610B)
                {

                    //YM2610B

                    if (pw.Type == enmChannelType.FMOPN || pw.Type == enmChannelType.FMOPNex)
                    {
                        setFmFNum(pw);

                        //タイ指定では無い場合はキーオンする
                        if (!pw.beforeTie)
                        {
                            setLfoAtKeyOn(pw);
                            setFmVolume(pw);
                            outFmKeyOn(pw);
                        }
                    }
                    else if (pw.Type == enmChannelType.SSG)
                    {
                        setSsgFNum(pw);

                        //タイ指定では無い場合はキーオンする
                        if (!pw.beforeTie)
                        {
                            setEnvelopeAtKeyOn(pw);
                            setLfoAtKeyOn(pw);
                            outSsgKeyOn(pw);
                        }
                    }
                    else if (pw.Type == enmChannelType.ADPCMA)
                    {
                        if (!pw.beforeTie)
                        {

                            pw.keyOn = true;
                            //if ((((YM2610B)pw.chip).adpcmA_KeyOn & (1 << (pw.ch - 12))) != 0)
                            //{
                            //    ((YM2610B)pw.chip).adpcmA_KeyOff |= (byte)(1 << (pw.ch - 12));
                            //    ((YM2610B)pw.chip).adpcmA_beforeKeyOn &= (byte)~(1 << (pw.ch - 12));
                            //}
                            //((YM2610B)pw.chip).adpcmA_KeyOn |= (byte)(1 << (pw.ch - 12));

                        }
                    }
                    else if (pw.Type == enmChannelType.ADPCMB)
                    {
                        setAdpcmBFNum(pw);

                        //タイ指定では無い場合はキーオンする
                        if (!pw.beforeTie)
                        {
                            setEnvelopeAtKeyOn(pw);
                            setLfoAtKeyOn(pw);
                            outAdpcmBKeyOn(pw);
                        }
                    }
                }
                else if (pw.chip is YM2612)
                {

                    //YM2612

                    if (!pw.pcm)
                    {
                        setFmFNum(pw);
                    }
                    else
                    {
                        getPcmNote(pw);
                    }
                    //タイ指定では無い場合はキーオンする
                    if (!pw.beforeTie)
                    {
                        setLfoAtKeyOn(pw);
                        setFmVolume(pw);
                        outFmKeyOn(pw);
                    }
                }
                else if (pw.chip is SN76489)
                {

                    // SN76489

                    setPsgFNum(pw);

                    //タイ指定では無い場合はキーオンする
                    if (!pw.beforeTie)
                    {
                        setEnvelopeAtKeyOn(pw);
                        setLfoAtKeyOn(pw);
                        outPsgKeyOn(pw);
                    }
                }
                else if (pw.chip is RF5C164)
                {

                    // RF5C164

                    setRf5c164FNum(pw);

                    //タイ指定では無い場合はキーオンする
                    if (!pw.beforeTie)
                    {
                        setEnvelopeAtKeyOn(pw);
                        setLfoAtKeyOn(pw);
                        setRf5c164Envelope(pw, pw.volume);
                        outRf5c164KeyOn(pw);
                    }
                }

                //gateTimeの決定
                if (pw.gatetimePmode)
                {
                    pw.waitKeyOnCounter = pw.waitCounter * pw.gatetime / 8L;
                }
                else
                {
                    pw.waitKeyOnCounter = pw.waitCounter - pw.gatetime;
                }
                if (pw.waitKeyOnCounter < 1) pw.waitKeyOnCounter = 1;

                //PCM専用のWaitClockの決定
                if (pw.pcm)
                {
                    pw.pcmWaitKeyOnCounter = -1;
                    if (Version != 1.60f)
                    {
                        pw.pcmWaitKeyOnCounter = pw.waitKeyOnCounter;
                    }
                    pw.pcmSizeCounter = instPCM[pw.instrument].size;
                }
            }

            pw.clockCounter += pw.waitCounter;
        }
Esempio n. 19
0
 private void cmdTotalVolume(partWork pw)
 {
     int n;
     pw.incPos();
     if (!pw.getNum(out n))
     {
         msgBox.setErrMsg("不正な音量が指定されています。", lineNumber);
         n = 63;
     }
     if ((pw.chip is YM2610B) && pw.Type== enmChannelType.ADPCMA)
     {
         ((YM2610B)pw.chip).adpcmA_TotalVolume = checkRange(n, 0, ((YM2610B)pw.chip).adpcmA_MAXTotalVolume);
     }
 }
Esempio n. 20
0
 private void cmdOctave(partWork pw)
 {
     int n;
     pw.incPos();
     if (!pw.getNum(out n))
     {
         msgBox.setErrMsg("不正なオクターブが指定されています。", lineNumber);
         n = 110;
     }
     n = checkRange(n, 1, 8);
     pw.octaveNew = n;
 }
Esempio n. 21
0
        private void cmdY(partWork pw)
        {
            int n = -1;
            byte adr = 0;
            byte dat = 0;
            pw.incPos();
            if (pw.getNum(out n))
            {
                adr = (byte)(n & 0xff);
            }
            pw.incPos();
            if (pw.getNum(out n))
            {
                dat = (byte)(n & 0xff);
            }

            if ((pw.chip is YM2610B) || (pw.chip is YM2612))
            {
                outFmAdrPort((pw.ch > 3 && pw.ch < 6) ? pw.port1 : pw.port0, adr, dat);
            }
            else if (pw.chip is SN76489)
            {
                outPsgPort(pw.isSecondary, dat);
            }
            else if (pw.chip is RF5C164)
            {
                outRf5c164Port(pw.isSecondary, adr, dat);
            }
        }
Esempio n. 22
0
 private void cmdOctaveDown(partWork pw)
 {
     pw.incPos();
     pw.octaveNew--;
     pw.octaveNew = checkRange(pw.octaveNew, 1, 8);
 }
Esempio n. 23
0
 private void cmdClockLength(partWork pw)
 {
     int n;
     pw.incPos();
     if (!pw.getNum(out n))
     {
         msgBox.setErrMsg("不正な音長が指定されています。", lineNumber);
         n = 10;
     }
     n = checkRange(n, 1, 65535);
     pw.length = n;
 }
Esempio n. 24
0
 private void cmdOctaveUp(partWork pw)
 {
     pw.incPos();
     pw.octaveNew++;
     pw.octaveNew = checkRange(pw.octaveNew, 1, 8);
 }
Esempio n. 25
0
        private void cmdEnvelope(partWork pw)
        {
            int n = -1;
            if (
                ((pw.chip is YM2610B) && (pw.Type == enmChannelType.SSG || pw.Type == enmChannelType.FMOPNex))
                || ((pw.chip is YM2612) && (pw.Type == enmChannelType.FMPCM || (pw.Type == enmChannelType.FMOPNex)))
                || (pw.chip is SN76489)
                || (pw.chip is RF5C164)
                )
            {
                pw.incPos();
                switch (pw.getChar())
                {
                    case 'O':
                        pw.incPos();
                        if (
                            ((pw.chip is YM2610B) && pw.Type == enmChannelType.FMOPNex)
                            || pw.chip is YM2612
                            )
                        {
                            switch (pw.getChar())
                            {
                                case 'N':
                                    pw.incPos();
                                    pw.Ch3SpecialMode = true;
                                    outOPNSetCh3SpecialMode(pw, true);
                                    break;
                                case 'F':
                                    pw.incPos();
                                    pw.Ch3SpecialMode = false;
                                    outOPNSetCh3SpecialMode(pw, false);
                                    break;
                                default:
                                    msgBox.setErrMsg(string.Format("未知のコマンド(EO{0})が指定されました。", pw.getChar()), lineNumber);
                                    pw.incPos();
                                    break;
                            }
                        }
                        else
                        {
                            switch (pw.getChar())
                            {
                                case 'N':
                                    pw.incPos();
                                    pw.envelopeMode = true;
                                    break;
                                case 'F':
                                    pw.incPos();
                                    pw.envelopeMode = false;
                                    break;
                                default:
                                    msgBox.setErrMsg(string.Format("未知のコマンド(EO{0})が指定されました。", pw.getChar()), lineNumber);
                                    pw.incPos();
                                    break;
                            }
                        }
                        break;
                    case 'X':
                        char c = pw.getChar();
                        if (
                            ((pw.chip is YM2610B) && pw.Type == enmChannelType.FMOPNex)
                            || pw.chip is YM2612
                            )
                        {
                            pw.incPos();
                            if (!pw.getNum(out n))
                            {
                                msgBox.setErrMsg("不正なスロット指定'EX'が指定されています。", lineNumber);
                                n = 0;
                            }
                            byte res = 0;
                            while (n % 10 != 0)
                            {
                                if (n % 10 > 0 && n % 10 < 5)
                                {
                                    res += (byte)(1 << (n % 10 - 1));
                                }
                                else
                                {
                                    msgBox.setErrMsg(string.Format("未知のコマンド(EX{0})が指定されました。", n), lineNumber);
                                    break;
                                }
                                n /= 10;
                            }
                            if (res != 0)
                            {
                                pw.slots = res;
                            }
                        }
                        else
                        {
                            msgBox.setErrMsg("未知のコマンド(EX)が指定されました。", lineNumber);
                        }
                        break;
                    default:
                        if (pw.Type == enmChannelType.FMOPNex)
                        {
                            int[] s = new int[] { 0, 0, 0, 0 };

                            for (int i = 0; i < 4; i++)
                            {
                                if (pw.getNum(out n))
                                {
                                    s[i] = n;
                                }
                                else
                                {
                                    msgBox.setErrMsg("Eコマンドの解析に失敗しました。", lineNumber);
                                    break;
                                }
                                if (i == 3) break;
                                pw.incPos();
                            }
                            pw.slotDetune = s;
                            break;
                        }
                        else
                        {
                            msgBox.setErrMsg(string.Format("未知のコマンド(E{0})が指定されました。", pw.getChar()), lineNumber);
                            pw.incPos();
                        }
                        break;
                }
            }
            else
            {
                msgBox.setWrnMsg("このパートは効果音モードに対応したチャンネルが指定されていないため、Eコマンドは無視されます。", lineNumber);
                pw.incPos();
            }
        }
Esempio n. 26
0
 private void cmdGatetime(partWork pw)
 {
     int n;
     pw.incPos();
     if (!pw.getNum(out n))
     {
         msgBox.setErrMsg("不正なゲートタイム指定'q'が指定されています。", lineNumber);
         n = 0;
     }
     n = checkRange(n, 0, 255);
     pw.gatetime = n;
     pw.gatetimePmode = false;
 }