# MusicGridStudio

Windows向けのPython製デスクトップ音楽プレーヤーです。foobar2000のように、再生、
プレイリスト管理、タグ整理を1つの画面で扱うことを目標にしています。

製作者: LeLien Consulting

## 現在のバージョン（v1.0.0）

- 英語・日本語のUI切替
  - 初回起動は英語
  - `Settings > Language` から English / Japanese を即時切替
  - 選択した言語を保存し、次回起動時に復元
- 視認性を重視した5種類の配色テーマ
  - ダーク（従来配色）、白、青、ピンク、黄色
  - `Settings > Theme`（日本語表示では `設定 > 配色テーマ`）から即時切替
  - テーマ設定を保存し、次回起動時に復元
  - 表、選択行、チェックボックス、ラジオボタン、無効状態の配色をテーマごとに最適化
  - 背景画像が確認できる透明度を保ちつつ、半透明パネルとスモーク処理で楽曲名や操作文字の視認性を維持
  - 背景画像はPC内の任意の場所から選択可能。選択後はアプリ専用データ領域へコピーして設定を保持
- `Information`（情報）メニューの製品情報画面
  - MusicGridStudioのバージョン、動作環境、製作者情報を表示
  - 表示言語の設定にかかわらず製品情報は英語で表示

- Windowsに認識された音声出力を選択（USB DACを含む）
- 再生順とリピート
  - 選択曲から下方向へ進み、末尾で停止する連続再生
  - 1周内で同じ曲を重複させず、停止するまで次の周を続けるシャッフル再生
  - 全曲リピート、1曲リピート、リピートなし
  - 手動の「次の曲」は1曲リピート中でも次へ進みます
- オン・オフ可能なギャップレス再生
  - Windows共有モードでは次曲を別プレーヤーへ事前読込
  - WASAPI排他では同一サンプルレート・チャンネル数・ネイティブ形式の曲を同一ストリーム内で接続
  - 形式が異なる曲間は安全のため通常の曲切替へ自動フォールバック
- WASAPI排他モード
  - Windowsミキサーを迂回
  - 音源本来のサンプルレートでDACを開く
  - 16/24/32bit PCMのネイティブ送出
  - DACが32bit/floatを受け付けない場合、同じサンプルレートの24bit、16bitを順に交渉
  - 排他対応形式が見つからない場合は通常モードへ安全に切替
- FLAC / WAV / MP3 / AAC / ALAC / AIFF / Ogg / Opus等の再生
- CUEシート（UTF-8 / UTF-16 / CP932）を曲単位の仮想トラックとして読み込み
  - `FILE`で参照された同階層のWAV等を`INDEX 01`の区間ごとに再生
  - CUEと参照音源を含むフォルダーを追加した場合、アルバム全体の音源は重複登録しない
  - 仮想トラックは通常の曲と同様に、行単位で削除・並べ替え・プレイリスト保存が可能
  - 実際に再生できる形式は、インストールされたQt Multimediaバックエンドにも依存します
- ファイル・フォルダーのドラッグ＆ドロップ
- 複数プレイリスト、名称変更、行のドラッグによる曲順変更、M3U/M3U8入出力
  - 選択曲を左側の別プレイリストへドラッグすると、元のプレイリストへ残したままドロップ先の末尾へコピー
  - ドロップ先に同じ曲がある場合は重複登録を省略
  - コピー後にどちらのプレイリストからタグやファイル名を変更しても、同じ曲を参照する全プレイリストへ最新情報を反映
- 全画面とウィンドウ表示の切替（F11）
- 表形式のタグ編集
  - タイトル、アーティスト、アルバム、ジャンルなど、多数のタグを任意の列として追加
  - `Settings > Tag Settings…`（日本語表示では `設定 > タグの設定…`）で、表示するタグと左右の並び順を自由に設定
  - 日本語モードで使用する列名をタグごとに編集可能
  - Disc番号/合計、Track番号/合計、ファイル名
  - `Rating WMP` は未評価から5段階を `☆☆☆☆☆`～`★★★★★` で表示し、マウスクリックで設定
  - レーティングは内部では数値として保存されるため、列見出しから数値順に並べ替え可能
  - 複数セルの `Ctrl+C` / `Ctrl+V`
  - ジャンルは自由入力を維持しつつ、欄のクリックで全候補を表示し、入力中は大文字・小文字を区別しない前方一致で絞り込み
  - 初期ジャンル候補は英語表記30件（`Anime`、`SoundTrack`を含む）
  - `Settings > Genre Suggestion Settings…`（日本語表示では `設定 > ジャンル候補の設定…`）で候補と表示順を編集可能
- Disc / Trackの自動連番
  - Disc番号とDisc合計を指定した同一値へ設定
  - 現在の表示順でTrack番号を連番化し、Track合計を最終番号へ設定
- タグ保存時のファイル名自動変更は初期設定でオフ
  - `Settings > Automatic Filename Change`（日本語表示では `設定 > ファイル名の自動変更`）で選択
  - `Do Not Rename Automatically`（自動変更しない）では現在のファイル名を維持
  - `Automatically Rename to D_T_Title`（「D_T_タイトル」へ自動変更）では `Disc番号_Track番号_タイトル.拡張子` を生成
  - `Automatically Rename to T_Title`（「T_タイトル」へ自動変更）では `Track番号_タイトル.拡張子` を生成
  - 例: Disc 1・Track 2・タイトル「楽曲名」の場合、`01_02_楽曲名.flac` または `02_楽曲名.flac`
  - Windows禁止文字、制御文字、CP932非互換文字は半角スペースへ置換
- 列見出しのクリックによる自然順の昇順・降順ソート
- 再生モードと編集モードの明確な切替
  - 再生モードではセル編集を無効化し、ダブルクリックで再生
  - 編集モード中は再生を停止し、矢印移動・直接入力・F2・ダブルクリックで編集
  - コピーした単一セルの値を、選択範囲全体へ一括貼り付け
  - マウスドラッグでセル範囲を選び、入力後の `Ctrl+Enter` で全セルへ一括確定
  - `Ctrl+Z` で最大5操作前まで元に戻す（一括編集はまとめて1操作）
  - 編集終了時に変更された曲だけのタグを自動保存
  - ファイル名の自動変更は `D_T_タイトル` または `T_タイトル` を選択した場合のみ実行
  - 変更曲が0件の場合はファイル保存と完了ダイアログを省略
- 選択曲への一括入力（編集モード）
  - アーティスト、アルバム、ジャンルのチェック項目だけを一括上書き
  - 文字入力で自動チェック、チェック済み空欄による一括消去
  - JPEG / PNGのドラッグ＆ドロップでジャケット画像を一括埋め込み・即時保存
  - 文字項目の一括変更は `Ctrl+Z` で1操作として元に戻せます
  - 編集モードの正常終了後は入力欄とチェックを初期化
- 選択曲のタイトル末尾へ、ドロップダウンで選んだ接尾辞を一括付加
  - 初期値は `(off vocal)` / `(instrumental)`
  - `Settings > Title Suffix Settings…`（日本語表示では `設定 > タイトル接尾辞の設定…`）で最大20件まで登録可能
  - 設定画面では追加・編集・削除・ドラッグまたは上下ボタンによる表示順変更に対応
  - 付加時に、接尾辞の手前へ半角スペースを入れるか選択可能
  - 同じ接尾辞の重複を防ぎ、既知の接尾辞が末尾にある場合は選択した接尾辞へ置換
- FLAC / MP3 / WAV / AIFF / M4Aへのタグ保存（形式により対応範囲は異なります）
- FLAC / MP3 / WAV / AIFF / M4AへのJPEG/PNGアートワーク埋め込み
  - 選択曲へメニューから埋め込み
  - 右上のアートワーク枠へJPEG/PNGをドロップして即時保存
  - 選択曲の埋め込み画像だけを削除して即時保存
- 同期歌詞（LRC）の作成・打刻・再生同期表示
  - 通常曲は音声ファイルと同名の `.lrc` を同じフォルダーで管理
  - タグ保存によって通常曲のファイル名を自動変更した場合、同名の `.lrc` も新しい音源名へ連動して変更
  - 1つの音源を分割したCUE仮想トラックは、`CUE名 - Track 01.lrc`のように曲番号別で管理
  - CUE仮想トラックのタイムスタンプは各曲の先頭を `00:00.00` とする相対時間
  - CUE内の楽曲タイトルを編集しても、CUE名とTrack番号によるLRCの関連付けを維持

## 別のWindows PCへ持っていくもの

Pythonだけでは起動できず、`requirements.txt` に記載された依存パッケージも必要です。
別PCには、このプロジェクトフォルダーを丸ごとコピーしてください。ただし、次のものは
コピーしなくても構いません。

- `.venv`（PCごとに作り直すため、コピー非推奨）
- `__pycache__`
- `tests`（利用時には不要）
- `music`（アプリ本体には不要。収録した音楽も移す場合だけコピー）

最低限必要なものは `app.py`、`musicgridstudio` フォルダー、`requirements.txt`、
`setup_musicgridstudio.bat`、`run_musicgridstudio.vbs` です。USB DAC固有のドライバーが
必要な場合は、移行先PCにもメーカーのドライバーをインストールしてください。

プレイリストはユーザーごとのWindowsアプリデータ領域に保存され、曲への絶対パスを
保持しています。そのため、アプリのフォルダーをコピーしただけでは移行されません。
移行先では音楽フォルダーを改めて追加するのが確実です。同じドライブ文字・同じ場所へ
音楽をコピーする場合は、事前にM3U8を書き出して移行先で読み込むこともできます。

## インストールと起動

1. [Python 3.12](https://www.python.org/downloads/windows/) をインストールします。
   インストーラーでは「Python Launcher」を有効にしてください。
2. 初回だけ `setup_musicgridstudio.bat` をダブルクリックします。プロジェクト内へ
   `.venv` を作成し、必要なパッケージを自動でインストールします。この処理には
   インターネット接続が必要です。
3. セットアップ後は `run_musicgridstudio.vbs` をダブルクリックして起動します。
   この方法では黒いコンソール画面は表示されません。

手動でセットアップする場合は、PowerShellまたはコマンドプロンプトでこのフォルダーへ
移動し、次を実行します。

```powershell
py -3 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
```

起動します。

```powershell
.\.venv\Scripts\python.exe app.py
```

`run_musicgridstudio.bat` も使用できます。こちらも `pythonw.exe` で起動するため、正常時は
黒い画面が残りませんが、BATの起動時に一瞬だけ表示される場合があります。完全に表示を
避けるには `run_musicgridstudio.vbs` を使用してください。本体は `app.py` で、exe化は
していません。

## Windows配布用ZIPの作成

`build_windows.bat` を実行すると、コンソールを表示しない64bit版の
`MusicGridStudio.exe`と必要DLLをフォルダー形式で生成し、`release`フォルダーへZIPで
出力します。EXEの製作者・作成者・更新者・会社名・著作権者は `LeLien Consulting` に設定されます。
単一EXEには圧縮せず、UPXも使用しないため、一般に単一ファイル形式よりウイルス対策
ソフトの誤検知を受けにくい構成です。ただし、コード署名されていないEXEの警告や誤検知を
完全に防ぐことはできません。

配布ZIPには第三者ライセンス、製作者情報、このビルドに対応するソースも同梱します。
特にMutagenはGPL-2.0-or-laterなので、有償頒布前にソース提供などの条件を確認してください。

## アップデートパッケージ

配布版には独立した `MusicGridStudioUpdater.exe` が同梱されます。利用者は
`Information > Apply Update Package…`（日本語表示では
`情報 > アップデートパッケージを適用…`）から公式の更新ZIPを選択できます。
更新前には製品名、対象バージョン、x64版、全ファイルのSHA-256を検証します。
適用中に問題が発生した場合は変更前のファイルへ自動的に戻します。
設定、プレイリスト、背景画像などのユーザーデータは更新対象に含まれません。
SHA-256検証はダウンロード破損や内容の不一致を検出するためのものです。
公開配布時に発行元の真正性まで保証するには、HTTPSでの配布に加えて、
MusicGridStudio本体・更新プログラム・更新ZIPへのデジタル署名を推奨します。

将来の更新ZIPは、旧版と新版の配布フォルダーを残した状態で次のように作成します。

```powershell
.\.venv\Scripts\python.exe .\packaging\create_update_patch.py `
  --base .\release\MusicGridStudio_v0.15.0_Windows_x64 `
  --target .\release\MusicGridStudio_v1.0.0_Windows_x64 `
  --output .\release\MusicGridStudio_Update_v0.15.0_to_v1.0.0.zip
```

更新ZIPは指定された旧版から新版への専用品です。複数バージョンを飛ばす利用者には、
該当する旧版向け更新ZIPまたは最新版の通常配布ZIPを案内してください。

## 操作

- 表示言語: `Settings > Language` から `English` または `Japanese`
- 配色テーマ: `Settings > Theme` から Dark / White / Blue / Pink / Yellow
- バージョン情報: `Information > About MusicGridStudio…`
- 更新ZIPの適用: `Information > Apply Update Package…`
- 曲の追加: 上部の「音楽を追加」、`Ctrl+O`、または中央の表へドロップ
- フォルダーの追加: ファイルメニュー、または中央の表へフォルダーをドロップ
- CUEの追加: `.cue`単体またはCUEを含むフォルダーを追加。参照音源はCUEの`FILE`と同じ場所に配置
- 再生モード（起動時の標準状態）:
  - 曲をダブルクリックして再生
  - セル編集、貼り付け、タグ変更操作は無効
- 編集モード:
  - 上部の「編集モード」または `Ctrl+E` で開始。再生は自動停止します
  - 曲順のドラッグ変更は無効になり、マウスドラッグはセル範囲選択になります
  - 矢印キーでセルを移動し、そのまま文字を入力して編集
  - F2、ダブルクリックでも編集可能。ダブルクリック再生は行いません
  - マウスで任意のセル範囲を選択し、値を入力して `Ctrl+Enter` を押すと、選択範囲全体へ同じ値を設定
  - 単一セルを `Ctrl+C` し、Shiftで同じ列の範囲を選択して `Ctrl+V` すると全セルへ同じ値を設定
  - Deleteキーは選択セルの内容を消去
  - 入力、貼り付け、`Ctrl+Enter`、Delete、自動連番、タイトル接尾辞は `Ctrl+Z` で最大5操作前まで戻せます
  - 「編集を終了」または `Ctrl+E` で変更済みの曲だけを保存し、成功後に再生モードへ戻ります
  - 保存失敗またはキャンセル時は編集モードを維持するため、内容を確認して再試行できます
- 一括入力（編集モード中）:
  1. 表で対象曲を選択（全曲は `Ctrl+A`）
  2. アーティスト、アルバム、ジャンルを入力。入力した項目は自動でチェックされます
  3. ジャケット画像はJPEG / PNGを入力欄へドロップ、または「参照」で選択
  4. 「選択曲へ一括反映」を押すと、チェック済み項目だけを反映
- 一時停止/再開: 中央下の丸いボタン、または `Space`（`Ctrl+Space`も使用可能）
- シーク: 再生バー上の任意の位置をクリック、またはつまみをドラッグ
- 停止: 再生ボタン右側の「■」、または `Ctrl+.`
- 再生順: 右側の「再生オプション」で「連続再生」または「シャッフル再生」を選択
- リピート: 同じ欄で「オフ」「全曲」「1曲」を選択
- ギャップレス: 「ギャップレス再生」のチェックでオン・オフ
  - CUE仮想トラックは区間の正確さを優先し、通常の曲切替を使用します
- 曲順変更（再生モード）: 行を選び、移動先へドラッグ
- プレイリスト名の変更: 左側で対象を選択して「名称変更」を押すか、名前をダブルクリック
  - システム用の「再生キュー」は名称変更できません
- 別プレイリストへの曲のコピー（再生モード）: 中央の表で曲を選択し、左側のコピー先プレイリスト名へドラッグ＆ドロップ
  - 元のプレイリストからは削除されず、コピー先の末尾へ追加されます
  - コピー先に既にある曲は重複して追加されません
  - コピー後のタグ編集やファイル名変更は、同じ曲が入っている他のプレイリストにも同期されます
- 自動連番（編集モード中）: 上部の「Disc / Track 自動連番」。Disc番号とTrack開始番号を指定
- タイトル接尾辞（編集モード中）: 対象曲を選択して上部の「タイトル接尾辞」をクリックし、
  登録済みの最大20件から選択。半角スペースを接尾辞の手前へ入れるかも指定できます
- 接尾辞の管理: `Settings > Title Suffix Settings…`（日本語表示では
  `設定 > タイトル接尾辞の設定…`）で接尾辞とドロップダウンの表示順を編集
- ジャンル入力（編集モード中）: ジャンルセルまたは一括入力のジャンル欄へ文字を入力すると、
  登録済み候補を大文字・小文字を区別しない前方一致で絞り込みます。候補は `Enter` で確定でき、
  候補にないジャンルもそのまま直接入力できます。欄をマウスでクリックすると全候補が開き、
  マウスで選択することもできます
- ジャンル候補の管理: `Settings > Genre Suggestion Settings…`（日本語表示では
  `設定 > ジャンル候補の設定…`）で追加・編集・削除・ドラッグまたは上下移動による表示順変更が可能
- タグ列の管理: `Settings > Tag Settings…`（日本語表示では
  `設定 > タグの設定…`）を開き、左の「登録可能なタグ」から右の「現在表示するタグ」へ追加
  - 右側リストの上にあるタグほど、プレイリスト表では左側へ表示されます
  - 右側リストはドラッグ、または「上へ」「下へ」で並べ替えられます
  - 右側でタグを選ぶと、日本語モードで表示する列名を自由に変更できます
  - ファイル名・形式・音質・長さはシステム列として常に表示されます
  - 「初期設定へ戻す」で従来のタイトル、アーティスト、アルバム、ジャンル、Disc、Track構成へ戻せます
- `Rating WMP` の編集（再生モード・編集モード共通）:
  - 星の位置を左クリックすると1～5を設定します（例: 4番目をクリックすると `★★★★☆`）
  - 現在と同じ星をもう一度クリックするか、右クリックすると `☆☆☆☆☆` へ戻ります
  - 列見出しをクリックすると、表示文字ではなく内部の0～5の数値で並べ替えます
  - 再生モードでは変更を自動保存します。再生中のファイルは音を途切れさせないため、表示を即時更新し、停止時またはアプリ終了時にファイルへ保存します
- タグの確定（編集モード中）: 対象行を選択し「タグを保存」または `Ctrl+S`
  - 初期設定では元のファイル名を維持します
  - 設定メニューで `D_T_タイトル` または `T_タイトル` を選ぶと、保存時に選択した形式へ変更されます
  - 全件成功時は「保存が完了しました！」ダイアログと保存曲数を表示します
  - 一部失敗・キャンセル時は成功件数と未完了内容を表示します
  - CUE仮想トラックの編集値はプレイリストへ保存し、共有する音源ファイル自体のタグやファイル名は変更しません
- 並べ替え: タイトル、ファイル名などの列見出しをクリック。再クリックで降順
- アートワークのドラッグ＆ドロップ:
  1. 編集モードを開始
  2. プレイリストで対象曲を選択（全曲は `Ctrl+A`）
  3. 右上の「NO ARTWORK」枠へJPEG/PNG画像をドロップ
  4. 選択したすべての曲へ画像が埋め込まれ、自動保存されます
- アートワークの削除:
  1. 編集モードを開始
  2. 対象曲を選択
  3. 右上の「選択曲のアートワークを削除」をクリック
  4. 確認後、埋め込み画像だけが削除されます。他のタグや元画像は残ります
- 全画面切替: `F11`
- USB DAC: 右下の音声出力モードを選び、「音声出力デバイス」から選択

## 音質について

「標準（Windows共有）」では、Windows側の既定フォーマットに応じてミキサーで変換
される場合があります。「WASAPI排他（ネイティブ）」ではWindowsミキサーを迂回し、
音源本来のサンプルレートでDACを開きます。まず元のPCM形式を試し、DACが32bit整数や
float32を受け付けない場合だけ、サンプルレートを変えず24bit、次に16bitを試します。
使用中の形式と「ネイティブ」「デコード出力」「変換 32bit→24bit」などの状態は
右下に表示されます。ソフトウェア音量は100%固定です。

WASAPI排他エンジンは現在、libsndfileが読み込めるWAV、FLAC、AIFF、Ogg、MP3等を
対象とします。M4A/AACなど排他エンジンがデコードできない形式や、選択DACが同じ
サンプルレートの16/24/32bit・float形式をすべて拒否した場合は、理由を表示して
Windows共有モードへ切り替えます。

## 次の開発段階

1. タグ編集のRedo、列フィル、オンラインメタデータ取得
2. ライブラリ監視、検索、ReplayGain、DSP、キーボード設定
