/examples/step/step-by-pitch.py

http://echo-nest-remix.googlecode.com/ · Python · 90 lines · 65 code · 4 blank · 21 comment · 0 complexity · f9c934ac5d1c96ad5d65f686d84969d8 MD5 · raw file

  1. #!/usr/bin/env python
  2. # encoding: utf=8
  3. """
  4. step-by-pitch.py
  5. For each bar, take one of the nearest (in pitch) beats
  6. to the last beat, chosen from all of the beats that fall
  7. on the one. Repeat for all the twos, etc.
  8. The variation parameter, (_v_) means there's a roughly
  9. one in _v_ chance that the actual next beat is chosen. The
  10. length is the length in bars you want it to go on.
  11. Originally by Adam Lindsay, 2009-03-10.
  12. """
  13. import random
  14. import echonest.audio as audio
  15. from echonest.sorting import *
  16. from echonest.selection import *
  17. usage = """
  18. Usage:
  19. python step-by-pitch.py inputFilename outputFilename [variation [length]]
  20. variation is the number of near candidates chosen from. [default=4]
  21. length is the number of bars in the final product. [default=40]
  22. Example:
  23. python step-by-pitch.py Discipline.mp3 SpicDinLie.mp3 3 60
  24. """
  25. def main(infile, outfile, choices=4, bars=40):
  26. audiofile = audio.LocalAudioFile(infile)
  27. meter = audiofile.analysis.time_signature['value']
  28. fade_in = audiofile.analysis.end_of_fade_in
  29. fade_out = audiofile.analysis.start_of_fade_out
  30. segments = audiofile.analysis.segments.that(are_contained_by_range(fade_in, fade_out))
  31. beats = audiofile.analysis.beats.that(are_contained_by_range(segments[0].start, segments[-1].end))
  32. outchunks = audio.AudioQuantumList()
  33. b = []
  34. segstarts = []
  35. for m in range(meter):
  36. b.append(beats.that(are_beat_number(m)))
  37. segstarts.append(segments.that(overlap_starts_of(b[m])))
  38. now = b[0][0]
  39. for x in range(0, bars * meter):
  40. beat = x % meter
  41. next_beat = (x + 1) % meter
  42. now_end_segment = segments.that(contain_point(now.end))[0]
  43. next_candidates = segstarts[next_beat].ordered_by(pitch_distance_from(now_end_segment))
  44. next_choice = next_candidates[random.randrange(min(choices, len(next_candidates)))]
  45. next = b[next_beat].that(start_during(next_choice))[0]
  46. outchunks.append(now)
  47. print now.context_string()
  48. now = next
  49. out = audio.getpieces(audiofile, outchunks)
  50. out.encode(outfile)
  51. def are_beat_number(beat):
  52. def fun(x):
  53. if x.local_context()[0] == beat:
  54. return x
  55. return fun
  56. #
  57. if __name__ == '__main__':
  58. import sys
  59. try:
  60. inputFilename = sys.argv[1]
  61. outputFilename = sys.argv[2]
  62. if len(sys.argv) > 3:
  63. variation = int(sys.argv[3])
  64. else:
  65. variation = 4
  66. if len(sys.argv) > 4:
  67. length = int(sys.argv[4])
  68. else:
  69. length = 40
  70. except:
  71. print usage
  72. sys.exit(-1)
  73. main(inputFilename, outputFilename, variation, length)