Пример #1
0
    def analyze(cls, events: List[CorpusEvent],
                metadata: Metadata) -> List[CorpusEvent]:
        if not FeatureUtils.is_valid_audio(events, metadata):
            raise FeatureError(
                f"Feature '{cls.__name__}' does not support content of "
                f"type {metadata.content_type.__class__.__name__}")

        metadata: AudioMetadata = typing.cast(AudioMetadata, metadata)
        # TODO: Pass rather than hard-code
        yin_frames: np.ndarray = librosa.yin(metadata.foreground_data,
                                             fmin=50,
                                             fmax=4186,
                                             sr=metadata.sr,
                                             frame_length=2048,
                                             hop_length=metadata.hop_length)
        yin_midipitches: np.ndarray = np.round(
            12 * np.log2(yin_frames / 8.175798915643707))
        for event in events:
            onset_frame: int = librosa.time_to_frames(
                event.onset, sr=metadata.sr, hop_length=metadata.hop_length)
            end_frame: int = librosa.time_to_frames(
                event.onset + event.duration,
                sr=metadata.sr,
                hop_length=metadata.hop_length)
            hist, _ = np.histogram(yin_midipitches[onset_frame:end_frame],
                                   bins=128,
                                   range=(0, 128))
            pitch: int = int(np.argmax(hist))
            event.set_feature(cls(value=pitch))

        return events
Пример #2
0
 def analyze(cls, events: List[MidiCorpusEvent],
             metadata: MidiMetadata) -> List[MidiCorpusEvent]:
     if FeatureUtils.is_valid_midi(events, metadata):
         for event in events:
             event.set_feature(cls(value=len(event.notes)))
         return events
     raise FeatureError(
         f"Feature '{cls.__name__}' does not support content of "
         f"type {metadata.content_type.__class__.__name__}")
Пример #3
0
 def analyze(cls, events: List[MidiCorpusEvent],
             metadata: MidiMetadata) -> List[MidiCorpusEvent]:
     """ raises: FeatureError if invalid MIDI content """
     if FeatureUtils.is_valid_midi(events, metadata):
         for event in events:
             event.set_feature(cls(int(min([n.pitch
                                            for n in event.notes]))))
         return events
     raise FeatureError(
         f"Feature '{cls.__name__}' does not support content of "
         f"type {metadata.content_type.__class__.__name__}")
Пример #4
0
 def analyze(cls, events: List[CorpusEvent], metadata: Metadata) -> List[CorpusEvent]:
     if FeatureUtils.is_valid_midi(events, metadata):
         events: List[MidiCorpusEvent]
         metadata: MidiMetadata
         cls._analyze_midi(events, metadata)
     elif FeatureUtils.is_valid_audio(events, metadata):
         events: List[AudioCorpusEvent]
         metadata: AudioMetadata
         cls._analyze_audio(events, metadata)
     else:
         raise FeatureError(f"Feature '{cls.__name__}' does not support content of type {metadata.content_type}")
     return events
Пример #5
0
 def analyze(cls, events: List[MidiCorpusEvent],
             metadata: MidiMetadata) -> List[MidiCorpusEvent]:
     if FeatureUtils.is_valid_midi(events, metadata):
         for event in events:
             band_distribution: np.ndarray = np.zeros(OctaveBands.NUM_BANDS,
                                                      dtype=float)
             octaves: List[int] = [
                 int(note.pitch // 12) for note in event.notes
             ]
             for octave in octaves:
                 band_distribution[octave] += 1.0
             max_val: float = np.max(band_distribution)
             if max_val > 0:
                 band_distribution /= max_val
             event.set_feature(cls(value=band_distribution))
         return events
     raise FeatureError(
         f"Feature '{cls.__name__}' does not support content of "
         f"type {metadata.content_type.__class__.__name__}")
Пример #6
0
 def get_feature(self, feature_type: Type[FeatureValue]) -> FeatureValue:
     """Raises KeyError"""
     try:
         return self.features[feature_type]
     except ValueError as e:
         raise FeatureError(f"Corpus does not have feature of type '{feature_type}'") from e