S-Vetrivel commited on
Commit
1f10fcd
·
1 Parent(s): 4b4453a

Fix: Add debug logging and robust padding to audio processing

Browse files
Files changed (2) hide show
  1. app/audio.py +27 -5
  2. reproduce_error.py +44 -0
app/audio.py CHANGED
@@ -21,27 +21,49 @@ def process_audio(input_data) -> torch.Tensor:
21
  # Check if it's a file path
22
  try:
23
  if os.path.isfile(input_data):
 
24
  audio_segment = AudioSegment.from_file(input_data)
25
  else:
26
  raise FileNotFoundError
27
  except:
28
  # Assume Base64 string if file load fails
29
- # 1. Clean up "data:audio/mp3;base64," prefix if present
 
 
30
  clean_b64 = input_data
31
  if "," in clean_b64:
32
  clean_b64 = clean_b64.split(",", 1)[1]
33
-
34
- # 2. Remove whitespace/newlines which break some decoders
35
  clean_b64 = clean_b64.strip().replace("\n", "").replace(" ", "")
36
 
37
- decoded_bytes = base64.b64decode(clean_b64)
38
- audio_segment = AudioSegment.from_file(io.BytesIO(decoded_bytes))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  elif isinstance(input_data, bytes):
40
  audio_segment = AudioSegment.from_file(io.BytesIO(input_data))
41
  else:
42
  raise ValueError("Unsupported input type. Expected: str (path/base64) or bytes.")
43
 
44
  except Exception as e:
 
45
  raise ValueError(f"Failed to load audio: {e}")
46
 
47
  # 2. Resample to 16kHz
 
21
  # Check if it's a file path
22
  try:
23
  if os.path.isfile(input_data):
24
+ print(f"DEBUG: Loading audio from file: {input_data}")
25
  audio_segment = AudioSegment.from_file(input_data)
26
  else:
27
  raise FileNotFoundError
28
  except:
29
  # Assume Base64 string if file load fails
30
+ print("DEBUG: Processing input as Base64 string...")
31
+
32
+ # 1. Clean up headers and whitespace
33
  clean_b64 = input_data
34
  if "," in clean_b64:
35
  clean_b64 = clean_b64.split(",", 1)[1]
 
 
36
  clean_b64 = clean_b64.strip().replace("\n", "").replace(" ", "")
37
 
38
+ # 2. Fix Padding
39
+ missing_padding = len(clean_b64) % 4
40
+ if missing_padding:
41
+ clean_b64 += '=' * (4 - missing_padding)
42
+
43
+ print(f"DEBUG: Base64 string length: {len(clean_b64)}")
44
+
45
+ try:
46
+ decoded_bytes = base64.b64decode(clean_b64)
47
+ print(f"DEBUG: Decoded bytes length: {len(decoded_bytes)}")
48
+ print(f"DEBUG: First 16 bytes: {decoded_bytes[:16].hex()}")
49
+
50
+ # 3. Explicitly try MP3 first, then let pydub probe
51
+ try:
52
+ audio_segment = AudioSegment.from_file(io.BytesIO(decoded_bytes), format="mp3")
53
+ except Exception as mp3_err:
54
+ print(f"DEBUG: Explicit MP3 load failed ({mp3_err}), trying auto-detection...")
55
+ audio_segment = AudioSegment.from_file(io.BytesIO(decoded_bytes))
56
+
57
+ except Exception as b64_err:
58
+ print(f"ERROR: Base64 decode failed: {b64_err}")
59
+ raise ValueError(f"Invalid Base64 string: {b64_err}")
60
  elif isinstance(input_data, bytes):
61
  audio_segment = AudioSegment.from_file(io.BytesIO(input_data))
62
  else:
63
  raise ValueError("Unsupported input type. Expected: str (path/base64) or bytes.")
64
 
65
  except Exception as e:
66
+ print(f"CRITICAL ERROR in process_audio: {e}")
67
  raise ValueError(f"Failed to load audio: {e}")
68
 
69
  # 2. Resample to 16kHz
reproduce_error.py ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from app.audio import process_audio
3
+ from pydub import AudioSegment
4
+ import numpy as np
5
+ import io
6
+ import base64
7
+
8
+ def generate_mp3_base64():
9
+ """Generates a valid 1-second MP3 sine wave and returns base64 string."""
10
+ sr = 44100
11
+ t = np.linspace(0, 1, sr, endpoint=False)
12
+ x = 0.5 * np.sin(2 * np.pi * 440 * t)
13
+ x_int = (x * 32767).astype(np.int16)
14
+ audio = AudioSegment(
15
+ x_int.tobytes(),
16
+ frame_rate=sr,
17
+ sample_width=2,
18
+ channels=1
19
+ )
20
+ mp3_io = io.BytesIO()
21
+ audio.export(mp3_io, format="mp3")
22
+ return base64.b64encode(mp3_io.getvalue()).decode('utf-8')
23
+
24
+ def test_reproduce():
25
+ print("--- 🔍 Testing Valid Audio Processing ---")
26
+
27
+ # 1. Generate Valid MP3
28
+ valid_b64 = generate_mp3_base64()
29
+ print(f"Generated Valid B64 Length: {len(valid_b64)}")
30
+
31
+ try:
32
+ # 2. Test Processing
33
+ waveform = process_audio(valid_b64)
34
+ print("\n✅ Success with Valid MP3!")
35
+ print(f"Waveform shape: {waveform.shape}")
36
+
37
+ except Exception as e:
38
+ print("\n❌ Failed with Valid MP3!")
39
+ print(e)
40
+ import traceback
41
+ traceback.print_exc()
42
+
43
+ if __name__ == "__main__":
44
+ test_reproduce()