0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

C#(Windowsフォーム)で音量ミキサーを作ってみる。ChatGPTに書かせる。

Posted at

はじめに

音量ミキサーを作りたくなりました。こういうやつ。
fig1.png
できたのがこちらです。
fig2.png
しかもchatGPTにほとんどを書かせたので、全然調べてもないし1時間もせずにできました。

早速中身を見ていきましょう。
環境は
Windows8.1 VisualStudio2022 .NETCore7.0

1.プロセスIDと音量の取得

正規のWindows音量ミキサーを見てみると、アプリケーション名と現在の音量がスライダーで出てます。
これを再現するには、アプリケーション名と、音量を取得する必要がありそうです。さらに、アプリケーションはOS内ではプロセスIDというもので管理されてそうなので、これも取得したいですね。ということでコードを考えてもらいます。

ChatGPT、「オーディオを使用するプロセスのidと名前の一覧を取得するC#プログラムを教えて」
Videotogif.gif
初めてGPTつかったけどマジですげえな、目の前でコード生えてくるの見ると感動してしまう。

//これ実行するとプロセスid,プロセス名,オーディオ音量をリストにして返してくれる
public List<Tuple<int, string, float>> GetAudioProcesses()
        {
            var audioProcesses = new List<Tuple<int, string, float>>();
            var enumerator = new MMDeviceEnumerator();
            var devices = enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active);

            foreach (var device in devices)
            {
                var sessions = device.AudioSessionManager.Sessions;

                for (int i = 0; i < sessions.Count; i++)
                {
                    var session = sessions[i];
                    var processId = session.GetProcessID;

                    if (processId != null)
                    {
                        var process = GetProcessFromId((int)processId);

                        if (process != null)
                        {
                            audioProcesses.Add(new Tuple<int, string, float>((int)processId, process.ProcessName, session.SimpleAudioVolume.Volume));
                            Debug.Print(session.SimpleAudioVolume.Volume.ToString());
                        }
                    }
                }
            }

            return audioProcesses;
        }
private Process GetProcessFromId(int processId)
        {
            try
            {
                return Process.GetProcessById(processId);
            }
            catch (ArgumentException)
            {
                // プロセスが存在しない場合はnullを返す
                return null;
            }
        }

画面の実装

これで取得できたので、次に実際に画面を作ってもらいます。
fig3.png

private void DisplayAudioProcesses()
        {
            // 既存のコントロールをクリアする
            flowLayoutPanel.Controls.Clear();

            audioProcesses = GetAudioProcesses();

            // リストの内容を表示する
            foreach (var audioProcess in audioProcesses)
            {
                // プロセスIDを表示するラベルを作成する
                var idLabel = new Label
                {
                    Text = $"Process ID: {audioProcess.Item1}",
                    AutoSize = true,
                    TextAlign = ContentAlignment.MiddleLeft
                };

                // プロセス名を表示するラベルを作成する
                var nameLabel = new Label
                {
                    Text = $"Process Name: {audioProcess.Item2}",
                    AutoSize = true,
                    TextAlign = ContentAlignment.MiddleLeft
                };

                // 音量を表示するラベルを作成する
                var volumeLabel = new Label
                {
                    Text = $"Volume: {(int)(audioProcess.Item3*100):F2}%",
                    AutoSize = true,
                    TextAlign = ContentAlignment.MiddleLeft
                };

                // 音量を設定するスライダーを作成する
                var volumeSlider = new TrackBar
                {
                    Minimum = 0,
                    Maximum = 100,
                    Value = (int)(audioProcess.Item3*100),
                    TickFrequency = 10,
                    Width = 150
                };
                volumeSlider.ValueChanged += VolumeSlider_ValueChanged;
                Debug.Print("abya="+audioProcess.Item2 + ":" + audioProcess.Item3);
                //volumeSlider.Value =(int)audioProcess.Item3 * 100;

                // コントロールをパネルに追加する
                var panel = new FlowLayoutPanel
                {
                    FlowDirection = FlowDirection.LeftToRight,
                    Dock = DockStyle.Top,
                    Padding = new Padding(5),
                    Margin = new Padding(5),
                    Width = flowLayoutPanel.Width - 25,
                    Height = 60
                };
                panel.Controls.Add(idLabel);
                panel.Controls.Add(nameLabel);
                panel.Controls.Add(volumeLabel);
                panel.Controls.Add(volumeSlider);
                flowLayoutPanel.Controls.Add(panel);
            }
        }

        private void VolumeSlider_ValueChanged(object sender, EventArgs e)
        {
            // スライダーの値が変更された時に、対応するプロセスの音量を変更する
            var slider = sender as TrackBar;
            var panel = slider.Parent as FlowLayoutPanel;
            if (panel == null) return;
            var volumeLabel = panel.Controls[2] as Label;

            var index = flowLayoutPanel.Controls.GetChildIndex(panel);
            audioProcesses[index] = new Tuple<int, string, float>(
                audioProcesses[index].Item1,
                audioProcesses[index].Item2,
                slider.Value
            );

            Debug.Print(slider.Value.ToString());

            SetApplicationVolume(audioProcesses[index].Item1, (float)slider.Value/100);

            volumeLabel.Text = $"Volume: {slider.Value}%";
        }

あとはこのプログラムを実行するためには、MainFormという名前のWindowsフォームを作成し、FlowLayoutPanelという名前のコントロールを配置しておく必要があります。また、リストの内容をaudioProcessesフィールドに設定し、MainForm_LoadメソッドでDisplayAudioProcessesメソッドを呼び出す必要があります。の指示通り、コピペします。
もうできちゃった、すげえな。

頼んだ3行の表はできませんでしたが、まあいい感じに出来たので良しとしましょう。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?