def select_features(cls, features_id, file_struct, annot_beats, framesync): """Selects the features from the given parameters. Parameters ---------- features_id: str The identifier of the features (it must be a key inside the `features_registry`) file_struct: msaf.io.FileStruct The file struct containing the files to extract the features from annot_beats: boolean Whether to use annotated (`True`) or estimated (`False`) beats framesync: boolean Whether to use framesync (`True`) or beatsync (`False`) features Returns ------- features: obj The actual features object that inherits from `msaf.Features` """ if not annot_beats and framesync: feat_type = FeatureTypes.framesync elif annot_beats and not framesync: feat_type = FeatureTypes.ann_beatsync elif not annot_beats and not framesync: feat_type = FeatureTypes.est_beatsync else: raise FeatureTypeNotFound("Type of features not valid.") # Select features with default parameters if features_id not in features_registry.keys(): raise FeaturesNotFound( "The features '%s' are invalid (valid features are %s)" % (features_id, features_registry.keys())) return features_registry[features_id](file_struct, feat_type)
def read_features(self, tol=1e-3): """Reads the features from a file and stores them in the current object. Parameters ---------- tol: float Tolerance level to detect duration of audio. """ try: # Read JSON file with open(self.file_struct.features_file) as f: feats = json.load(f) # Store duration if self.dur is None: self.dur = float(feats["globals"]["dur"]) # Check that we have the correct global parameters assert (np.isclose(self.dur, float(feats["globals"]["dur"]), rtol=tol)) assert (self.sr == int(feats["globals"]["sample_rate"])) assert (self.hop_length == int(feats["globals"]["hop_length"])) assert (os.path.basename( self.file_struct.audio_file) == os.path.basename( feats["globals"]["audio_file"])) # Check for specific features params feat_params_err = FeatureParamsError( "Couldn't find features for %s id in file %s" % (self.get_id(), self.file_struct.features_file)) if self.get_id() not in feats.keys(): raise feat_params_err for param_name in self.get_param_names(): value = getattr(self, param_name) if hasattr(value, '__call__'): # Special case of functions if value.__name__ != \ feats[self.get_id()]["params"][param_name]: raise feat_params_err else: if str(value) != \ feats[self.get_id()]["params"][param_name]: raise feat_params_err # Store actual features self._est_beats_times = np.array(feats["est_beats"]) self._est_beatsync_times = np.array(feats["est_beatsync_times"]) self._est_beats_frames = librosa.core.time_to_frames( self._est_beats_times, sr=self.sr, hop_length=self.hop_length) self._framesync_features = \ np.array(feats[self.get_id()]["framesync"]) self._est_beatsync_features = \ np.array(feats[self.get_id()]["est_beatsync"]) # Read annotated beats if available if "ann_beats" in feats.keys(): self._ann_beats_times = np.array(feats["ann_beats"]) self._ann_beatsync_times = np.array( feats["ann_beatsync_times"]) self._ann_beats_frames = librosa.core.time_to_frames( self._ann_beats_times, sr=self.sr, hop_length=self.hop_length) self._ann_beatsync_features = \ np.array(feats[self.get_id()]["ann_beatsync"]) except KeyError: raise WrongFeaturesFormatError( "The features file %s is not correctly formatted" % self.file_struct.features_file) except AssertionError: raise FeaturesNotFound( "The features for the given parameters were not found in " "features file %s" % self.file_struct.features_file) except IOError: raise NoFeaturesFileError("Could not find features file %s", self.file_struct.features_file)