Esempio n. 1
0
def main(input_filename, output_filename, tatums, beats, bars):

    audiofile = audio.LocalAudioFile(input_filename)
    num_channels = audiofile.numChannels
    sample_rate = audiofile.sampleRate
    
    # mono files have a shape of (len,) 
    out_shape = list(audiofile.data.shape)
    out_shape[0] = len(audiofile)
    out = audio.AudioData(shape=out_shape, sampleRate=sample_rate,numChannels=num_channels)

    # same hack to change shape: we want blip_files[0] as a short, silent blip
    null_shape = list(audiofile.data.shape)
    null_shape[0] = 2
    null_audio = audio.AudioData(shape=null_shape)
    null_audio.endindex = len(null_audio)
    
    low_blip = audio.AudioData(blip_filenames[0])
    med_blip = audio.AudioData(blip_filenames[1])
    high_blip = audio.AudioData(blip_filenames[2])
    
    all_tatums = audiofile.analysis.tatums
    all_beats = audiofile.analysis.beats
    all_bars = audiofile.analysis.bars
            
    if not all_tatums:
        print "Didn't find any tatums in this analysis!"
        print "No output."
        sys.exit(-1)
    
    print "going to add blips..."
    
    for tatum in all_tatums:
        mix_list = [audiofile[tatum], null_audio, null_audio, null_audio]
        if tatums:
            print "match! tatum start time:" + str(tatum.start)
            mix_list[1] = low_blip

        if beats:
            for beat in all_beats:
                if beat.start == tatum.start:
                    print "match! beat start time: " + str(beat.start)
                    mix_list[2] = med_blip
                    break

        if bars:
            for bar in all_bars:
                if bar.start == tatum.start:
                    print "match! bar start time: " + str(bar.start)
                    mix_list[3] = high_blip
                    break
        out_data = audio.megamix(mix_list)
        out.append(out_data)
        del(out_data)
    print "blips added, going to encode", output_filename, "..."
    out.encode(output_filename)
    print "Finito, Benito!"
Esempio n. 2
0
def mashComponents(localAudioFiles, loudnessMarkers):
    instSegments = localAudioFiles[0].analysis.segments# This is the base track
    vocalSegments = localAudioFiles[1].analysis.segments# This is the overlay track
    instBeats = localAudioFiles[0].analysis.beats[loudnessMarkers[0][0]:
                                                  loudnessMarkers[0][1]]
    vocalBeats = localAudioFiles[1].analysis.beats[loudnessMarkers[1][0]:
                                                   loudnessMarkers[1][1]]
    pitches = meanPitches(instSegments,instBeats)
    timbre = meanTimbre(instSegments,instBeats)
    sections = localAudioFiles[1].analysis.sections #This is the new lead vocal layer
    sections = sections.that(selection.are_contained_by_range(
            vocalBeats[0].start, vocalBeats[-1].start+vocalBeats[-1].duration))
    if(len(sections)==0):sections = localAudioFiles[1].analysis.sections[2:-2]
    pyplot.figure(0,(16,9))
    image = numpy.array(pitches)
    image = numpy.concatenate((image,numpy.array(timbre)),axis = 1)
    image = numpy.concatenate((image,numpy.array(meanLoudness(instSegments,instBeats))),
                              axis = 1)
    """ Now image contains chromatic, timbral, and loudness information"""
    sectBeats = getSectBeats(sections[0]) # get beats that comprise a specific section
    template = numpy.array(meanPitches(vocalSegments,sectBeats))
    template = numpy.concatenate((template,numpy.array(
                                meanTimbre(vocalSegments,sectBeats))),axis=1)
    template = numpy.concatenate((template,numpy.array(
                                meanLoudness(vocalSegments,sectBeats))),axis = 1)
    im = feature.match_template(image,template,pad_input=True)
    maxValues = [] #tuples of x coord, y coord, correlation, and section len(in secs)
    ij = numpy.unravel_index(numpy.argmax(im), im.shape)
    x, y = ij[::-1]
    maxValues.append((numpy.argmax(im),x,y,sections[0].duration))
    for i in range(len(sections)-1):
        sectBeats = getSectBeats(sections[i+1])
        template = numpy.array(meanPitches(vocalSegments,sectBeats))
        template = numpy.concatenate((template,numpy.array(
                                meanTimbre(vocalSegments,sectBeats))), axis=1)
        template = numpy.concatenate((template,numpy.array(
                                meanLoudness(vocalSegments,sectBeats))),axis = 1)
        match = feature.match_template(image,template,pad_input=True)
        ij = numpy.unravel_index(numpy.argmax(match), match.shape)
        x, y = ij[::-1]
        maxValues.append((numpy.argmax(match),
                          TEMPLATE_WIDTH*i+x,y,sections[i+1].duration))
        im = numpy.concatenate((im,match),axis = 1)
    maxValues.sort()
    maxValues.reverse()
    try:
        count = 0
        while(maxValues[count][3] < 10.0): # choose a section longer than 10 secs
            count += 1
        x = maxValues[count][1]
        y = maxValues[count][2]
    except:        
        print "exception in mashComponents..."
        ij = numpy.unravel_index(numpy.argmax(im), im.shape)
        x, y = ij[::-1]
    pyplot.imshow(im, cmap = pyplot.get_cmap('gray'), aspect = 'auto')
    pyplot.plot(x,y,'o',markeredgecolor='r',markerfacecolor='none',markersize=15)
    pyplot.show()
    sectionBeats = getSectBeats(sections[x/TEMPLATE_WIDTH])
    print "len(sectionBeats): ", len(sectionBeats)
    print "len(instBeats): ", len(instBeats)
    print "y: ", y
    y = instBeats[y].absolute_context()[0]
    instBeats = localAudioFiles[0].analysis.beats 
    matchingBeats = instBeats[(y-len(sectionBeats)/2):(y+len(sectionBeats)/2)]
    print"len(matchingBeats): ", len(matchingBeats)
    matchingBeats = matchingBeats[-len(sectionBeats):]
    print"len(matchingBeats): ", len(matchingBeats)
    """ Check to make sure lengths of beat lists are equal... """
    if len(matchingBeats) != len(sectionBeats):
        print "len(matchingBeats) != len(sectionBeats). For now, I will just truncate..."
        print "len(matchingBeats): ", len(matchingBeats)
        print "len(sectionBeats): ", len(sectionBeats)
        if len(matchingBeats) > len(sectionBeats):matchingBeats = matchingBeats[
                                                            :len(sectionBeats)]
        else: sectionBeats = sectionBeats[:len(matchingBeats)]
    """ I have to make sure sectionBeats and matchingBeats are similarly aligned
        within their group, aka bar of four beats. I will add a beat to the beginning
        of matchingBeats until that condition is met. I re-initialize instBeats and
        vocalBeats, because now I want to include the areas outside of those marked
        off by AutomaticDJ for fade ins and fade outs."""
    vocalBeats = localAudioFiles[1].analysis.beats
    while(matchingBeats[0].local_context()[0] != sectionBeats[0].local_context()[0]):
        matchingBeats.insert(0,instBeats[matchingBeats[0].absolute_context()[0]-1])
        sectionBeats.append(vocalBeats[sectionBeats[-1].absolute_context()[0]+1])
    """ Check to make sure lengths of beat lists are equal... """
    if len(matchingBeats) != len(sectionBeats):
        print "len(matchingBeats) != len(sectionBeats) at the second checkpoint."
        print "This should not be the case. The while loop must not be adding beats"
        print "to both lists equally."
        print "len(matchingBeats): ", len(matchingBeats)
        print "len(sectionBeats): ", len(sectionBeats)
        sys.exit()
    """ Next, I will use the beats around the designated beats above to transition into
    and out of the mashup. """
    XLEN = 4 # number of beats in crossmatch
    if(matchingBeats[0].absolute_context()[0] < XLEN or
       len(instBeats) - matchingBeats[-1].absolute_context()[0] - 1 < XLEN or
       sectionBeats[0].absolute_context()[0] < XLEN or
       len(vocalBeats) - sectionBeats[-1].absolute_context()[0] - 1 < XLEN):
        XLEN -= 1
    BUFFERLEN = 12 # number of beats before and after crossmatches
    while(matchingBeats[0].absolute_context()[0] < BUFFERLEN+XLEN or
       len(instBeats) - matchingBeats[-1].absolute_context()[0] - 1 < BUFFERLEN+XLEN or
       sectionBeats[0].absolute_context()[0] < BUFFERLEN+XLEN or
       len(vocalBeats) - sectionBeats[-1].absolute_context()[0] - 1 < BUFFERLEN+XLEN):
        BUFFERLEN -= 1
    try:
        """ These are the 4 beats before matchingBeats. These are the four beats of the
        instrumental track that preclude the mashed section. """
        b4beatsI = instBeats[matchingBeats[0].absolute_context()[0]-XLEN:
                            matchingBeats[0].absolute_context()[0]]
        """ These are the 4 beats after matchingBeats. These are the four beats of the
        instrumental track that follow the mashed section. """
        afterbeatsI = instBeats[matchingBeats[-1].absolute_context()[0]+1:
                            matchingBeats[-1].absolute_context()[0]+1+XLEN]
        if(len(b4beatsI) != len(afterbeatsI)):
            print "The lengths of b4beatsI and afterbeatsI are not equal."
        """ These are the 16 beats before the 4-beat crossmatch into matchingBeats. """
        preBufferBeats = instBeats[matchingBeats[0].absolute_context()[0]-BUFFERLEN-XLEN:
                                            matchingBeats[0].absolute_context()[0]-XLEN]
        """ These are the 16 beats before the 4-beat crossmatch into matchingBeats. """
        postBufferBeats = instBeats[matchingBeats[-1].absolute_context()[0]+1+XLEN:
                                matchingBeats[-1].absolute_context()[0]+1+XLEN+BUFFERLEN]
        if(len(preBufferBeats) != len(postBufferBeats)):
            print "The lengths of preBufferBeats and postBufferBeats are not equal."
            print "len(preBufferBeats): ", len(preBufferBeats)
            print "len(postBufferBeats): ", len(postBufferBeats)
            print matchingBeats[-1].absolute_context()[0]
            print len(instBeats)
            sys.exit()
        """ These are the 4 beats before matchingBeats. These are the four beats of the
        new vocal track that preclude the mashed section. """
        b4beatsV = vocalBeats[sectionBeats[0].absolute_context()[0]-XLEN:
                            sectionBeats[0].absolute_context()[0]]
        """ These are the 4 beats after matchingBeats. These are the four beats of the 
        new vocal track that follow the mashed section. """
        afterbeatsV = vocalBeats[sectionBeats[-1].absolute_context()[0]+1:
                            sectionBeats[-1].absolute_context()[0]+1+XLEN]
        if(len(b4beatsV) != len(afterbeatsV)):
            print "The lengths of b4beatsI and afterbeatsI are not equal."
            sys.exit()
    except: 
        print "exception in 4 beat try block."
        sys.exit()
    """ vocData: An AudioData object for the new vocal data that will be overlaid. 
        instData: An AudioData object for the base instrumental track. 
        originalVocData: An AudioData object of the original vocal to accompany 
            the new one. 
        vocalMix: An AudioData of both vocal tracks mixed together, in order to 
            keep the overall vocal loudness approximately constant. 
        mix: An AudioData of the instrumental track and combined vocals
            mixed together. """
    vocData = audio.getpieces(localAudioFiles[3],b4beatsV+sectionBeats+afterbeatsV)
    instData = audio.getpieces(localAudioFiles[2],b4beatsI+matchingBeats+afterbeatsI)
    if instData.data.shape[0] >= vocData.data.shape[0]: 
        mix = audio.megamix([instData, vocData])
    else: 
        mix = audio.megamix([vocData, instData]) # the longer data set has to go first.
    mix.encode('mix.mp3')
    vocData.encode('vocData.mp3')
    """ Now, make a similar mix for before the mashed sections..."""
    instData = audio.getpieces(localAudioFiles[2], preBufferBeats + b4beatsI)
    vocData = audio.getpieces(localAudioFiles[4], preBufferBeats + b4beatsI)
    premix = audio.megamix([instData, vocData])
    """ ...and another mix for after the mashed sections."""
    instData = audio.getpieces(localAudioFiles[2], afterbeatsI + postBufferBeats)
    vocData = audio.getpieces(localAudioFiles[4], afterbeatsI + postBufferBeats)
    postmix = audio.megamix([instData, vocData])
    """ Now, I have three AudioData objects, mix, premix, and postmix, that overlap by
    four beats. I will build Crossmatch objects from the overlapping regions, and three 
    Playback objects for the areas that are not in transition. """
    action.make_stereo(premix)
    action.make_stereo(mix)
    action.make_stereo(postmix)
    preBuffdur = sum([p.duration for p in preBufferBeats]) # duration of preBufferBeats
    playback1 = action.Playback(premix,0.0,preBuffdur)
    b4dur = sum([p.duration for p in b4beatsI]) # duration of b4beatsI
    crossfade1 = action.Crossfade((premix,mix),(preBuffdur,0.0),b4dur) 
    abdur = sum([p.duration for p in afterbeatsI])
    playback2 = action.Playback(mix,b4dur,mix.duration - b4dur - abdur)
    crossfade2 = action.Crossfade((mix,postmix),(mix.duration - abdur,0.0),abdur) 
    playback3 = action.Playback(postmix,abdur,sum([p.duration for p in postBufferBeats]))
    action.render([playback1,crossfade1,playback2,crossfade2,playback3], 'mashup.mp3')
Esempio n. 3
0
				# we need to add silence, because segment1 is longer
				if num_channels > 1:
					silence_shape = (reference_data.endindex,num_channels)
				else:
					silence_shape = (reference_data.endindex,)
				new_segment = audio.AudioData(shape=silence_shape,
										sampleRate=out.sampleRate,
										numChannels=segment_data.numChannels)
				new_segment.append(segment_data)
				new_segment.endindex = len(new_segment)
				segment_data = new_segment
			elif reference_data.endindex < segment_data.endindex:
				# we need to cut segment2 shorter, because segment2 is shorter
				index = slice(0, int(reference_data.endindex), 1)
				segment_data = audio.AudioData(None, segment_data.data[index], sampleRate=segment_data.sampleRate)
		else: 		  
			# TODO: stretch samples to fit.
			# haven't written this part yet.
			segment_data = segment_data
		
		
		segment_data_list.append(segment_data)
		
	# mix the original and the remix
	#mixed_data = audio.mix(segment_data,reference_data,mix=mix)
	mixed_data = audio.megamix(segment_data_list)
	out.append(mixed_data)

# redner output
out.encode(outputFilename)
Esempio n. 4
0
                else:
                    silence_shape = (reference_data.endindex, )
                new_segment = audio.AudioData(
                    shape=silence_shape,
                    sampleRate=out.sampleRate,
                    numChannels=segment_data.numChannels)
                new_segment.append(segment_data)
                new_segment.endindex = len(new_segment)
                segment_data = new_segment
            elif reference_data.endindex < segment_data.endindex:
                # we need to cut segment2 shorter, because segment2 is shorter
                index = slice(0, int(reference_data.endindex), 1)
                segment_data = audio.AudioData(
                    None,
                    segment_data.data[index],
                    sampleRate=segment_data.sampleRate)
        else:
            # TODO: stretch samples to fit.
            # haven't written this part yet.
            segment_data = segment_data

        segment_data_list.append(segment_data)

    # mix the original and the remix
    #mixed_data = audio.mix(segment_data,reference_data,mix=mix)
    mixed_data = audio.megamix(segment_data_list)
    out.append(mixed_data)

# redner output
out.encode(outputFilename)