Beispiel #1
0
 def mix(self, verbose=True):
     """
     Mix all the patterns into a single result sample.
     """
     if not self.patterns:
         if verbose:
             print("No patterns to mix, output is empty.")
         return Sample()
     total_seconds = 0.0
     for p in self.patterns:
         bar = next(iter(p.values()))
         total_seconds += len(bar) * 60.0 / self.bpm / self.ticks
     if verbose:
         print("Mixing {:d} patterns...".format(len(self.patterns)))
     mixed = Sample().make_32bit()
     for index, timestamp, sample in self.mixed_samples(tracker=False):
         if verbose:
             print("\r{:3.0f} % ".format(timestamp / total_seconds * 100),
                   end="")
         mixed.mix_at(timestamp, sample)
     # chop/extend to get to the precise total duration (in case of silence in the last bars etc)
     missing = total_seconds - mixed.duration
     if missing > 0:
         mixed.add_silence(missing)
     elif missing < 0:
         mixed.clip(0, total_seconds)
     if verbose:
         print("\rMix done.")
     return mixed
Beispiel #2
0
 def mix_generator(self):
     """
     Returns a generator that produces samples that are the chronological
     chunks of the final output mix. This avoids having to mix it into one big
     output mix sample.
     """
     if not self.patterns:
         yield Sample()
         return
     total_seconds = 0.0
     for p in self.patterns:
         bar = next(iter(p.values()))
         total_seconds += len(bar) * 60.0 / self.bpm / self.ticks
     mixed_duration = 0.0
     samples = self.mixed_samples()
     # get the first sample
     index, previous_timestamp, sample = next(samples)
     mixed = Sample().make_32bit()
     mixed.mix_at(previous_timestamp, sample)
     # continue mixing the following samples
     for index, timestamp, sample in samples:
         trigger_duration = timestamp - previous_timestamp
         overflow = None
         if mixed.duration < trigger_duration:
             # fill with some silence to reach the next sample position
             mixed.add_silence(trigger_duration - mixed.duration)
         elif mixed.duration > trigger_duration:
             # chop off the sound that extends into the next sample position
             # keep this overflow and mix it later!
             overflow = mixed.split(trigger_duration)
         mixed_duration += mixed.duration
         yield mixed
         mixed = overflow if overflow else Sample().make_32bit()
         mixed.mix(sample)
         previous_timestamp = timestamp
     # output the last remaining sample and extend it to the end of the duration if needed
     timestamp = total_seconds
     trigger_duration = timestamp - previous_timestamp
     if mixed.duration < trigger_duration:
         mixed.add_silence(trigger_duration - mixed.duration)
     elif mixed.duration > trigger_duration:
         mixed.clip(0, trigger_duration)
     mixed_duration += mixed.duration
     yield mixed