# (Paste your full Gradio app.py code here) !pip install -q gradio soundfile import gradio as gr from pathlib import Path # Use your project brief path from the notebook PROJECT_BRIEF_LOCAL = "/mnt/data/Project_description.pdf" def normalize_audio_path(audio_file): """Return a filesystem path (or None) from Gradio's audio input.""" if audio_file is None: return None if isinstance(audio_file, str): return audio_file if hasattr(audio_file, "name"): return audio_file.name if isinstance(audio_file, (tuple, list)) and len(audio_file) > 0: # In some cases Gradio gives (filepath, ...other stuff) return audio_file[0] return str(audio_file) # Extended cuisine map: starters / main / desserts, separated veg / non-veg CUISINE_MAP = { "kerala": { "region": "Kerala", "starters_veg": ["Banana Chips", "Vegetable Uzhunnu Vada"], "starters_nonveg": ["Kerala Fish Fry", "Chicken 65 (Kerala Style)"], "main_veg": ["Appam with Vegetable Stew", "Puttu with Kadala Curry"], "main_nonveg": ["Kerala Fish Curry", "Beef Ularthiyathu", "Chicken Stew"], "desserts": ["Palada Payasam", "Ada Pradhaman"], }, "hindi": { "region": "North India (Hindi-speaking belt)", "starters_veg": ["Paneer Tikka", "Veg Samosa"], "starters_nonveg": ["Chicken 65", "Mutton Seekh Kabab"], "main_veg": ["Paneer Butter Masala", "Dal Makhani", "Aloo Paratha"], "main_nonveg": ["Butter Chicken", "Rogan Josh", "Mutton Biryani"], "desserts": ["Gulab Jamun", "Kheer"], }, "telugu": { "region": "Andhra / Telangana", "starters_veg": ["Mirchi Bajji", "Pesarattu"], "starters_nonveg": ["Gongura Chicken Fry", "Chepala Vepudu"], "main_veg": ["Pappu (dal) with rice", "Pesara Pappu", "Gutti Vankaya"], "main_nonveg": ["Andhra Chicken Biryani", "Kodi Pulusu (Chicken Curry)"], "desserts": ["Bobbatlu (Puran Poli)", "Pootharekulu"], }, "tamil": { "region": "Tamil Nadu", "starters_veg": ["Medu Vada", "Sundal"], "starters_nonveg": ["Chicken 65 (TN style)", "Fish Fry"], "main_veg": ["Idli & Sambar", "Masala Dosa", "Rasam Rice"], "main_nonveg": ["Chettinad Chicken", "Fish Curry (Meen Kuzhambu)"], "desserts": ["Payasam", "Kesari"], }, "malayalam": { "region": "Kerala", "starters_veg": ["Banana Chips", "Vegetable Uzhunnu Vada"], "starters_nonveg": ["Kerala Fish Fry", "Chicken 65 (Kerala)"], "main_veg": ["Appam with Vegetable Stew", "Puttu and Kadala Curry"], "main_nonveg": ["Kerala Fish Curry", "Beef Ularthiyathu", "Chicken Stew"], "desserts": ["Palada Payasam", "Ada Pradhaman"], }, "kannada": { "region": "Karnataka", "starters_veg": ["Maddur Vada", "Bonda"], "starters_nonveg": ["Kheema Cutlet"], "main_veg": ["Bisi Bele Bath", "Ragi Mudde", "Akki Roti"], "main_nonveg": ["Mangalorean Chicken Curry", "Neer Dosa with Fish Curry"], "desserts": ["Mysore Pak", "Kesari"], }, "bengali": { "region": "West Bengal", "starters_veg": ["Vegetable Chop"], "starters_nonveg": ["Fish Kabiraji", "Kolkata-style Chicken Pakora"], "main_veg": ["Shukto", "Cholar Dal with Luchi"], "main_nonveg": ["Machher Jhol (Fish Curry)", "Ilish Bhapa (Hilsa)"], "desserts": ["Mishti Doi", "Rasgulla"], }, # Jharkhand-specific mapping (use label "Jharkhand" -> "jharkhand") "jharkhand": { "region": "Jharkhand", "starters_veg": ["Dhuska", "Chilka Roti"], "starters_nonveg": ["Sohari Chicken Fry", "Kodo Chicken", "Jhal Murg"], "main_veg": ["Thekua with Chana Sabzi", "Litti Chokha"], "main_nonveg": [ "Chicken Jhol", "Mutton with Kodo/Kutki Millet", "Bamboo Shoot Chicken", ], "desserts": ["Dudh Pitha", "Gur ki Roti"], }, "gujarati": { "region": "Gujarat", "starters_veg": ["Dhokla", "Khandvi"], "starters_nonveg": ["(Typically veg cuisine; pick local non-veg if needed)"], "main_veg": ["Undhiyu", "Khichdi", "Thepla"], "main_nonveg": ["(Typically veg cuisine; pick local non-veg if needed)"], "desserts": ["Basundi", "Shrikhand"], }, # default fallback "default": { "region": "Unknown / Other", "starters_veg": ["Local vegetarian starters"], "starters_nonveg": ["Local non-veg starters"], "main_veg": ["Local vegetarian mains"], "main_nonveg": ["Local non-veg mains"], "desserts": ["Local desserts"], }, } # NEW: map HuBERT / MFCC labels (state names etc.) to cuisine keys above LABEL_ALIAS = { # Andhra / Telangana "andhra_pradesh": "telugu", "ap": "telugu", "andhra": "telugu", "telugu": "telugu", "telangana": "telugu", # Kerala "kerala": "kerala", "malayalam": "malayalam", # Tamil Nadu "tamil_nadu": "tamil", "tamil": "tamil", # Karnataka "karnataka": "kannada", "kannada": "kannada", # Jharkhand "jharkhand": "jharkhand", "jharkhand_state": "jharkhand", # Gujarat "gujarat": "gujarati", "gujarati": "gujarati", # West Bengal "west_bengal": "bengali", "bengal": "bengali", "bengali": "bengali", # North India / Hindi belt "hindi": "hindi", "north_india": "hindi", "delhi": "hindi", } def format_cuisine_output(pred_label: str) -> str: """Format cuisine recommendations as a readable multiline string.""" key = pred_label.lower().strip() key = key.replace(" ", "_") # handle "Andhra Pradesh" → "andhra_pradesh" key = LABEL_ALIAS.get(key, key) # map state-style labels → cuisine keys info = CUISINE_MAP.get(key, CUISINE_MAP["default"]) lines = [] lines.append(f"Inferred region: {info['region']}") lines.append("") lines.append("Starters (Veg): " + ", ".join(info["starters_veg"])) lines.append("Starters (Non-Veg): " + ", ".join(info["starters_nonveg"])) lines.append("") lines.append("Main Course (Veg): " + ", ".join(info["main_veg"])) lines.append("Main Course (Non-Veg): " + ", ".join(info["main_nonveg"])) lines.append("") lines.append("Desserts: " + ", ".join(info["desserts"])) return "\n".join(lines) def ui_predict_multi(audio_file, feature_choice, hubert_layer_idx, use_trained_model): """Main function used by Gradio UI.""" audio_path = normalize_audio_path(audio_file) if audio_path is None: return "No audio provided", "" feat = "hubert" if feature_choice == "HuBERT" else "mfcc" # If using trained model, pick the correct model info if use_trained_model: model_info = app_state.get("models", {}).get(feat) if not model_info: return ( f"No trained {feat.upper()} model available on server. " "Train it or uncheck 'Use trained model'.", "", ) clf = model_info["clf"] scaler = model_info["scaler"] le = model_info["le"] if feat == "hubert" and hubert_layer_idx != model_info.get( "layer", hubert_layer_idx ): return ( f"Note: the HuBERT model was trained on layer " f"{model_info.get('layer')}. Set the slider to that layer or re-train.", "", ) else: # Fallback path: only MFCC fallback is implemented if feat != "mfcc": return ( "Fallback training is only available for MFCC. " "Choose MFCC or upload HuBERT artifacts.", "", ) # Try to train a quick MFCC model using local data/ folder wav_paths = [] if Path("data").exists(): wav_paths = [str(p) for p in Path("data").rglob("*.wav")] model_info = train_fast_mfcc_fallback(wav_paths[:200]) if model_info is None: return ( "No fallback MFCC model could be trained (not enough data). " "Upload model artifacts or provide a data/ folder.", "", ) clf = model_info["clf"] scaler = model_info["scaler"] le = model_info["le"] # Extract features try: if feat == "mfcc": x = extract_mfcc_pooled(audio_path) else: x = get_hubert_layer_embedding(audio_path, layer_idx=hubert_layer_idx) except Exception as e: return f"Feature extraction failed: {e}", "" # Predict try: Xs = scaler.transform(x.reshape(1, -1)) pred_idx = clf.predict(Xs)[0] pred_label = le.inverse_transform([pred_idx])[0] except Exception as e: return f"Prediction failed (shape mismatch or model error): {e}", "" # Format cuisine recommendations cuisine_text = format_cuisine_output(pred_label) return pred_label, cuisine_text # Build Gradio UI with gr.Blocks() as demo: gr.Markdown("## Accent Detection + Cuisine Recommendation Demo") gr.Markdown(f"[📄 Open Project Brief]({PROJECT_BRIEF_LOCAL})") with gr.Row(): audio_in = gr.Audio( type="filepath", label="Upload audio (.wav/.flac/.mp3)", ) with gr.Column(): feature_choice = gr.Radio( ["MFCC", "HuBERT"], value="MFCC", label="Feature Type", ) hubert_layer_idx = gr.Slider( minimum=0, maximum=24, value=11, step=1, label="HuBERT Layer", ) use_trained_model = gr.Checkbox( value=True, label="Use trained model from notebook", ) btn = gr.Button("Predict & Recommend") output_label = gr.Textbox(label="Predicted Accent") output_cuisines = gr.Textbox( label="Recommended Cuisines (starters, mains, desserts separated)", lines=12, ) btn.click( ui_predict_multi, inputs=[audio_in, feature_choice, hubert_layer_idx, use_trained_model], outputs=[output_label, output_cuisines], ) demo.launch(share=True)