def info_audiofile_sloppy(fp): info = {} info['duration'] = af.duration(fp, sloppy=True) info['samples'] = af.samples(fp) info['channels'] = af.channels info['sampling_rate'] = af.sampling_rate return info
def test_mp3(tmpdir, magnitude, sampling_rate, channels): # Currently we are not able to setup the Windows runner with MP3 support # https://github.com/audeering/audiofile/issues/51 if sys.platform == 'win32': return signal = sine(magnitude=magnitude, sampling_rate=sampling_rate, channels=channels) # Create wav file and use sox to convert to mp3 wav_file = str(tmpdir.join('signal.wav')) mp3_file = str(tmpdir.join('signal.mp3')) af.write(wav_file, signal, sampling_rate) subprocess.call(['sox', wav_file, mp3_file]) assert audeer.file_extension(mp3_file) == 'mp3' sig, fs = af.read(mp3_file) assert_allclose(_magnitude(sig), magnitude, rtol=0, atol=tolerance(16)) assert fs == sampling_rate assert _channels(sig) == channels if channels == 1: assert sig.ndim == 1 else: assert sig.ndim == 2 assert af.channels(mp3_file) == _channels(sig) assert af.sampling_rate(mp3_file) == sampling_rate assert af.samples(mp3_file) == _samples(sig) assert af.duration(mp3_file) == _duration(sig, sampling_rate) assert af.duration(mp3_file, sloppy=True) == sox.file_info.duration(mp3_file) assert af.bit_depth(mp3_file) is None # Test additional arguments to read with sox offset = 0.1 duration = 0.5 sig, fs = af.read(mp3_file, offset=offset, duration=duration) assert _duration(sig, sampling_rate) == duration sig, fs = af.read(mp3_file, offset=offset) # Don't test for 48000 Hz and 2 channels # https://github.com/audeering/audiofile/issues/23 if not (sampling_rate == 48000 and channels == 2): assert_allclose( _duration(sig, sampling_rate), af.duration(mp3_file) - offset, rtol=0, atol=tolerance('duration', sampling_rate), )
def add_duration(arguments, path, metadata): local_path = LocalFileCache(arguments, path).get_path() audio_duration = audiofile.duration(local_path) metadata["duration_seconds"] = audio_duration metadata["size_in_bytes"] = os.path.getsize(local_path) os.remove(local_path) return metadata
def deduce_properties(self): # Audio file duration self.duration = af.duration(self.file.path) # Audio file sampling rate rate = af.sampling_rate(self.file.path) self._deduce_tempo(rate) self.save()
def align_item(config, item): label, audio = item[0], item[1] duration_seconds = audiofile.duration(audio) if duration_seconds < float( config["forced_alignment"]["max_duration_seconds"]): return (label, audio) + item[2:] assert False, "Not implemented."
def _add_media( self, root: str, file: str, version: str, archive: str = None, checksum: str = None, ): r"""Add or update media file. If you want to update only the version of an unaltered media file, don't specify ``archive`` and ``checksum``. Args: root: root directory file: relative file path archive: archive name without extension checksum: checksum of file version: version string """ format = audeer.file_extension(file).lower() if archive is None: archive = self.archive(file) if checksum is None: checksum = self.checksum(file) bit_depth = self.bit_depth(file) channels = self.channels(file) duration = self.duration(file) sampling_rate = self.sampling_rate(file) else: bit_depth = channels = sampling_rate = 0 duration = 0.0 if format in define.FORMATS: path = os.path.join(root, file) bit_depth = audiofile.bit_depth(path) channels = audiofile.channels(path) duration = audiofile.duration(path) sampling_rate = audiofile.sampling_rate(path) self._df.loc[file] = [ archive, bit_depth, channels, checksum, duration, format, 0, # removed sampling_rate, define.DependType.MEDIA, version, ]
def deduce_properties(self): ''' Deduces the sample duration and tempo. ''' # Duration self.duration = af.duration(self.file.path) # Sampling rate self.tempo = get_file_bpm(self.file.path) self.save()
def test_formats(): files = [ 'gs-16b-1c-44100hz.opus', 'gs-16b-1c-8000hz.amr', 'gs-16b-1c-44100hz.m4a', 'gs-16b-1c-44100hz.aac', ] header_durations = [ # as given by mediainfo 15.839, 15.840000, 15.833, None, ] files = [os.path.join(ASSETS_DIR, f) for f in files] for file, header_duration in zip(files, header_durations): signal, sampling_rate = af.read(file) assert af.channels(file) == _channels(signal) assert af.sampling_rate(file) == sampling_rate assert af.samples(file) == _samples(signal) duration = _duration(signal, sampling_rate) assert af.duration(file) == duration if header_duration is None: # Here we expect samplewise precision assert af.duration(file, sloppy=True) == duration else: # Here we expect limited precision # as the results differ between soxi and mediainfo precision = 1 sloppy_duration = round(af.duration(file, sloppy=True), precision) header_duration = round(header_duration, precision) assert sloppy_duration == header_duration assert af.bit_depth(file) is None if file.endswith('m4a'): # Test additional arguments to read with ffmpeg offset = 0.1 duration = 0.5 sig, fs = af.read(file, offset=offset, duration=duration) assert _duration(sig, sampling_rate) == duration sig, fs = af.read(file, offset=offset) assert _duration(sig, sampling_rate) == af.duration(file) - offset
def test_broken_file(non_audio_file): # Only match the beginning of error message # as the default soundfile message differs at the end on macOS error_msg = 'Error opening' # Reading file with pytest.raises(RuntimeError, match=error_msg): af.read(non_audio_file) # Metadata if audeer.file_extension(non_audio_file) == 'wav': with pytest.raises(RuntimeError, match=error_msg): af.bit_depth(non_audio_file) else: assert af.bit_depth(non_audio_file) is None with pytest.raises(RuntimeError, match=error_msg): af.channels(non_audio_file) with pytest.raises(RuntimeError, match=error_msg): af.duration(non_audio_file) with pytest.raises(RuntimeError, match=error_msg): af.samples(non_audio_file) with pytest.raises(RuntimeError, match=error_msg): af.sampling_rate(non_audio_file)
def __call__(self, value): # in order for duration to be calculated, file must be # temporarily written to disk with tempfile.NamedTemporaryFile() as tmp_file: for chunk in value.chunks(): tmp_file.write(chunk) duration = af.duration(tmp_file.name) if duration > self.max_duration: raise ValidationError( 'Please upload a sample <= {0:.1f}s'.format( self.max_duration))
def deduce_properties(self): ''' Deduces the sample duration and tempo. ''' # Duration self.duration = af.duration(self.file.path) # Sampling rate rate = af.sampling_rate(self.file.path) self._deduce_tempo(rate) self.save()
def test_empty_file(empty_file): # Reading file signal, sampling_rate = af.read(empty_file) assert len(signal) == 0 # Metadata for sloppy in [True, False]: assert af.duration(empty_file, sloppy=sloppy) == 0.0 assert af.channels(empty_file) == 1 assert af.sampling_rate(empty_file) == sampling_rate assert af.samples(empty_file) == 0 if audeer.file_extension(empty_file) == 'wav': assert af.bit_depth(empty_file) == 16 else: assert af.bit_depth(empty_file) is None
def get_duration(file_path): time = audiofile.duration(file_path) return time
def test_wav(tmpdir, bit_depth, duration, sampling_rate, channels, always_2d): file = str(tmpdir.join('signal.wav')) signal = sine(duration=duration, sampling_rate=sampling_rate, channels=channels) sig, fs = write_and_read( file, signal, sampling_rate, bit_depth=bit_depth, always_2d=always_2d, ) # Expected number of samples samples = int(np.ceil(duration * sampling_rate)) # Compare with sox implementation to check write() assert_allclose(sox.file_info.duration(file), duration, rtol=0, atol=tolerance('duration', sampling_rate)) assert sox.file_info.sample_rate(file) == sampling_rate assert sox.file_info.channels(file) == channels assert sox.file_info.num_samples(file) == samples assert sox.file_info.bitdepth(file) == bit_depth # Compare with signal values to check read() assert_allclose(_duration(sig, fs), duration, rtol=0, atol=tolerance('duration', sampling_rate)) assert fs == sampling_rate assert _channels(sig) == channels assert _samples(sig) == samples # Test audiofile metadata methods assert_allclose(af.duration(file), duration, rtol=0, atol=tolerance('duration', sampling_rate)) assert af.sampling_rate(file) == sampling_rate assert af.channels(file) == channels assert af.samples(file) == samples assert af.bit_depth(file) == bit_depth # Test types of audiofile metadata methods assert type(af.duration(file)) is float assert type(af.sampling_rate(file)) is int assert type(af.channels(file)) is int assert type(af.samples(file)) is int # Test dimensions of array if channels == 1 and not always_2d: assert sig.ndim == 1 else: assert sig.ndim == 2 # Test additional arguments to read if sampling_rate > 100: offset = 0.001 duration = duration - 2 * offset sig, fs = af.read( file, offset=offset, duration=duration, always_2d=always_2d, ) assert _samples(sig) == int(np.ceil(duration * sampling_rate))
def test_publish(version): db = audformat.Database.load(DB_ROOT_VERSION[version]) print(db.is_portable) print(db.files) if not audb.versions(DB_NAME): with pytest.raises(RuntimeError): audb.latest_version(DB_NAME) archives = db['files']['speaker'].get().dropna().to_dict() deps = audb.publish( DB_ROOT_VERSION[version], version, pytest.PUBLISH_REPOSITORY, archives=archives, previous_version=None, num_workers=pytest.NUM_WORKERS, verbose=False, ) backend = audb.core.utils.lookup_backend(DB_NAME, version) number_of_files = len(set(archives.keys())) number_of_archives = len(set(archives.values())) assert len(deps.files) - len(deps.archives) == (number_of_files - number_of_archives) for archive in set(archives.values()): assert archive in deps.archives db = audb.load( DB_NAME, version=version, full_path=False, num_workers=pytest.NUM_WORKERS, ) assert db.name == DB_NAME versions = audb.versions(DB_NAME) latest_version = audb.latest_version(DB_NAME) assert version in versions assert latest_version == versions[-1] df = audb.available(only_latest=False) assert DB_NAME in df.index assert set(df[df.index == DB_NAME]['version']) == set(versions) df = audb.available(only_latest=True) assert DB_NAME in df.index assert df[df.index == DB_NAME]['version'][0] == latest_version for file in db.files: name = archives[file] if file in archives else file file_path = backend.join(db.name, 'media', name) backend.exists(file_path, version) path = os.path.join(DB_ROOT_VERSION[version], file) assert deps.checksum(file) == audbackend.md5(path) if deps.format(file) in [ audb.core.define.Format.WAV, audb.core.define.Format.FLAC, ]: assert deps.bit_depth(file) == audiofile.bit_depth(path) assert deps.channels(file) == audiofile.channels(path) assert deps.duration(file) == audiofile.duration(path) assert deps.sampling_rate(file) == audiofile.sampling_rate(path)
'a07': 'In sieben Stunden wird es soweit sein.', 'b01': 'Was sind denn das für Tüten, die da unter dem Tisch ' 'stehen.', 'b02': 'Sie haben es gerade hochgetragen und jetzt gehen sie ' 'wieder runter.', 'b03': 'An den Wochenenden bin ich jetzt immer nach Hause ' 'gefahren und habe Agnes besucht.', 'b09': 'Ich will das eben wegbringen und dann mit Karl was ' 'trinken gehen.', 'b10': 'Die wird auf dem Platz sein, wo wir sie immer hinlegen.', } transcriptions = list(parse_names(names, from_i=2, to_i=5)) durations = audeer.run_tasks( task_func=lambda x: pd.to_timedelta( af.duration(os.path.join(src_dir, x)), unit='s', ), params=[([f], {}) for f in files], num_workers=12, ) # Convert to audformat db = audformat.Database( name='emodb', author=( 'Felix Burkhardt, ' 'Astrid Paeschke, ' 'Miriam Rolfes, ' 'Walter Sendlmeier, ' 'Benjamin Weiss'
def test_process_file(tmpdir, start, end, segment): start_org = start end_org = end feature = audinterface.Feature( feature_names=('o1', 'o2', 'o3'), process_func=feature_extractor, sampling_rate=None, channels=range(NUM_CHANNELS), resample=False, segment=segment, verbose=False, ) y_expected = np.ones((1, NUM_CHANNELS * NUM_FEATURES)) # create test file root = str(tmpdir.mkdir('wav')) file = 'file.wav' path = os.path.join(root, file) af.write(path, SIGNAL_2D, SAMPLING_RATE) # test absolute path start = start_org end = end_org y = feature.process_file(path, start=start, end=end) if start is None or pd.isna(start): start = pd.to_timedelta(0) if end is None or pd.isna(end): end = pd.to_timedelta(af.duration(path), unit='s') if segment is not None: index = segment.process_file(path) start = index[0][1] end = index[0][2] assert y.index.levels[0][0] == path assert y.index.levels[1][0] == start assert y.index.levels[2][0] == end np.testing.assert_array_equal(y, y_expected) # test relative path start = start_org end = end_org y = feature.process_file(file, start=start, end=end, root=root) if start is None or pd.isna(start): start = pd.to_timedelta(0) if end is None or pd.isna(end): end = pd.to_timedelta(af.duration(path), unit='s') if segment is not None: index = segment.process_file(file, root=root) start = index[0][1] end = index[0][2] assert y.index.levels[0][0] == file assert y.index.levels[1][0] == start assert y.index.levels[2][0] == end np.testing.assert_array_equal(y, y_expected)
import numpy as np import audiofile as af sampling_rate = 8000 noise = np.random.normal(0, 1, sampling_rate) noise /= np.amax(np.abs(noise)) af.write('MY.wav', noise, sampling_rate) af.channels('MY.wav') af.duration('MY.wav') sig, fs = af.read('MY.wav') print(fs) print(sig)