File size: 5,767 Bytes
19bd8b9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import sys
import json
import time
import random
import librosa  # The new library for real audio analysis
import numpy as np # The library for numerical operations

# --- This is our new "intelligence" factor ---
# We'll consider any audio with average energy below this threshold as silence.
# You can experiment with this value; lower values make it more sensitive to quiet sounds.
SILENCE_THRESHOLD = 0.001

def get_mock_species_data(species_name):
    """

    Returns a rich, detailed data structure for a given species name.

    This simulates a database lookup for species information.

    """
    all_species = {
        "European Robin": { "scientificName": "Erithacus rubecula", "icon": "🐦", "conservationStatus": "Least Concern", "description": "A small insectivorous passerine bird. Known for its bright orange-red breast.", "habitat": "Woodlands, parks, gardens", "frequency": "2-6 kHz", "callType": "Melodic song", "sound": "Clear, warbling notes" },
        "Great Tit": { "scientificName": "Parus major", "icon": "🐦", "conservationStatus": "Least Concern", "description": "A distinctive bird with a black head and neck, prominent white cheeks, and a black stripe down its yellow front.", "habitat": "Deciduous woodland, gardens", "frequency": "3-7 kHz", "callType": "Repetitive two-note song", "sound": "'Teacher-teacher' sound" },
        "Common Nightingale": { "scientificName": "Luscinia megarhynchos", "icon": "🎶", "conservationStatus": "Least Concern", "description": "A small passerine bird best known for its powerful and beautiful song.", "habitat": "Dense scrub and woodland", "frequency": "1-8 kHz", "callType": "Complex, rich song", "sound": "Crescendo of notes" },
        "Red-winged Blackbird": { "scientificName": "Agelaius phoeniceus", "icon": "⚫", "conservationStatus": "Least Concern", "description": "A passerine bird of the family Icteridae. Males are black with a red and yellow shoulder patch.", "habitat": "Marshes, wetlands", "frequency": "2-4 kHz", "callType": "Gurgling song", "sound": "'Conk-la-ree' sound" }
    }
    return all_species.get(species_name, { "scientificName": "Unknown", "icon": "❓", "conservationStatus": "Unknown", "description": "Could not identify species.", "habitat": "Unknown", "frequency": "N/A", "callType": "N/A", "sound": "N/A" })

def analyze_audio_file(file_path):
    """

    A smarter simulation of AI audio analysis.

    It now performs REAL energy analysis to detect silence.

    """
    # --- REAL ANALYSIS STEP ---
    # Load the audio file using librosa. This gives us the raw sound wave (y)
    # and the sample rate (sr).
    y, sr = librosa.load(file_path, sr=None, mono=True, res_type='kaiser_fast')

    # Calculate the Root Mean Square (RMS) energy, a measure of average volume.
    rms_energy = np.sqrt(np.mean(y**2))

    # --- INTELLIGENT DECISION STEP ---
    # If the energy is below our silence threshold, return a specific "silent" result.
    if rms_energy < SILENCE_THRESHOLD:
        return {
            "confidence": 95,
            "analysisQuality": "High",
            "detectedSpecies": [], # Return an empty list of species
            "biodiversityMetrics": {
                "biodiversityScore": 0,
                "shannonIndex": 0,
                "ecosystemHealth": "Unknown (Silence)"
            },
            "acousticFeatures": { "duration": librosa.get_duration(y=y, sr=sr), "sampleRate": sr },
            "recommendations": [
                "No significant audio was detected in this recording.",
                "Try recording in a location with more natural sounds.",
                "Ensure your microphone is working and not covered."
            ]
        }

    # --- SIMULATION STEP (if sound is detected) ---
    # If the audio is NOT silent, we proceed with our previous simulation.
    time.sleep(random.uniform(1.5, 2.5)) # Simulate processing time

    possible_species = ["European Robin", "Great Tit", "Common Nightingale", "Red-winged Blackbird"]
    num_detected = random.randint(1, 3)
    detected_species_names = random.sample(possible_species, num_detected)

    detected_species_results = []
    for species_name in detected_species_names:
        species_data = get_mock_species_data(species_name)
        species_data["name"] = species_name
        species_data["confidence"] = random.randint(75, 98)
        detected_species_results.append(species_data)

    biodiversity_score = 60 + len(detected_species_results) * 15 + random.randint(-5, 5)
    ecosystem_health = "Excellent" if biodiversity_score > 85 else "Good" if biodiversity_score > 70 else "Fair"
    shannon_index = round(1.2 + len(detected_species_results) * 0.2 + random.uniform(-0.1, 0.1), 2)

    return {
        "confidence": random.randint(85, 99),
        "analysisQuality": "High",
        "detectedSpecies": detected_species_results,
        "biodiversityMetrics": {
            "biodiversityScore": biodiversity_score,
            "shannonIndex": shannon_index,
            "ecosystemHealth": ecosystem_health
        },
        "acousticFeatures": { "duration": librosa.get_duration(y=y, sr=sr), "sampleRate": sr },
        "recommendations": [
            "This area shows healthy species diversity.",
            "Consider conservation efforts for nearby wetlands.",
            "Continue monitoring during migratory seasons."
        ]
    }

if __name__ == "__main__":
    try:
        audio_file_path = sys.argv[1]
        analysis_data = analyze_audio_file(audio_file_path)
        print(json.dumps(analysis_data, indent=4))
    except Exception as e:
        print(f"Error in Python script: {e}", file=sys.stderr)
        sys.exit(1)