Пример #1
0
    /// <summary>
    /// 指定したVSQの指定した位置に,テンポの挿入を試みます.
    /// 既存のテンポがある場合,値が上書きされます
    /// </summary>
    /// <param name="vsq">挿入対象のVSQ</param>
    /// <param name="clock">挿入位置</param>
    /// <param name="tempo">楽譜表記上のテンポ.BPS</param>
    private static void insertTempoInto(VsqFileEx vsq, int clock, float t)
    {
        // clockの位置にテンポ変更があるかどうか?
        int num_tempo = vsq.TempoTable.size();
        int index     = -1;

        for (int j = 0; j < num_tempo; j++)
        {
            TempoTableEntry itemj = vsq.TempoTable[j];
            if (itemj.Clock == clock)
            {
                index = j;
                break;
            }
        }
        int tempo = (int)(60e6 / t);

        if (index >= 0)
        {
            // clock位置に既存のテンポ変更がある場合,テンポ値を変更
            TempoTableEntry itemj = vsq.TempoTable[index];
            itemj.Tempo = tempo;
        }
        else
        {
            // 既存のものはないので新規に追加
            vsq.TempoTable.Add(new TempoTableEntry(clock, tempo, 0.0));
        }
        // テンポテーブルを更新
        vsq.TempoTable.updateTempoInfo();
    }
Пример #2
0
 private decimal getTempo(TempoTableEntry tempo)
 {
     return(Math.Round((decimal)(60e6 / tempo.Tempo), 2));
 }
Пример #3
0
        /// <summary>
        /// このWAVE描画コンテキストが保持しているWAVEデータを、ゲートタイム基準でグラフィクスに描画します。
        /// </summary>
        /// <param name="g">描画に使用するグラフィクスオブジェクト</param>
        /// <param name="pen">描画に使用するペン</param>
        /// <param name="rect">描画範囲</param>
        /// <param name="clock_start">描画開始位置のゲートタイム</param>
        /// <param name="clock_end">描画終了位置のゲートタイム</param>
        /// <param name="tempo_table">ゲートタイムから秒数を調べる際使用するテンポ・テーブル</param>
        /// <param name="pixel_per_clock">ゲートタイムあたりの秒数</param>
        /// <param name="scale_y">Y軸方向の描画スケール。デフォルトは1.0</param>
        /// <param name="auto_maximize">自動で最大化するかどうか</param>
        private void drawCore(
            Graphics2D g,
            Color pen,
            Rectangle rect,
            int clock_start,
            int clock_end,
            TempoVector tempo_table,
            float pixel_per_clock,
            float scale_y,
            bool auto_maximize)
        {
            if (mWave.Length == 0)
            {
                return;
            }
#if DEBUG
            double startedTime = PortUtil.getCurrentTime();
#endif
            mDrawer.setGraphics(g);
            mDrawer.clear();
            double secStart = tempo_table.getSecFromClock(clock_start);
            double secEnd   = tempo_table.getSecFromClock(clock_end);
            int    sStart0  = (int)(secStart * mSampleRate) - 1;
            int    sEnd0    = (int)(secEnd * mSampleRate) + 1;

            int    count   = tempo_table.Count;
            int    sStart  = 0;
            double cStart  = 0.0;
            float  order_y = 1.0f;
            if (auto_maximize)
            {
                order_y = rect.height / 2.0f / 127.0f * mMaxAmplitude / mActualMaxAmplitude;
            }
            else
            {
                order_y = rect.height / 127.0f * scale_y * mMaxAmplitude;
            }
            int  ox       = rect.x;
            int  oy       = rect.height / 2;
            int  last     = mWave[0];
            int  lastx    = ox;
            int  lastYMax = oy - (int)(last * order_y);
            int  lastYMin = lastYMax;
            int  lasty    = lastYMin;
            int  lasty2   = lastYMin;
            bool skipped  = false;
            mDrawer.append(ox, lasty);
            int xmax      = rect.x + rect.width;
            int lastTempo = 500000;
            for (int i = 0; i <= count; i++)
            {
                double time  = 0.0;
                int    tempo = 500000;
                int    cEnd  = 0;
                if (i < count)
                {
                    TempoTableEntry entry = tempo_table[i];
                    time  = entry.Time;
                    tempo = entry.Tempo;
                    cEnd  = entry.Clock;
                }
                else
                {
                    time  = tempo_table.getSecFromClock(clock_end);
                    tempo = tempo_table[i - 1].Tempo;
                    cEnd  = clock_end;
                }
                int sEnd = (int)(time * mSampleRate);

                // sStartサンプルからsThisEndサンプルまでを描画する(必要なら!)
                if (sEnd < sStart0)
                {
                    sStart    = sEnd;
                    cStart    = cEnd;
                    lastTempo = tempo;
                    continue;
                }
                if (sEnd0 < sStart)
                {
                    break;
                }

                //
                int    xoffset       = (int)(cStart * pixel_per_clock) - AppManager.mMainWindowController.getStartToDrawX() + AppManager.keyOffset;
                double sec_per_clock = lastTempo * 1e-6 / 480.0;
                lastTempo = tempo;
                double pixel_per_sample = 1.0 / mSampleRate / sec_per_clock * pixel_per_clock;
                int    j0 = sStart;
                if (j0 < 0)
                {
                    j0 = 0;
                }
                int j1 = sEnd;
                if (mWave.Length < j1)
                {
                    j1 = mWave.Length;
                }

                // 第j0サンプルのデータを画面に描画したときのx座標がいくらになるか?
                int draftStartX = xoffset + (int)((j0 - sStart) * pixel_per_sample);
                if (draftStartX < rect.x)
                {
                    j0 = (int)((rect.x - xoffset) / pixel_per_sample) + sStart;
                }
                // 第j1サンプルのデータを画面に描画した時のx座標がいくらになるか?
                int draftEndX = xoffset + (int)((j1 - sStart) * pixel_per_sample);
                if (rect.x + rect.width < draftEndX)
                {
                    j1 = (int)((rect.x + rect.width - xoffset) / pixel_per_sample) + sStart;
                }

                bool breakRequired = false;
                for (int j = j0; j < j1; j++)
                {
                    int v = mWave[j];
                    if (v == last)
                    {
                        skipped = true;
                        continue;
                    }
                    int x = xoffset + (int)((j - sStart) * pixel_per_sample);
                    if (xmax < x)
                    {
                        breakRequired = true;
                        break;
                    }
                    if (x < rect.x)
                    {
                        continue;
                    }
                    int y = oy - (int)(v * order_y);
                    if (lastx == x)
                    {
                        lastYMax = Math.Max(lastYMax, y);
                        lastYMin = Math.Min(lastYMin, y);
                        continue;
                    }

                    if (skipped)
                    {
                        mDrawer.append(x - 1, lasty);
                        lastx = x - 1;
                    }
                    if (lastYMax == lastYMin)
                    {
                        mDrawer.append(x, y);
                    }
                    else
                    {
                        if (lasty2 != lastYMin)
                        {
                            mDrawer.append(lastx, lastYMin);
                        }
                        mDrawer.append(lastx, lastYMax);
                        if (lastYMax != lasty)
                        {
                            mDrawer.append(lastx, lasty);
                        }
                        mDrawer.append(x, y);
                    }
                    lasty2   = lasty;
                    lastx    = x;
                    lastYMin = y;
                    lastYMax = y;
                    lasty    = y;
                    last     = v;
                    skipped  = false;
                }
                sStart = sEnd;
                cStart = cEnd;
                if (breakRequired)
                {
                    break;
                }
            }

            mDrawer.append(rect.x + rect.width, lasty);
            mDrawer.flush();
        }
Пример #4
0
        /// <summary>
        /// vsqxファイルを読み込み,新しいシーケンスオブジェクトを生成する
        /// </summary>
        /// <param name="filePath">ファイルパス</param>
        /// <exception cref="System.Exception">読み込みに失敗した時スローされる</exception>
        /// <returns>生成したシーケンスオブジェクト</returns>
        public static VsqFile readFromVsqx(string filePath)
        {
            if (filePath == null)
            {
                throw new ArgumentNullException("filePath");
            }

            if (false == File.Exists(filePath))
            {
                throw new Exception("file not found");
            }

            var xml = new XmlDocument();

            xml.Load(filePath);

            // 音源テーブルを解釈
            var voiceTable = getVoiceTable(xml);

            // マスタートラックを解釈
            XmlElement masterTrack = xml.DocumentElement["masterTrack"];
            int        preMeasure  = int.Parse(masterTrack["preMeasure"].InnerText);
            VsqFile    result      = new VsqFile("", preMeasure, 4, 4, 500000);

            // テンポ変更を読み取る
            result.TempoTable.Clear();
            foreach (XmlNode node in masterTrack.GetElementsByTagName("tempo"))
            {
                int             posTick    = int.Parse(node["posTick"].InnerText);
                int             bpm        = int.Parse(node["bpm"].InnerText);
                int             tempo      = (int)(6000000000L / bpm);
                TempoTableEntry tempoEntry = new TempoTableEntry(posTick, tempo, 0.0);
                result.TempoTable.Add(tempoEntry);
            }
            result.TempoTable.updateTempoInfo();
            // 拍子変更を読み取る
            result.TimesigTable.Clear();
            foreach (XmlNode node in masterTrack.GetElementsByTagName("timeSig"))
            {
                int posMes      = int.Parse(node["posMes"].InnerText);
                int numerator   = int.Parse(node["nume"].InnerText);
                int denominator = int.Parse(node["denomi"].InnerText);
                TimeSigTableEntry timesigEntry = new TimeSigTableEntry(0, numerator, denominator, posMes);
                result.TimesigTable.Add(timesigEntry);
            }
            result.TimesigTable.updateTimesigInfo();

            // マスター以外のトラックを解釈
            foreach (XmlNode node in xml.DocumentElement.GetElementsByTagName("vsTrack"))
            {
                int      trackIndex = int.Parse(node["vsTrackNo"].InnerText) + 1;
                VsqTrack track      = null;
                if (result.Track.Count <= trackIndex)
                {
                    int amount = trackIndex + 1 - result.Track.Count;
                    for (int i = 0; i < amount; i++)
                    {
                        result.Track.Add(new VsqTrack("", ""));
                    }
                }
                track = result.Track[trackIndex];
                track.setName(node["trackName"].InnerText);

                foreach (XmlNode child in node.ChildNodes)
                {
                    if (child.Name == "musicalPart")
                    {
                        parseMusicalPart(voiceTable, track, child);
                    }
                }
            }

            // MasterMixerをパース
            var mixer      = xml.DocumentElement["mixer"];
            var masterUnit = mixer["masterUnit"];

            result.Mixer.MasterFeder  = int.Parse(masterUnit["vol"].InnerText);
            result.Mixer.MasterMute   = 0;
            result.Mixer.MasterPanpot = 0;

            // SlaveMixerをパース
            result.Mixer.Slave.Clear();
            for (int i = 1; i < result.Track.Count; i++)
            {
                result.Mixer.Slave.Add(null);
            }
            foreach (XmlNode vsUnit in mixer.GetElementsByTagName("vsUnit"))
            {
                int vsTrackNo = int.Parse(vsUnit["vsTrackNo"].InnerText);
                int mute      = int.Parse(vsUnit["mute"].InnerText);
                int solo      = int.Parse(vsUnit["solo"].InnerText);
                int pan       = int.Parse(vsUnit["pan"].InnerText);
                int vol       = int.Parse(vsUnit["vol"].InnerText);
                var slave     = new VsqMixerEntry(vol, pan, mute, solo);
                result.Mixer.Slave[vsTrackNo] = slave;
            }

            return(result);
        }
Пример #5
0
 public SelectedTempoEntry(TempoTableEntry original_, TempoTableEntry editing_)
 {
     original = original_;
     editing  = editing_;
 }