def sortFiles(self): # Get list of wav files, recursively fileList = utility.getFiles(self.snippetDirectory, '.wav') # Array of per-file, per-note tonalities. Each file gets a score for each pitch tonalities = np.zeros((len(fileList), self.nNotes)) print "Getting tonalities..." for n in np.arange(len(fileList)): # Get audio data audioData, fs = utility.getWavData(fileList[n]) # Make sure the sampling rate matches... assert fs == self.fs # Get the tonality scores for all notes for this file tonalities[n] = self.getTonality(audioData) # Hash for the fundamental frequencies of each file fileFrequencies = {} # Find the best file for each note print "Finding best candidates for notes" for n in np.arange(self.nNotes): # Get the tonality scores tonalitiesForThisNote = tonalities[:, n] # Get the sorted indices of tonality scores tonalitiesSort = np.argsort(tonalitiesForThisNote)[::-1] # Keep track of which sorted array index we're getting the frequency for sortedIndex = 0 # What frequency is the note we're looking for? targetHz = utility.midiToHz(self.baseNote + n) # What's the detected Hz of the note? detectedHz = 1.0 # Until we find an audio file whose YIN detected pitch is sufficiently close while ( (targetHz / detectedHz) < (1 - PITCH_TOLERANCE) or (targetHz / detectedHz) > (1 + PITCH_TOLERANCE)) and sortedIndex < tonalitiesSort.shape[ 0] and sortedIndex < PITCHES_TO_RUN: # If this file has not been YIN analyzed yet, analyze it if not fileFrequencies.has_key(tonalitiesSort[sortedIndex]): audioData, fs = utility.getWavData( fileList[tonalitiesSort[sortedIndex]]) # ... and store it so that you don't have to calculate it next time fileFrequencies[tonalitiesSort[ sortedIndex]] = self.yinPitchDetect(audioData) detectedHz = fileFrequencies[tonalitiesSort[sortedIndex]] # Check the next file next time sortedIndex += 1 # If we didn't run out of files, copy out the file that we found (with the closest pitch) if sortedIndex < len(fileList): shutil.copy( fileList[tonalitiesSort[sortedIndex - 1]], os.path.join(self.destinationDirectory, str(n + self.baseNote) + ".wav")) else: shutil.copy( fileList[tonalitiesSort[0]], os.path.join(self.destinationDirectory, str(n + self.baseNote) + ".wav"))
def sortFiles( self ): # Get list of wav files, recursively fileList = utility.getFiles( self.snippetDirectory, '.wav' ) # Array of per-file, per-note tonalities. Each file gets a score for each pitch tonalities = np.zeros( ( len( fileList ), self.nNotes ) ) print "Getting tonalities..." for n in np.arange( len( fileList ) ): # Get audio data audioData, fs = utility.getWavData( fileList[n] ) # Make sure the sampling rate matches... assert fs == self.fs # Get the tonality scores for all notes for this file tonalities[n] = self.getTonality( audioData ) # Hash for the fundamental frequencies of each file fileFrequencies = {} # Find the best file for each note print "Finding best candidates for notes" for n in np.arange( self.nNotes ): # Get the tonality scores tonalitiesForThisNote = tonalities[:,n] # Get the sorted indices of tonality scores tonalitiesSort = np.argsort( tonalitiesForThisNote )[::-1] # Keep track of which sorted array index we're getting the frequency for sortedIndex = 0 # What frequency is the note we're looking for? targetHz = utility.midiToHz( self.baseNote + n ) # What's the detected Hz of the note? detectedHz = 1.0 # Until we find an audio file whose YIN detected pitch is sufficiently close while ((targetHz/detectedHz) < (1 - PITCH_TOLERANCE) or (targetHz/detectedHz) > (1 + PITCH_TOLERANCE)) and sortedIndex < tonalitiesSort.shape[0] and sortedIndex < PITCHES_TO_RUN: # If this file has not been YIN analyzed yet, analyze it if not fileFrequencies.has_key( tonalitiesSort[sortedIndex] ): audioData, fs = utility.getWavData( fileList[tonalitiesSort[sortedIndex]] ) # ... and store it so that you don't have to calculate it next time fileFrequencies[tonalitiesSort[sortedIndex]] = self.yinPitchDetect( audioData ) detectedHz = fileFrequencies[tonalitiesSort[sortedIndex]] # Check the next file next time sortedIndex += 1 # If we didn't run out of files, copy out the file that we found (with the closest pitch) if sortedIndex < len( fileList ): shutil.copy( fileList[tonalitiesSort[sortedIndex-1]], os.path.join( self.destinationDirectory, str(n + self.baseNote) + ".wav" ) ) else: shutil.copy( fileList[tonalitiesSort[0]], os.path.join( self.destinationDirectory, str(n + self.baseNote) + ".wav" ) )
# Run function as script if __name__ == "__main__": import sys import os import utility if len(sys.argv) < 2: print "Usage: %s filename.mp3|filename.wav" % sys.argv[0] sys.exit(-1) # Wav or mp3? basename, extension = os.path.splitext( sys.argv[1] ) if extension == '.mp3': print "Getting mp3 data ..." audioData, fs = utility.getMp3Data( sys.argv[1] ) elif extension == '.wav': print "Getting wav data ..." audioData, fs = utility.getWavData( sys.argv[1] ) else: print "Not .wav or .mp3." sys.exit(-1) hop = 1024 frameSize = 4096 spectrogram = utility.getSpectrogram( audioData, hop=hop, frameSize=frameSize ) print "Separating harmonic and percussive components ..." start = time() seperator = HarmonicPercussiveSeparator( spectrogram ) end = time() print "Took ", end - start utility.plotSpectrogram( spectrogram ) utility.plotSpectrogram( seperator.harmonicSpectrogram ) utility.plotSpectrogram( seperator.percussiveSpectrogram )
# The data, being manipulated each step of the way audioData = {} audioDataDownsampled = {} spectrograms = {} ODFOutput = {} # Test to plot histograms allAccuracies = np.zeros(nTests) # Can we calculate the spectrogram from the previous spectrogram? previousHopSizeScale = 0 for directory in directories: # Read in wav data for each file - should try downsampling factors for file in filenames: audioData[file], fs = utility.getWavData(os.path.join(directory, file)) for downsamplingFactor in downsamplingFactors: for file in filenames: audioDataDownsampled[file] = scipy.signal.decimate(audioData[file], downsamplingFactor) for frameSize, window, hopSizeScale in itertools.product(frameSizes, windows, hopSizeScales): if hopSizeScale < previousHopSizeScale and np.mod(previousHopSizeScale, hopSizeScale) == 0: # Instead of calculating a new spectrogram, just grab the frames newHopRatio = previousHopSizeScale / hopSizeScale for file in filenames: spectrograms[file] = spectrograms[file][::newHopRatio] else: # Calculate spectrograms - should not re-calculate if just the hop size changes. for file in filenames: spectrograms[file] = utility.getSpectrogram( audioDataDownsampled[file], hop=frameSize / hopSizeScale,