@@ -274,9 +274,7 @@ def test_save_audio_auto_format(tmp_path, catalog):
274274
275275def test_audio_info_file_error (audio_file ):
276276 """Test audio_info handles file errors properly."""
277- with patch (
278- "datachain.lib.audio.torchaudio.info" , side_effect = Exception ("Test error" )
279- ):
277+ with patch ("datachain.lib.audio.sf.info" , side_effect = Exception ("Test error" )):
280278 with pytest .raises (
281279 FileError , match = "unable to extract metadata from audio file"
282280 ):
@@ -285,9 +283,7 @@ def test_audio_info_file_error(audio_file):
285283
286284def test_audio_fragment_np_file_error (audio_file ):
287285 """Test audio_fragment_np handles file errors properly."""
288- with patch (
289- "datachain.lib.audio.torchaudio.info" , side_effect = Exception ("Test error" )
290- ):
286+ with patch ("datachain.lib.audio.sf.info" , side_effect = Exception ("Test error" )):
291287 with pytest .raises (FileError , match = "unable to read audio fragment" ):
292288 audio_to_np (audio_file )
293289
@@ -322,34 +318,30 @@ def test_audio_to_bytes_formats(audio_file, format_type):
322318
323319
324320@pytest .mark .parametrize (
325- "encoding, file_ext,expected_format" ,
321+ "format_str,subtype, file_ext,expected_format,expected_bit_rate " ,
326322 [
327- # Test direct encoding mappings
328- ("FLAC" , "flac" , "flac" ),
329- ("MP3" , "mp3" , "mp3" ),
330- ("VORBIS" , "ogg" , "ogg" ),
331- ("OPUS" , "opus" , "opus" ),
332- ("AMR_WB" , "amr" , "amr" ),
333- ("AMR_NB" , "amr" , "amr" ),
334- ("GSM" , "gsm" , "gsm" ),
335- # Test PCM variants with different extensions
336- ("PCM_S16LE" , "wav" , "wav" ),
337- ("PCM_S24LE" , "aiff" , "aiff" ),
338- ("PCM_F32LE" , "au" , "au" ),
339- ("PCM_U8" , "raw" , "raw" ),
340- ("PCM_S16BE" , "unknown_ext" , "wav" ), # Default for PCM
341- # Test unknown encoding falls back to file extension
342- ("UNKNOWN_CODEC" , "mp3" , "mp3" ),
343- ("UNKNOWN_CODEC" , "flac" , "flac" ),
344- # Test files without extension
345- ("UNKNOWN_CODEC" , "" , "unknown" ),
346- ("" , "" , "unknown" ),
323+ # Direct format mappings from soundfile
324+ ("WAV" , "PCM_16" , "wav" , "wav" , 16 * 16000 ),
325+ ("FLAC" , "PCM_16" , "flac" , "flac" , 16 * 16000 ),
326+ ("OGG" , "VORBIS" , "ogg" , "ogg" , - 1 ),
327+ ("AIFF" , "PCM_24" , "aiff" , "aiff" , 24 * 16000 ),
328+ # Format fallback to file extension when subtype is PCM
329+ (None , "PCM_16" , "wav" , "wav" , 16 * 16000 ),
330+ (None , "PCM_24" , "aiff" , "aiff" , 24 * 16000 ),
331+ (None , "PCM_S16LE" , "au" , "au" , 16 * 16000 ),
332+ (None , "PCM_F32LE" , "wav" , "wav" , 32 * 16000 ),
333+ # Unknown format with extension falls back to extension
334+ (None , "UNKNOWN_CODEC" , "mp3" , "mp3" , - 1 ),
335+ ("" , "UNKNOWN_CODEC" , "flac" , "flac" , - 1 ),
336+ # Files without extension should fall back to "unknown"
337+ (None , "PCM_16" , "" , "unknown" , 16 * 16000 ),
338+ ("" , "UNKNOWN_CODEC" , "" , "unknown" , - 1 ),
347339 ],
348340)
349341def test_audio_info_format_detection (
350- tmp_path , catalog , encoding , file_ext , expected_format
342+ tmp_path , catalog , format_str , subtype , file_ext , expected_format , expected_bit_rate
351343):
352- """Test audio format detection for different file extensions and encodings ."""
344+ """Test audio format detection for different file extensions and formats ."""
353345 # Create a test audio file with the specified extension
354346 filename = f"test_audio.{ file_ext } " if file_ext else "test_audio"
355347 audio_data = generate_test_wav (duration = 0.1 , sample_rate = 16000 )
@@ -359,18 +351,20 @@ def test_audio_info_format_detection(
359351 audio_file = AudioFile (path = str (audio_path ), source = "file://" )
360352 audio_file ._set_stream (catalog , caching_enabled = False )
361353
362- # Mock torchaudio.info to return controlled encoding
363- with patch ("datachain.lib.audio.torchaudio.info" ) as mock_info :
364- mock_info .return_value .sample_rate = 16000
365- mock_info .return_value .num_channels = 1
366- mock_info .return_value .num_frames = 1600 # 0.1 seconds
367- mock_info .return_value .encoding = encoding
368- mock_info .return_value .bits_per_sample = 16
354+ # Mock soundfile.info to return controlled format
355+ with patch ("datachain.lib.audio.sf.info" ) as mock_info :
356+ mock_info .return_value .samplerate = 16000
357+ mock_info .return_value .channels = 1
358+ mock_info .return_value .frames = 1600 # 0.1 seconds
359+ mock_info .return_value .duration = 0.1
360+ mock_info .return_value .format = format_str
361+ mock_info .return_value .subtype = subtype
369362
370363 result = audio_info (audio_file )
371364
372365 assert result .format == expected_format
373- assert result .codec == encoding
366+ assert result .codec == subtype
367+ assert result .bit_rate == expected_bit_rate
374368
375369
376370def test_audio_info_stereo (stereo_audio_file ):
0 commit comments