import argparse
import struct
import sys

# 一度に処理するチャンクサイズ
CHUNK_SIZE = 8192

def convert_s16_to_u16(input_path, output_path):
    """
    符号付き16bitのRAWオーディオファイルを符号なし16bitに変換する。
    """
    print(f"変換を開始します: '{input_path}' -> '{output_path}'")
    
    try:
        with open(input_path, 'rb') as infile, open(output_path, 'wb') as outfile:
            while True:
                # ファイルからチャンクを読み込む
                s16_chunk = infile.read(CHUNK_SIZE)
                if not s16_chunk:
                    break  # ファイルの終端に達したらループを抜ける

                # チャンク内のサンプル数を計算 (1サンプル = 2バイト)
                num_samples = len(s16_chunk) // 2

                # バイト列を符号付き16bit整数のタプルにアンパックする
                # '<' はリトルエンディアンを指定
                s16_samples = struct.unpack(f'<{num_samples}h', s16_chunk)

                # 各サンプルを符号なしに変換 (サンプル値 + 32768)
                u16_samples = [((s + 32768) >> 4) for s in s16_samples]

                # 符号なし整数のリストをバイト列にパックする
                # '*' はリストの要素を展開して関数の引数として渡す
                u16_chunk = struct.pack(f'>{num_samples}H', *u16_samples)

                # 変換後のチャンクを出力ファイルに書き込む
                outfile.write(u16_chunk)
                
        print("変換が正常に完了しました！")

    except FileNotFoundError:
        print(f"エラー: 入力ファイルが見つかりません '{input_path}'", file=sys.stderr)
        sys.exit(1)
    except Exception as e:
        print(f"エラーが発生しました: {e}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="RAWオーディオファイルを符号付き16bitから符号なし16bitに変換します。"
    )
    parser.add_argument("input_file", help="入力ファイルパス (signed 16-bit raw)")
    parser.add_argument("output_file", help="出力ファイルパス (unsigned 16-bit raw)")
    
    args = parser.parse_args()
    
    convert_s16_to_u16(args.input_file, args.output_file)
    