Metadata-Version: 2.4
Name: rs_audio_stats
Version: 1.1.9
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Rust
Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
Summary: Professional-grade audio analysis tool with EBU R128 loudness measurement
Keywords: audio,loudness,ebu-r128,analysis,normalization
Author: Hiroshi Tamura
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/hiroshi-tamura/rs_audio_stats
Project-URL: Repository, https://github.com/hiroshi-tamura/rs_audio_stats

# rs_audio_stats

Professional-grade audio analysis tool with EBU R128 loudness measurement for Python.

## 概要

rs_audio_statsは、EBU R128標準（ITU-R BS.1770-4）に準拠したラウドネス測定、真のピーク検出、RMS計算、音声正規化機能を提供する包括的な音声解析ライブラリです。

## インストール

```bash
pip install rs_audio_stats
```

## クイックスタート

```python
import rs_audio_stats as ras

# 音声ファイルを解析
info, results = ras.analyze_audio("audio.wav", True, False, False, False, True, False, False)
print(f"統合ラウドネス: {results.integrated_loudness:.1f} LUFS")
print(f"真のピーク: {results.true_peak:.1f} dBFS")

# ディレクトリの一括解析
results = ras.batch_analyze_directory("audio_folder/", True, False, False, False, True, False, False)
for file_path, (info, analysis) in results.items():
    print(f"{file_path}: {analysis.integrated_loudness:.1f} LUFS")
```

## 📖 完全ドキュメント

全機能の詳細な使用方法とサンプルコードは **[GitHubリポジトリ](https://github.com/hiroshi-tamura/rs_audio_stats/blob/master/lib_python/COMPLETE_API_REFERENCE.md)** でご覧いただけます。

## 📊 音声情報の取得

### サンプルレート、チャンネル、ビット深度の取得 (-sr, -ch, -bt)

```python
import rs_audio_stats as ras

# 音声ファイル情報を取得
info = ras.get_audio_info_py("audio.wav")

print(f"サンプルレート: {info.sample_rate} Hz")        # 44100 Hz
print(f"チャンネル数: {info.channels}")                 # 2
print(f"ビット深度: {info.bit_depth} bit")              # 16 bit
print(f"サンプルフォーマット: {info.sample_format}")      # PCM
```

### 再生時間の取得 (-du, -tm)

```python
import rs_audio_stats as ras

info = ras.get_audio_info_py("audio.wav")

print(f"再生時間（秒）: {info.duration_seconds:.2f} 秒")     # 183.45 秒
print(f"再生時間（フォーマット済み）: {info.duration_formatted}")  # 03:03.45
```

### 総サンプル数とフォーマット検出 (-f, -fe, -fea)

```python
import rs_audio_stats as ras

info = ras.get_audio_info_py("audio.wav")

print(f"総サンプル数: {info.total_samples:,} サンプル")  # 8,088,000 サンプル

# ファイルサイズ計算
file_size = info.total_samples * info.channels * (info.bit_depth // 8)
print(f"計算ファイルサイズ: {file_size:,} バイト")       # 32,352,000 バイト
```

## 🎚️ EBU R128 ラウドネス解析

### 統合ラウドネス測定 (-i)

```python
import rs_audio_stats as ras

# 統合ラウドネスを測定
info, results = ras.analyze_audio("audio.wav", integrated_loudness=True)

print(f"統合ラウドネス: {results.integrated_loudness:.1f} LUFS")

# 放送基準チェック
if results.integrated_loudness >= -23.0:
    print("✅ EBU R128放送基準（-23 LUFS）を満たしています")
else:
    print(f"⚠️ 基準より低いです")
```

### 短期・モーメンタリラウドネス測定 (-s, -m)

```python
import rs_audio_stats as ras

# 短期（3秒）・モーメンタリ（400ms）ラウドネスを測定
info, results = ras.analyze_audio("audio.wav", 
    short_term_loudness=True, momentary_loudness=True)

print(f"短期ラウドネス: {results.short_term_loudness:.1f} LUFS")
print(f"モーメンタリラウドネス: {results.momentary_loudness:.1f} LUFS")
```

### ラウドネス範囲とピーク測定 (-l, -tp)

```python
import rs_audio_stats as ras

# ラウドネス範囲（LRA）と真のピークを測定
info, results = ras.analyze_audio("audio.wav", 
    loudness_range=True, true_peak=True)

print(f"ラウドネス範囲: {results.loudness_range:.1f} LU")
print(f"真のピーク: {results.true_peak:.1f} dBFS")

# ダイナミックレンジ評価
if results.loudness_range > 15.0:
    print("🎵 高いダイナミックレンジ")
elif results.loudness_range > 7.0:
    print("🎶 適度なダイナミックレンジ")
else:
    print("📻 圧縮された音源")
```

### RMS測定 (-rm, -ra)

```python
import rs_audio_stats as ras

# RMS最大値・平均値を測定
info, results = ras.analyze_audio("audio.wav", 
    rms_max=True, rms_average=True)

print(f"RMS最大値: {results.rms_max:.1f} dBFS")
print(f"RMS平均値: {results.rms_average:.1f} dBFS")
print(f"RMSダイナミックレンジ: {results.rms_max - results.rms_average:.1f} dB")
```

### 全ラウドネス指標の一括測定

```python
import rs_audio_stats as ras

# すべての指標を一度に測定
info, results = ras.analyze_audio_all("audio.wav")

print("=== 全ラウドネス指標 ===")
print(f"統合ラウドネス: {results.integrated_loudness:.1f} LUFS")
print(f"短期ラウドネス: {results.short_term_loudness:.1f} LUFS") 
print(f"モーメンタリラウドネス: {results.momentary_loudness:.1f} LUFS")
print(f"ラウドネス範囲: {results.loudness_range:.1f} LU")
print(f"真のピーク: {results.true_peak:.1f} dBFS")
print(f"RMS最大値: {results.rms_max:.1f} dBFS")
print(f"RMS平均値: {results.rms_average:.1f} dBFS")
```

## 🎛️ 音声正規化

### 真のピーク正規化 (-norm-tp)

```python
import rs_audio_stats as ras

# 真のピークを-1.0 dBFSに正規化
ras.normalize_true_peak("input.wav", -1.0, "output_peak.wav")

# 便利なラッパー関数
ras.normalize_to_dbfs("input.wav", -1.0)  # 自動で input_peaked.wav を生成
```

### 統合ラウドネス正規化 (-norm-i)

```python
import rs_audio_stats as ras

# 放送用（-23 LUFS）に正規化
ras.normalize_integrated_loudness("input.wav", -23.0, "broadcast.wav")

# ポッドキャスト用（-16 LUFS）に正規化  
ras.normalize_integrated_loudness("input.wav", -16.0, "podcast.wav")

# 便利なラッパー関数
ras.normalize_to_lufs("input.wav", -23.0)  # 自動で input_normalized.wav を生成
```

### 短期・モーメンタリラウドネス正規化 (-norm-s, -norm-m)

```python
import rs_audio_stats as ras

# 短期ラウドネス正規化
ras.normalize_short_term_loudness("input.wav", -18.0, "short_term.wav")

# モーメンタリラウドネス正規化
ras.normalize_momentary_loudness("input.wav", -16.0, "momentary.wav")
```

### RMS正規化 (-norm-rm, -norm-ra)

```python
import rs_audio_stats as ras

# RMS最大値正規化
ras.normalize_rms_max("input.wav", -12.0, "rms_max.wav")

# RMS平均値正規化
ras.normalize_rms_average("input.wav", -20.0, "rms_avg.wav")
```

## 🔄 バッチ処理

### ディレクトリの一括解析

```python
import rs_audio_stats as ras

# フォルダ内の全音声ファイルを解析
results = ras.batch_analyze_directory("audio_folder/", 
    integrated_loudness=True, true_peak=True, loudness_range=True)

print(f"解析ファイル数: {len(results)}")

# 統計情報
loudness_values = []
for file_path, (info, analysis) in results.items():
    filename = file_path.split("\\")[-1]  # ファイル名のみ
    print(f"{filename}: {analysis.integrated_loudness:.1f} LUFS")
    loudness_values.append(analysis.integrated_loudness)

avg_loudness = sum(loudness_values) / len(loudness_values)
print(f"平均ラウドネス: {avg_loudness:.1f} LUFS")
```

### 結果のエクスポート (-csv, -tsv, -xml, -json)

```python
import rs_audio_stats as ras

# バッチ解析実行
results = ras.batch_analyze_directory("audio_folder/", 
    integrated_loudness=True, true_peak=True, loudness_range=True)

# 各形式でエクスポート
ras.export_to_csv(results, "analysis_results.csv")
ras.export_to_tsv(results, "analysis_results.tsv") 
ras.export_to_xml(results, "analysis_results.xml")
ras.export_to_json(results, "analysis_results.json")

print("✅ 全形式でエクスポート完了")
```

## 🎯 実用例

### 放送用品質チェック

```python
import rs_audio_stats as ras

def broadcast_check(file_path):
    info, results = ras.analyze_audio_all(file_path)
    
    issues = []
    if results.integrated_loudness < -24.0 or results.integrated_loudness > -22.0:
        issues.append(f"ラウドネス基準外: {results.integrated_loudness:.1f} LUFS")
    if results.true_peak > -1.0:
        issues.append(f"ピーク過大: {results.true_peak:.1f} dBFS")
    
    if not issues:
        print("✅ 放送基準適合")
    else:
        for issue in issues:
            print(f"❌ {issue}")

broadcast_check("broadcast_content.wav")
```

### 音楽ストリーミング用最適化

```python
import rs_audio_stats as ras

def optimize_for_streaming(input_file, platform="spotify"):
    targets = {
        "spotify": -14.0,    # LUFS
        "apple_music": -16.0,
        "youtube": -14.0
    }
    
    target_lufs = targets.get(platform, -14.0)
    output_file = f"{input_file.split('.')[0]}_{platform}.wav"
    
    # ピーク正規化 → ラウドネス正規化
    temp_file = "temp_peak.wav"
    ras.normalize_true_peak(input_file, -1.0, temp_file)
    ras.normalize_integrated_loudness(temp_file, target_lufs, output_file)
    
    import os
    os.remove(temp_file)  # 一時ファイル削除
    
    print(f"✅ {platform}用最適化完了: {output_file}")

optimize_for_streaming("my_song.wav", "spotify")
```

### ポッドキャスト用バッチ処理

```python
import rs_audio_stats as ras
import os

def process_podcast_episodes(episodes_folder, output_folder):
    os.makedirs(output_folder, exist_ok=True)
    
    for file in os.listdir(episodes_folder):
        if file.endswith(('.wav', '.mp3', '.flac')):
            input_path = os.path.join(episodes_folder, file)
            output_path = os.path.join(output_folder, f"podcast_{file}")
            
            # ポッドキャスト推奨設定（-16 LUFS, -3 dBFS）
            temp_file = os.path.join(output_folder, f"temp_{file}")
            ras.normalize_true_peak(input_path, -3.0, temp_file)
            ras.normalize_integrated_loudness(temp_file, -16.0, output_path)
            os.remove(temp_file)
            
            print(f"✅ 処理完了: {file}")

process_podcast_episodes("raw_episodes/", "ready_episodes/")
```

## 📋 便利な関数

```python
import rs_audio_stats as ras

# 簡単にラウドネスのみ取得
loudness = ras.get_loudness("audio.wav")
print(f"ラウドネス: {loudness:.1f} LUFS")

# 簡単に真のピークのみ取得  
peak = ras.get_true_peak("audio.wav")
print(f"真のピーク: {peak:.1f} dBFS")
```

## 対応フォーマット

- **ロスレス**: WAV, FLAC, WavPack, Monkey's Audio
- **非可逆圧縮**: MP3, AAC/M4A, OGG/Vorbis, Opus
- **その他**: Symphoniaデコーダー経由で多数対応

## 動作環境

- **Python**: 3.10以上
- **OS**: Windows, macOS, Linux
- **依存関係**: なし（バイナリパッケージ）

## ライセンス

MIT License
