/examples/multi/multitest.py

http://echo-nest-remix.googlecode.com/ · Python · 79 lines · 48 code · 15 blank · 16 comment · 5 complexity · 890857cdc52490a4ea3902cefd3fbf7b MD5 · raw file

  1. #!/usr/bin/env python
  2. # encoding: utf=8
  3. """
  4. multitest.py
  5. Take a whole directory of audio files and smash them together, by
  6. beat, with a fairly simple algorithm. Demonstrates the use of
  7. deferred audio file loading used in conjunction with render_serially(),
  8. which allow one to remix countless files without running out of memory
  9. too soon. Also outputs a "score" in XML.
  10. Originally by Adam Lindsay, 2000-05-05.
  11. """
  12. import os, sys
  13. import time
  14. from math import sqrt
  15. from echonest import audio
  16. usage = """
  17. Usage:
  18. python multitest.py <inputDirectory> <outputFilename> <beats>
  19. Example:
  20. python multitest.py ../music mashedbeats.mp3 40
  21. """
  22. def main(num_beats, directory, outfile):
  23. aud = []
  24. ff = os.listdir(directory)
  25. for f in ff:
  26. # collect the files
  27. if f.rsplit('.', 1)[1].lower() in ['mp3', 'aif', 'aiff', 'aifc', 'wav']:
  28. aud.append(audio.LocalAudioFile(os.path.join(directory,f)))
  29. # mind the rate limit
  30. num_files = len(aud)
  31. x = audio.AudioQuantumList()
  32. print >> sys.stderr, "Assembling beats.",
  33. for w in range(num_beats):
  34. print >> sys.stderr, '.',
  35. ssong = aud[w%num_files].analysis
  36. s = ssong.beats[w%len(ssong.beats)]
  37. tsong = aud[(w-1)%num_files].analysis
  38. t = tsong.beats[w%len(tsong.beats)]
  39. x.append(audio.Simultaneous([s,t]))
  40. print >> sys.stderr, "\nStarting rendering pass..."
  41. then = time.time()
  42. # call render_sequentially() with no arguments, and then it calls itself with
  43. # contextual arguments for each source, for each AudioQuantum. It's a lot of
  44. # tree-walking, but each source file gets loaded once (and takes itself from)
  45. # memory when its rendering pass finishes.
  46. x.render().encode(outfile)
  47. print >> sys.stderr, "%f sec for rendering" % (time.time() - then,)
  48. print >> sys.stderr, "Outputting XML: each source makes an API call for its metadata."
  49. # output an XML file, for debugging purposes
  50. y = open(outfile.rsplit('.', 1)[0] + '.xml', 'w')
  51. y.write(x.toxml())
  52. y.close()
  53. if __name__ == '__main__':
  54. try:
  55. directory = sys.argv[-3]
  56. outfile = sys.argv[-2]
  57. num_beats = int(sys.argv[-1])
  58. except:
  59. print usage
  60. sys.exit(-1)
  61. main(num_beats, directory, outfile)