コード例 #1
0
    def add_wave(self, path):
        """Reads a wave file at `path` and imports its structure into a pattern
        dictionary."""
        # **********************************************************************
        # STEP 1: Open waveform from argv and get mono audio samples
        wav = waveform.from_file(path)
        wav.setchannelcount(1)
        samples = np.fromstring(wav.getsamples(), dtype='Int16').tolist()

        # **********************************************************************
        # STEP 2: Run STFT on samples
        matrix = stft.STFT_Matrix(samples, c_size=2**10)
        matrix.amplitudes = stft.triangular_smoothing(matrix.amplitudes, 3)
        matrix.smooth_amps_2()
        matrix.blip_filter_2()
        #matrix.spectrogram()

        # **********************************************************************
        # STEP 3: Convert the STFT to PatternDictionary
        self.pattern_dictionary.import_stft(matrix)
コード例 #2
0
waveform-test.py - tests the waveform class
Copyright EJM Software 2016

Usage: python waveform-test.py PATH
"""
# ******************************************************************************
# Add the parent directory to Python's list of paths to search for modules
import sys
sys.path.append("../")
# ******************************************************************************
import waveform

if __name__=="__main__":
    if len(sys.argv) > 1:
        # LOAD A WAVEFORM FROM FILE
        wav = waveform.from_file(sys.argv[1])
        originalsamplewidth = wav.getsamplewidth()
        originalchannelcount = wav.getchannelcount()
        originalsize = len(wav.getsamples())

        # TEST ONE: LOADING AND WRITING
        # write the data to a file
        waveform.to_file('readertest.wav', wav)
        # check that the files are identical, ie. the data was read and processed properly
        import filecmp
        assert filecmp.cmp(sys.argv[1], 'readertest.wav')
        # delete the created test file
        from os import remove
        remove('readertest.wav')

        # TEST TWO: CHANGING THE CHANNEL COUNT
コード例 #3
0
    def add_template(self, filename):
        """Adds a song to the music generator's knowledge base"""
        # STEP 1: Read the waveform music file at the given path
        wave = waveform.from_file(filename)
        print "Setting channel count"
        wave.setchannelcount(1)
        print "Making samples"
        samples = stft.np.fromstring(wave.getsamples(), dtype='Int16').tolist()
        print "Done"

        # STEP 2: Parse the waveform music into a music note format using STFT
        matrix = stft.STFT_Matrix(samples, c_size=2**10)
        matrix.amplitudes = stft.triangular_smoothing(matrix.amplitudes, 5)
        matrix.smooth_amps_2()
        matrix.filter(31000)
        matrix.spectrogram()

        # STEP 3: Create an array with all the patterns found in the music
        # Notes about the self.patterns dictionary:
        #     "Next" - an array
        # Parse the data into songsmith format
        # Then, place each note into the patterns dictionary
        song = matrix.to_song()
        #print len(song.chords)
        song.debug()
        # Note: In "next" array, the 0 index is the newest
        self.patterns.append({"name":"", "frequency":"", "durations":[0], "next":[[] for i in range(self.search_depth)], "chords":[]})
        lastindices = [[0] for i in range(self.search_depth)]

        for chord in song.chords:
            currentindices = []
            # Skip notes shorter than 25 bps, its probably trash data
            if chord.notes[0].duration < 0.04:
                continue
            # Add the notes from the chord
            for note in chord.notes:
                name = songsmith.freqtoname(note.frequency)[:-1]
                currentindex = next((i for i,v in enumerate(self.patterns) if v["name"]==name), None)
                if currentindex==None:
                    currentindex = len(self.patterns)
                    self.patterns.append({"name":name, "frequency":note.frequency, "durations":[], "next":[[] for i in range(self.search_depth)], "chords":[]})
                self.patterns[currentindex]["durations"].append(note.duration)
                for other in currentindices:
                    if other != note:
                        self.patterns[currentindex]["chords"].append(other)
                # Pack the next note data into the patterns dictionary
                for depth, indices in enumerate(lastindices):
                    for index in indices:
                        self.patterns[index]["next"][depth].append(currentindex)
                currentindices.append(currentindex)
            # Update the lastindices for the next loop
            lastindices.pop()
            lastindices.insert(0, currentindices)
            # last2indices = last1indices
            # last1indices = currentindices
        # Add the blank notes to the end of the song
        # for last1index in last1indices:
        #     self.patterns[last1index]["nexts"].append(0)
        # for last2index in last2indices:
        #     self.patterns[last2index]["next2"].append(0)
        # Add as many empty notes to the end of the patterns as the search_depth
        for depth, indices in enumerate(lastindices):
            for index in indices:
                for i in range(depth, self.search_depth):
                    self.patterns[index]["next"][i].append(0)