PageRenderTime 25ms CodeModel.GetById 12ms app.highlight 9ms RepoModel.GetById 2ms app.codeStats 0ms

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

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