File size: 3,864 Bytes
a361db3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
"""
Compute TDOA-based DoA for original 4-channel audio files
and update results.json with actual spatial estimates
"""

import json
from pathlib import Path
import soundfile as sf

from .doa_tdoa import compute_tdoa_based_doa_for_mixture

def analyze_4ch_doa(input_4ch_file, output_dir):
    """
    Analyze a 4-channel audio file for Direction of Arrival

    Args:
        input_4ch_file: Path to 4-channel WAV
        output_dir: Output directory where results.json exists
    """
    # Load 4-channel audio (downsample for faster TDOA computation)
    audio_4ch, sr = sf.read(str(input_4ch_file))

    # Downsample to 16 kHz for faster processing while maintaining accuracy
    downsample_factor = sr // 16000
    if downsample_factor > 1:
        audio_4ch = audio_4ch[::downsample_factor]
        sr_analysis = 16000
    else:
        sr_analysis = sr

    print(f"\nAnalyzing {input_4ch_file}")
    print(f"  Original shape: {audio_4ch.shape}")
    print(f"  Analysis sample rate: {sr_analysis} Hz (downsampled by {downsample_factor}x)")

    # Compute TDOA-based DoA
    print("\nComputing TDOA-based Direction of Arrival...")
    doa_result = compute_tdoa_based_doa_for_mixture(audio_4ch, sr_analysis)

    print(f"  Left-Right angle: {doa_result['lr_angle']:.1f}° (xcorr: {doa_result['lr_xcorr']:.3f})")
    print(f"  Front-Rear angle: {doa_result['fb_angle']:.1f}° (xcorr: {doa_result['fb_xcorr']:.3f})")

    # Update results.json with DoA information
    results_file = Path(output_dir) / 'results.json'

    if results_file.exists():
        with open(results_file) as f:
            results = json.load(f)

        # Add TDOA DoA analysis
        results['tdoa_analysis'] = {
            'input_4ch_file': str(input_4ch_file),
            'method': 'TDOA (Time Difference of Arrival) cross-correlation',
            'microphone_pairs': {
                'front_pair_lr': {
                    'channels': [0, 2],
                    'labels': ['LF', 'RF'],
                    'lr_angle_degrees': float(doa_result['lr_angle']),
                    'xcorr_confidence': float(doa_result['lr_xcorr']),
                    'interpretation': 'Negative = left, Positive = right'
                },
                'front_rear_pair': {
                    'channels': [0, 1],
                    'labels': ['LF', 'LR'],
                    'fb_angle_degrees': float(doa_result['fb_angle']),
                    'xcorr_confidence': float(doa_result['fb_xcorr']),
                    'interpretation': 'Negative = front, Positive = rear'
                }
            },
            'compass_angles': {
                '0_degrees': 'Front (center)',
                '90_degrees': 'Right',
                '180_degrees': 'Rear',
                '270_degrees': 'Left',
                'note': 'Sound source direction relative to listener'
            }
        }

        # Update direction_of_arrival field with actual result
        results['processing_methods']['direction_of_arrival'] = 'TDOA cross-correlation (4-channel analysis)'

        # Save updated results
        with open(results_file, 'w') as f:
            json.dump(results, f, indent=2)

        print(f"\n✓ Updated {results_file}")
        print("  Added TDOA analysis with spatial estimates")

        return doa_result
    else:
        print(f"✗ {results_file} not found")
        return None


if __name__ == '__main__':
    # Analyze both files
    files = [
        ('data/example_mixture.wav', 'output/analysis_example_frankenstein'),
        ('data/mixture.wav', 'output/analysis_frankenstein'),
    ]

    print("=" * 60)
    print("TDOA-Based Direction of Arrival Analysis")
    print("=" * 60)

    for input_file, output_dir in files:
        analyze_4ch_doa(input_file, output_dir)

    print("\n" + "=" * 60)
    print("✓ TDOA analysis complete")
    print("=" * 60)