Exemple #1
0
    def __init__(self):
        self.__change_after_samples: int = MAX_32_INT
        self.__sample_counter: int = 0
        self.__i: Intensity = Intensity.SILENT

        self.__file_finder = FileFinder(
            "etc/drums", False, "", MainLoader.get(ConfigName.drum_type,
                                                   "pop"))
        tmp = self.__file_finder.get_path_now()
        DrumLoader.load(tmp)
Exemple #2
0
def load_all_dics() -> Dict[str, Dict[str, Dict]]:
    dic = dict()
    ff: FileFinder = FileFinder("etc/midi", True, ".json", "")
    for _ in range(ff.items_len):
        ff.iterate_dir(True)
        ff.now = ff.next
        file = ff.get_path_now()
        item = ff.get_item_now()[:-len(ff.get_end_with())]
        assert always_true(f"Loading midi config from {file}")
        loader = JsonDictLoader(file)
        default_dic = loader.get(ConfigName.default_config, dict())
        dic1 = dict()

        for key in [
                x for x in loader.get_keys()
                if x not in [ConfigName.default_config, ConfigName.comment]
        ]:
            value = loader.get(key, None)
            assert type(
                value) == dict, f"Must be dictionary key={key} in file {item}"
            assert len(
                value
            ) > 0, f"Dictionary must be non empty key={key} in file {item}"
            dic1[key] = dict(default_dic, **value)

        dic[item] = dic1

    return dic
Exemple #3
0
def findFiles(paths):
    """Takes an array of paths, returns all files found
    """
    valid_files = []

    for cfile in paths:
        cur = FileFinder(cfile, recursive = Config['recursive'])
        try:
            valid_files.extend(cur.findFiles())
        except InvalidPath:
            warn("Invalid path: %s" % cfile)

    if len(valid_files) == 0:
        raise NoValidFilesFoundError()

    # Remove duplicate files (all paths from FileFinder are absolute)
    valid_files = list(set(valid_files))

    return valid_files
Exemple #4
0
def findFiles(paths):
    """Takes an array of paths, returns all files found
    """
    valid_files = []

    for cfile in paths:
        cur = FileFinder(cfile,
                         with_extension=Config['valid_extensions'],
                         recursive=Config['recursive'])

        try:
            valid_files.extend(cur.findFiles())
        except InvalidPath:
            warn("Invalid path: %s" % cfile)

    if len(valid_files) == 0:
        raise NoValidFilesFoundError()

    # Remove duplicate files (all paths from FileFinder are absolute)
    valid_files = list(set(valid_files))

    return valid_files
Exemple #5
0
 def __init__(self):
     super().__init__()
     self._file_finder: FileFinder = FileFinder("save_song", True, ".sng", "")
     self._song_name = ""
     self.__set_song_name()
Exemple #6
0
class RealDrum:
    """Drums generated from patterns with random changes"""

    change_after_bars: int = 3  # change pattern and fill after this many bars

    def __init__(self):
        self.__change_after_samples: int = MAX_32_INT
        self.__sample_counter: int = 0
        self.__i: Intensity = Intensity.SILENT

        self.__file_finder = FileFinder(
            "etc/drums", False, "", MainLoader.get(ConfigName.drum_type,
                                                   "pop"))
        tmp = self.__file_finder.get_path_now()
        DrumLoader.load(tmp)

    @staticmethod
    def clear() -> None:
        DrumLoader.length = 0

    @property
    def is_empty(self) -> bool:
        return DrumLoader.length == 0

    @property
    def length(self) -> int:
        return DrumLoader.length

    @property
    def volume(self) -> float:
        return MainLoader.get(ConfigName.drum_volume,
                              1) * DrumLoader.max_volume / SD_MAX

    @property
    def swing(self) -> float:
        return MainLoader.get(ConfigName.drum_swing, 0.75)

    def show_drum_type(self) -> str:
        return f"Now: {self.__file_finder.get_item_now()}   Next: {self.__file_finder.get_item_next()}"

    def change_drum_type(self, go_fwd: bool) -> None:
        self.__file_finder.iterate_dir(go_fwd)

    def load_drum_type(self) -> None:
        if self.__file_finder.now == self.__file_finder.next:
            return
        self.__file_finder.now = self.__file_finder.next
        tmp = self.__file_finder.get_path_now()

        DrumLoader.load(tmp)
        MainLoader.set(ConfigName.drum_type, self.__file_finder.get_item_now())
        MainLoader.save()

        if not self.is_empty:
            self.prepare_drum(self.length)

    def prepare_drum(self, length: int) -> None:
        """ Non blocking drum init in another thread, length is one bar long and holds drum pattern """
        Timer(0.2, DrumLoader.prepare_all, [length]).start()
        self.__change_after_samples = RealDrum.change_after_bars * length
        self.__i = Intensity.LVL2

    def play_samples(self, out_data: np.ndarray, idx: int) -> None:
        if self.__i == Intensity.SILENT or self.is_empty:
            return

        self.__sample_counter += len(out_data)
        if self.__sample_counter > self.__change_after_samples:
            self.__random_samples()

        if self.__i & Intensity.LVL1:
            play_sound_buff(DrumLoader.get_l1(), out_data, idx)
        if self.__i & Intensity.LVL2:
            play_sound_buff(DrumLoader.get_l2(), out_data, idx)
        if self.__i & Intensity.BREAK:
            play_sound_buff(DrumLoader.get_bk(), out_data, idx)

    def play_break_later(self, part_len: int, idx: int) -> None:
        bars = 0.5
        samples = self.length * bars
        idx %= part_len
        start_at = (part_len - idx) - samples
        if start_at > 0:
            Timer(start_at / SD_RATE, self.play_break_now, [bars]).start()

    def __random_samples(self):
        self.__sample_counter = 0
        DrumLoader.random_samples()

    def play_break_now(self, bars: float = 0) -> None:
        if self.__i == Intensity.SILENT:
            self.__i = Intensity.LVL2

        def revert():
            self.__i &= ~Intensity.BREAK

        self.__random_samples()
        self.__i |= Intensity.BREAK
        if bars <= 0:
            bars = 0.5 if random.random() < 0.5 else 1
        samples = self.length * bars
        Timer(samples / SD_RATE, revert).start()

    @staticmethod
    def change_volume(change_by: int) -> None:
        factor = 1.41 if change_by >= 0 else (1 / 1.41)
        v = MainLoader.get(ConfigName.drum_volume, 1) * factor
        if v * DrumLoader.max_volume >= SD_MAX:
            return
        if v * DrumLoader.max_volume < 0.01 * SD_MAX:
            return
        MainLoader.set(ConfigName.drum_volume, v)
        MainLoader.save()
        DrumLoader.prepare_all(DrumLoader.length)

    @staticmethod
    def change_swing(change_by: int) -> None:
        v = MainLoader.get(ConfigName.drum_swing, 0.625)
        v += (0.25 / 4) if change_by >= 0 else (-0.25 / 4)
        if v > 0.80:
            v = 0.50
        elif v < 0.45:
            v = 0.75

        MainLoader.set(ConfigName.drum_swing, v)
        MainLoader.save()
        DrumLoader.prepare_all(DrumLoader.length)

    def change_intensity(self, change_by: int) -> None:
        i = self.__i + change_by
        i = min(3, i)
        i = max(0, i)
        self.__i = i

    def __str__(self):
        return f"RealDrum length: {self.length} empty: {self.is_empty} intensity: {self.__i}"