예제 #1
0
 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,