Hope is a Dream. Dream is a Hope.

非公開ブログは再開しました。

Roland UA-25 ドライバ Windows10対応

f:id:hope_is_dream:20190406164434p:plain

PCの音がならないぞ!

f:id:hope_is_dream:20190406164637j:plain

10年愛用しているオーディオインターフェイスが動かなくなった。 ランプがつかない。。 壊れたか。。

。。

Windows10にアップデートしたせいか??と思いドライバを探したら、Win10には対応していないもよう。

解決法

heetnote.com

UA25はWin10では動作保証外らしい!!!!もう結構な歳なのね。現役で使い続けているのにありがとう。 Win10でも動作させるハック見つけました。本当にありがとうございます。

f:id:hope_is_dream:20190406164702j:plain

せいや!復活!まだ頑張ってもらうよー

C#でWindowsのCPU使用率を取得する方法

CPUの使用率をアプリに表示したいよね。 でも、マルチコアとかだと意外と面倒。 以下に、クラス化したので使ってください。

内部タイマーを使って、バッファをためます。 それを取得して使うだけ。

List<SingleCPUManager> SingleCPUList = new List<SingleCPUManager>();

// Initialize
for (int i = 0; i<SingleCPUManager.GetCPUCount(); i++)
{
    SingleCPUList.Add(new SingleCPUManager(i, 200, 4, 30));
}

// Load Data
int Ncpu = Environment.ProcessorCount;
for (int k = 0; k<Ncpu; k++)
{
    SingleCPUManager scpu = SingleCPUList[k];
    float[] cpu_values = scpu.GetQueBuffer().ToArray();
}

using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace SimScreenSaver
{

    /// <summary>
    /// CPUマネージャー
    /// </summary>
    public class SingleCPUManager
    {



        PerformanceCounter Counter;
        int BufferLength;

        public int CPUIndex;

        int Tap;

        List<float> QueBuffer;
        private System.Windows.Forms.Timer timer;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="index">CPU番号</param>
        /// <param name="buffer_length">バッファ長さ</param>
        /// <param name="tap">移動平均tap</param>
        public SingleCPUManager(int index, int buffer_length, int tap, int interval_ms)
        {

            // Param
            this.BufferLength = buffer_length;
            this.CPUIndex = index;
            this.Tap = tap;
            if (this.Tap <= 0) this.Tap = 1;

            // Init
            Init();

            // タイマーの間隔(ミリ秒)
            timer = new System.Windows.Forms.Timer();
            timer.Interval = interval_ms;
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            Update();
        }

        /// <summary>
        /// 初期化
        /// </summary>
        /// <param name="index"></param>
        /// <param name="buffer_length"></param>
        void Init()
        {
            // CPUカウンタ
            Counter = new PerformanceCounter("Processor", "% Processor Time", CPUIndex.ToString());

            // バッファ
            QueBuffer = new List<float>();

            // バッファの初期化
            for (int i = 0; i < BufferLength; i++)
            {
                QueBuffer.Add(0.0f);
            }
        }

        /// <summary>
        /// アップデート
        /// バッファにデータを追加
        /// </summary>
        void Update()
        {
            float v = Counter.NextValue();

            // 移動平均

            float ave = 0;
            for (int i = 0; i < Tap - 1; i++)
            {
                ave += QueBuffer[(QueBuffer.Count - 1) - i];
            }
            ave += v;
            ave /= Tap;
            v = ave;

            QueBuffer.Add(v);
            QueBuffer.RemoveAt(0);
        }


        /// <summary>
        /// バッファを渡す
        /// </summary>
        /// <returns></returns>
        public List<float> GetQueBuffer()
        {
            return QueBuffer;
        }

        /// <summary>
        /// Utilities
        /// </summary>
        /// <returns></returns>
        static public int GetCPUCount()
        {
            return Environment.ProcessorCount;
        }

    }
}

C# グラフ描画

C#のGraphicsでグラフを書くことは良くある。 そのたびに、座標変換を書いていていよいよ面倒になったので、ここに記す。

        /// <summary>
        /// 正規化座標へ変換
        /// x[0,1], y[0,1]の範囲
        /// </summary>
        /// <param name="Origins">ワールド座標の点</param>
        /// <param name="ClipRect">ワールド座標のクリップ領域. xy:左下. </param>
        static PointF Norm(PointF Origin, RectangleF ClipRect)
        {
            PointF NormPoint = new PointF();

            NormPoint.X = (Origin.X - ClipRect.X) / (ClipRect.Width) + ClipRect.X;
            NormPoint.Y = (Origin.Y - ClipRect.Y) / (ClipRect.Height) + ClipRect.Y;

            return NormPoint;
        }

        /// <summary>
        /// 座標変換するぜ
        /// </summary>
        /// <param name="Origin"></param>
        /// <param name="ClipRect"></param>
        /// <param name="DrawRect"></param>
        static PointF ScreenPosition(PointF Origin, RectangleF ClipRect, RectangleF DrawRect)
        {
            PointF norm = Norm(Origin, ClipRect);

            PointF Screen = new PointF();

            Screen.X = (norm.X * DrawRect.Width) + DrawRect.X;
            Screen.Y = ((1f - norm.Y) * DrawRect.Height) + DrawRect.Y;


            return Screen;

        }

        /// <summary>
        /// 指定した位置にラインを描画
        /// </summary>
        /// <param name="e"></param>
        /// <param name="pen"></param>
        /// <param name="Origins">ワールド座標の点</param>
        /// <param name="ClipRect">ワールド座標のクリップ領域. xy:左下. </param>
        /// <param name="DrawRect">描画先のスクリーン座標. xy:左上</param>
        private void DrawLines(PaintEventArgs e, Pen pen, PointF[] Origins, RectangleF ClipRect, RectangleF DrawRect)
        {
            int N = Origins.Length;

            PointF[] ScrPoints = new PointF[N];

            for (int i = 0; i < Origins.Length; i++)
            {
                PointF _ScrPoint = ScreenPosition(Origins[i], ClipRect, DrawRect);

                ScrPoints[i] = _ScrPoint;
            }

            e.Graphics.DrawLines(pen, ScrPoints);

        }