前回は input_metadata() を通して、アルバム全体に共通する情報を集める仕組みを確認しました。
今回はその続きとして、各トラックごとの情報を集める input_tracks() を見ていくことにします。
 

1. はじめに

CUE シートは「アルバム情報 → トラック情報 → テキスト生成」という三段構造になっている。
その中で input_tracks() は、まさに “曲ごとの情報を順番に集める” 役割を担っている。

2. input_tracks() の目的は「曲ごとの情報を集める」だけ

input_metadata() がアルバム全体の情報をまとめたのに対し、input_tracks() は、1 曲目から最終曲まで、必要な情報を一つずつ入力してもらい、それらをリストとしてまとめて返す関数である。

ここで扱う情報は主に次の二つ。

・曲名(TITLE)
・曲の長さ(MM:SS → フレーム数)


CUE シートでは TRACK 行が曲数ぶん必要になるが、この段階では「INDEX(曲の開始位置)」はまだ決めない。
INDEX は「オフセット+それまでの曲の長さの合計」から自動計算できるため、input_tracks() では「曲名」と「曲の長さ」だけを集めることに専念している。

input_tracks() は metadata["total_tracks"] を参照しながら、「何曲ぶん入力するか」を決めてループを回す。


3. metadata を渡す理由

関数の呼び出しは次のようになっている。

    tracks = input_tracks(metadata)

metadata を渡している理由は、トラック入力や一覧表示に必要な情報が
metadata に含まれているためである。

・アルバムの総トラック数(total_tracks)
・オフセット(offset_frames:開始位置の補正)
・アルバムアーティスト名(必要に応じて参照)


input_tracks() の中では、まず total_tracks を使って
「何曲ぶん入力するか」を決める。

さらに、入力後の確認フェーズでは offset_frames を起点として、
各トラックの長さを足し上げながら INDEX を計算し、
「TRACK xx: 曲名 / MM:SS → INDEX 01 mm:ss:ff」
という形で一覧表示している。


4. input_tracks() の全体像(◆A〜◆H 対応)

前回の input_metadata() と同じように、
今回もコードの各処理に ◆A〜◆H の記号を付けて、
フローチャートと 1 対 1 で対応するようにしている。

これにより、読者は「どの処理がどの図に対応しているか」を迷わず追えるようになる。

以下が、コメント付きの input_tracks() の全体像である。

    # === トラック情報入力(曲名と時間) ===
    def input_tracks(metadata: Metadata) -> list[dict]:
        tracks = []

        print("\n🎼 トラック情報の入力:")

        # ◆A: 1曲目から順に、曲名と時間を入力
        for i in range(1, metadata["total_tracks"] + 1):

            # ◆B: 曲名を入力
            title = input(f"TRACK {i:02} の曲名: ")

            # ◆C: 時間(MM:SS)を入力し、形式チェック
            while True:
                new_length = input(f"TRACK {i:02} の曲時間(MM:SS): ").strip()
                try:
                    duration = mmss_to_frames(new_length)
                    break
                except ValueError:
                    print("⚠️ MM:SS 形式で入力してください(例: 3:35)")

            # ◆D: 入力された1曲分を tracks に追加
            tracks.append({"title": title, "duration": duration})

        # ◆E: 入力後の一覧確認ループ
        while True:
            print("\n📜 トラック一覧:")
            current_index = metadata["offset_frames"]

            # ◆F: INDEX を計算しながら一覧表示
            for i, track in enumerate(tracks, start=1):
                index_time = frames_to_cuetime(current_index)
                mmss = frames_to_mmss(track["duration"])
                print(f"  TRACK {i:02}: {track['title']} / {mmss} → INDEX 01 {index_time}")
                current_index += track["duration"]

            # ◆G: この内容でよいか確認
            if confirm("このトラック情報でよろしいですか"):
                return tracks

            # ◆H: 修正処理(0 = metadata に戻る)
            print("修正したいトラック番号を入力してください(0 = メタ情報に戻る)")
            try:
                choice = int(input("修正対象番号: "))

                if choice == 0:
                    metadata = input_metadata(existing=metadata)

                elif 1 <= choice <= metadata["total_tracks"]:
                    track = tracks[choice - 1]

                    # 曲名修正
                    new_title = input(
                        f"TRACK {choice:02} の曲名(現在: {track['title']}): "
                    ).strip()
                    if new_title:
                        track["title"] = new_title

                    # 時間修正
                    new_mmss = input(
                        f"TRACK {choice:02} の曲時間(MM:SS、現在: {frames_to_mmss(track['duration'])}): "
                    ).strip()
                    if new_mmss:
                        try:
                            track["duration"] = mmss_to_frames(new_mmss)
                        except ValueError:
                            print("⚠️ MM:SS 形式で入力してください(例: 3:35)")

                else:
                    print("⚠️ 無効な番号です")

            except ValueError:
                print("⚠️ 数値で入力してください")



5. input_tracks() が返すもの

最終的に input_tracks() は、各曲の情報を辞書としてまとめたリストを返す。

例:

    [
        {"title": "曲名1", "duration": 12345},
        {"title": "曲名2", "duration": 17890},
        ...
    ]

ここでの duration はフレーム数であり、
実際の CUE シートに書き出すときには、

・オフセット(offset_frames)
・各トラックの duration の累積


を使って INDEX 01 mm:ss:ff を計算する。

この tracks リストが、次の generate_cue_text() に渡され、TRACK 行の生成に使われる。

6. 次回予告

次回は generate_cue_text() の実際のコードを引用しながら、

・metadata と tracks をどのように受け取り  
・どのように INDEX を計算し  
・どのように CUE シートのテキストへ落とし込んでいくのか

を順番に見ていく予定だ。
 

いかがだろうか?ここまで来ると、CUE シート生成の全体像が「入力 → 確認 → テキスト生成」という一本の線としてはっきり見えてくると思います。
 

イメージ 1 ← にほんブログ村「科学」-「技術・工学」へ
 ↑ クリックをお願いします