Beispiel #1
0
    def multitrack(self):
        # How many times do you want this to run?
        iterations = int(self._config["tracks"])
        voices = self._config["voices"]
        nvoices = len(voices)

        if nvoices < 2:
            raise robox.GIParameterErr(
                "Insufficient voices specified for the multitrack algorithm")

        mute = 1.5 * nextPowerOf2(nvoices)

        for ctr in range(iterations):
            audios = []
            # Randomly select our samples
            for voice in voices:
                sample = self._inventory.selectRandom(voice)
                audio = AudioSegment.from_wav(sample)
                audio = audio.normalize()
                audio = audio - mute
                audios.append(audio)

            summation = audios[0]
            for nctr in range(nvoices - 1):
                summation = summation.overlay(audios[nctr + 1], loop=True)
            summation = summation.normalize()

            fname = inspect.currentframe().f_code.co_name
            self.write(algorithm=fname, counter=ctr, source=summation)
Beispiel #2
0
    def path(self, value):
        """Sets value of full path.
 
        Also derives various component features from the path
        """
        if value is None:
            raise robox.GIParameterErr("No path given on Source class path setting accessor.")
        self._path = value
        self._fname = os.path.basename(self._path)
        self._dname = os.path.basename(os.path.dirname(self._path))
        self._root, self._ext = os.path.splitext(self._fname)
Beispiel #3
0
    def voices(self):
        """ This developmental prototype algorithm uses the same algorithm as voices3, 
        but allows the user to designate the 3 or more voices to be used in the compose file.

        Warning:
            This is example code used during early development, and should really only be used for reference and study.

        """
        # These could be parameterised in the config
        declick = 10
        vol_range = (14, 22)

        # How many times do you want this to run?
        iterations = int(self._config["tracks"])
        # Track repeats
        repeats = int(self._config["repeats"])

        voices = self._config["voices"]
        nvoices = len(voices)
        if nvoices < 3:
            raise robox.GIParameterErr(
                "Insufficient voices specified for the 'voices' algorithm")

        for ctr in range(iterations):
            audios = []
            # Randomly select our samples
            for voice in voices:
                sample = self._inventory.selectRandom(voice)
                audio = self.getsegment(sample, vol_range, declick)
                audios.append(audio)

            summation = audios[0]
            for nctr in range(nvoices - 2):
                summation = summation.overlay(audios[nctr + 1])

            composite = summation + summation + summation + summation

            final_overlay = composite.overlay(audios[nvoices - 1])

            for ctr2 in range(repeats):
                final_overlay = final_overlay + final_overlay

            fname = inspect.currentframe().f_code.co_name
            self.write(algorithm=fname, counter=ctr, source=final_overlay)
Beispiel #4
0
    def voices_shifted(self):
        """ This algorithm uses the same algorithm as voices, 
        but implements a sequential shift as each new voice is incorporated.

        Warning:
            This is example code used during early development, and should really only be used for reference and study.
        """
        # These could be parameterised in the config
        declick = 10
        vol_range = (14, 22)

        # How many times do you want this to run?
        iterations = int(self._config["tracks"])
        # Track repeats
        repeats = int(self._config["repeats"])

        voices = self._config["voices"]
        nvoices = len(voices)
        if nvoices < 3:
            raise robox.GIParameterErr(
                "Insufficient voices specified for the 'voices' algorithm")

        for ctr in range(iterations):
            audios = []
            # Randomly select our samples
            for voice in voices:
                sample = self._inventory.selectRandom(voice)
                audio = self.getsegment(sample, vol_range, declick)
                audios.append(audio)

            summation = audios[0]
            for nctr in range(nvoices - 1):
                summation = summation.overlay(audios[nctr + 1])
                summation = summation + summation

            for ctr2 in range(repeats):
                summation = summation + summation

            fname = inspect.currentframe().f_code.co_name
            self.write(algorithm=fname, counter=ctr, source=summation)
Beispiel #5
0
    def voices_shifted(self):
        """ This algorithm uses the same algorith as voices3, 
        but allows the user to designate the 3 or more voices to be used in the compose file."""
        # These could be parameterised in the config
        declick = 10
        vol_range = (14, 22)

        # How many times do you want this to run?
        iterations = int(self._config["tracks"])
        # Track repeats
        repeats = int(self._config["repeats"])

        voices = self._config["voices"]
        nvoices = len(voices)
        if nvoices < 3:
            raise robox.GIParameterErr(
                "Insufficient voices specified for the 'voices' algorithm")

        for ctr in range(iterations):
            audios = []
            # Randomly select our samples
            for voice in voices:
                sample = self._inventory.selectRandom(voice)
                audio = self.getsegment(sample, vol_range, declick)
                audios.append(audio)

            summation = audios[0]
            for nctr in range(nvoices - 1):
                summation = summation.overlay(audios[nctr + 1])
                summation = summation + summation

            for ctr2 in range(repeats):
                summation = summation + summation

            fname = inspect.currentframe().f_code.co_name
            self.write(algorithm=fname, counter=ctr, source=summation)
Beispiel #6
0
    def groove(self):
        """The `Basic.groove` algorithm is used to form a rhythmic backbone to a composition. This algorithm attempts to make sensible alignment
        choices for the samples in use. It is considered a *production* algorithm.

        .. image:: images/Basic.groove.jpg

        The number of voices can be 3 or more. In this example we are using 4, which we can think of as **A**, **B**, **C** and **D** corresponding
        to their declaration position in the configuration list.

        Segments **A** and **B** are randomly selected from their inventory categories. These are then length-aligned. That is, whichever is the
        shorter of the two is padded with exactly the right amount of silence to make the frame lengths of both segments equal. These are then overlayed
        to form a composite rhythmic unit referred to as **AB**.

        The basic rhythmic beat is created by replicating a sequence of these **AB** segments end-to-end until the track size limit is surpassed.
        This is the `groove_base`.

        The `cycle` parameter specifies the number of these **AB** components tahe represent a higher level repetition unit called the `cycle` (obviously).

        Subsequent voices are also length-aligned (or curtailed) to match the size of the **AB** unit. A new segment, `groove_layer` is created,
        into which the later voices **C**, **D**, etc. are injected in a cyclic sequence, aligned precisely to the `groove_base` cycles and beats.

        Finally, the `groove_base` is overlayed with the `groove_layer` to create a composite whole track which is output as an audio file.

        Parameters:
            tracks (int) : number of times the process is to run.
            voices (list) : list of voice categories to select and use in the track
            cycle (int) : length of a repeat cycle in terms of groove_base *beats*

        Example:

        .. code:: json

           {
               "Basic" : {
                   "groove" : {
                       "tracks" : 50,
                       "cycle" : 4,
                       "voices" : [
                           "Bass",
                           "Beat",
                           "Percussion",
                           "Pad"
                       ]
                    }
                }
            }

        Raises:
            GenerIter.excepts.GIParameterErr
        """
        declick = 10
        # How many times do you want this to run?
        iterations = int(self._config["tracks"])
        voices = self._config["voices"]
        nvoices = len(voices)
        cycle = self._config["cycle"]

        if nvoices < 3:
            raise robox.GIParameterErr(
                "Insufficient voices specified for the groove algorithm")

        # Need to keep all overlays below the clipping threshold
        mute = 6.0 * nextPowerOf2(nvoices)

        for ctr in range(iterations):
            audios = []
            maxlen = 0
            # Set a soft threshold for the size of the piece
            size_limit = self.threshold()
            # Randomly select our samples
            for voice in voices:
                sample = self._inventory.selectRandom(voice)
                audio = self.getsegmentm(sample, mute, declick)
                audios.append(audio)

            for aud in range(2):
                if len(audios[aud]) > maxlen:
                    maxlen = len(audios[aud])

            for aud in range(2, nvoices):
                audios[aud] = self.padtolength(audios[aud], maxlen, declick)

            # Create the groove's rhythmic base layer
            rhythm = audios[0].overlay(audios[1])
            rlen = len(rhythm)
            groove_base = rhythm
            print("{0}  < {1}".format(str(groove_base.duration_seconds),
                                      str(size_limit)))
            while groove_base.duration_seconds < size_limit:
                #groove_base = groove_base + rhythm
                groove_base = groove_base + rhythm

            # Create a blank segment of same size and frame rate
            groove_layer = AudioSegment.silent(
                duration=len(groove_base), frame_rate=groove_base.frame_rate)

            for ctr2 in range(2, nvoices):
                compound = AudioSegment.silent(
                    duration=cycle * len(rhythm),
                    frame_rate=groove_layer.frame_rate)
                offset = ((ctr2 - 2) % cycle) * rlen
                compound = compound.overlay(audios[ctr2], position=offset)
                groove_layer = groove_layer.overlay(compound, loop=True)

            summation = groove_base.overlay(groove_layer)

            fname = inspect.currentframe().f_code.co_name
            self.write(algorithm=fname, counter=ctr, source=summation)