示例#1
0
    def render(self, input_midi_filename, frame_save_dir, tracks, speed_map=[{'time':0.0,'speed':4}],
        dimensions=(720,480), fps=29.97, min_pitch=34, max_pitch=86, first_frame=None,
        last_frame=None, every_nth_frame=1, do_render=1):
        """Render the animation!"""

        print "Beginning render..."
        speed = speed_map[0]['speed']
        if first_frame == None:
            first_frame = 0
        if last_frame == None:
            last_frame = 10000000 # just a large number

        print "Lexing midi..."
        blocks = []
        lexer = MidiLexer()
        midi_events = lexer.lex(input_midi_filename)

        print "Blockifying midi..."
        blocks = self.blockify(midi_events) # convert into list of blocks

        for track in tracks:
            if 'color' in track:
                base_color = colorsys.rgb_to_hls(*track['color'])
                track['high_color'] = colorsys.hls_to_rgb(base_color[0], 0.95,
                    base_color[2])
                track['lyrics_color'] = colorsys.hls_to_rgb(base_color[0], 0.7,
                    base_color[2])
            if 'lyrics' in track:
                track['lyrics'] = self.lyrics_deque(track['lyrics'])

        # do some useful calculations on all blocks
        blocks, last_block_end = self.add_block_info(blocks, tracks,
            fps, speed_map, dimensions, min_pitch, max_pitch)

        # following used for calculating percentage done to print to console
        original_end = last_block_end
        percent = 0
        last_percent = -1

        # sort by z-index descending
        blocks.sort(lambda a, b: cmp(b['z-index'], a['z-index']))

        # for naming image files:
        frame = 0
        # for keeping track of speed changes:
        # need to initialize time
        time = -dimensions[0]/(2.0*fps*speed_map[0]['speed'])

        if not do_render:
            print "Skipping render pass, Done!"
            return

        print "Rendering frames..."
        # generate frames while there are blocks on the screen:
        while last_block_end > (0 - speed):
            # code only for rendering blocks
            if frame >= first_frame and frame <= last_frame and frame % every_nth_frame == 0:
                # cairo setup stuff
                filename = frame_save_dir + ("frame%05i.png" % frame)
                surface = cairo.ImageSurface(cairo.FORMAT_RGB24, *dimensions)
                #surface = cairo.SVGSurface(filename, *dimensions)
                cr = cairo.Context(surface)
                cr.set_antialias(cairo.ANTIALIAS_GRAY)
                cr.select_font_face("Garamond", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_BOLD)
                cr.set_font_size(19)
                # add black background
                cr.set_source_rgb(0, 0, 0)
                cr.rectangle(0, 0, *dimensions)
                cr.fill()

                # need to do two passes of drawing blocks, once in reverse order
                # in full opacity, and a second time in ascending order in half-
                # opacityto get fully-colored bars that blend together when
                # overlapping

                # get list of blocks that are on screen
                on_screen_blocks = [block for block in blocks
                    if block['start_x'] < dimensions[0] and block['end_x'] > 0]
                on_screen_layers = list(set([block['layer'] for block in on_screen_blocks]))
                
                for layer in on_screen_layers:
                    layer_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, *dimensions)
                    layer_context = cairo.Context(layer_surface)
                    
                    in_layer_blocks = [block for block in on_screen_blocks if block['layer'] == layer]

                    # do first drawing pass
                    for block in in_layer_blocks:
                        self.draw_block_cairo(block, tracks, dimensions, layer_context)

                    # do second drawing pass
                    on_screen_blocks.reverse()
                    for block in in_layer_blocks:
                        self.draw_block_cairo(block, tracks, dimensions, layer_context, transparent=True)
                        
                    cr.set_source_surface(layer_surface)
                    cr.paint()

                # do lyrics pass, sort by start x so starts of words are on top
                on_screen_blocks.sort(lambda a, b: cmp(a['start_x'], b['start_x']))
                for block in on_screen_blocks:
                    if ('lyrics' in block):
                        self.draw_lyrics_cairo(block, tracks, dimensions, cr)

                #cr.save()
                surface.write_to_png(filename)

            # other code needed to advance animation
            frame += 1
            # need to set speed
            speed = self.get_speed(speed_map, time)
            for block in blocks: # move blocks to left
                block['start_x'] -= speed
                block['end_x'] -= speed
                if 'lyrics_end_x' in block:
                    block['lyrics_end_x'] -= speed
            last_block_end -= speed # move video endpoint left as well
            percent = int(min((original_end - last_block_end) * 100.0
                / original_end, 100))
            if percent != last_percent:
                print percent, "% done"
            last_percent = percent

            time += (1/fps)

        print "Done!"
示例#2
0
    def render(self,
               input_midi_filename,
               frame_save_dir,
               tracks,
               speed_map=speed_map,
               dimensions=(width, height),
               fps=fps,
               min_pitch=min_pitch,
               max_pitch=max_pitch,
               first_frame=first_frame,
               last_frame=last_frame,
               every_nth_frame=every_nth_frame,
               do_render=do_render,
               dynamicmode=False):
        self.dynamicmode = dynamicmode
        """Render the animation!"""
        print "Beginning render..."
        speed = speed_map[0]['speed']
        if first_frame == None:
            first_frame = 0
        if last_frame == None:
            last_frame = 10000000  # just a large number

        print "Lexing midi..."
        blocks = []
        lexer = MidiLexer()
        midi_events = lexer.lex(input_midi_filename)

        print "Blockifying midi..."
        blocks = self.blockify(midi_events)  # convert into list of blocks
        print str(len(blocks)) + " blocks"

        for track in tracks:
            if 'color' in track:
                base_color = colorsys.rgb_to_hls(*track['color'])
                track['high_color'] = colorsys.hls_to_rgb(
                    base_color[0], 0.95, base_color[2])
                track['lyrics_color'] = colorsys.hls_to_rgb(
                    base_color[0], 0.7, base_color[2])
            if 'lyrics' in track:
                track['lyrics'] = self.lyrics_deque(track['lyrics'])

        # do some useful calculations on all blocks
        blocks, last_block_end = self.add_block_info(blocks, tracks, fps,
                                                     speed_map, dimensions,
                                                     min_pitch, max_pitch)

        # following used for calculating percentage done to print to console
        original_end = last_block_end
        percent = 0
        last_percent = -1

        # sort by z-index descending
        blocks.sort(lambda a, b: cmp(b['z-index'], a['z-index']))

        # for naming image files:
        frame = 0
        framefile = 0
        # for keeping track of speed changes:
        # need to initialize time
        time = -dimensions[0] / (2.0 * fps * speed_map[0]['speed'])

        if not do_render:
            print "Skipping render pass, Done!"
            return

        print "Rendering frames..."
        # generate frames while there are blocks on the screen:
        while last_block_end > -speed:
            # code only for rendering blocks
            if first_frame < frame and frame <= last_frame and frame % every_nth_frame == 0:
                # cairo setup stuff
                filename = frame_save_dir + ("frame%05i.png" % framefile)
                surface = cairo.ImageSurface(cairo.FORMAT_RGB24, *dimensions)
                cr = cairo.Context(surface)
                cr.set_antialias(cairo.ANTIALIAS_GRAY)
                cr.select_font_face("Garamond", cairo.FONT_SLANT_NORMAL,
                                    cairo.FONT_WEIGHT_BOLD)
                cr.set_font_size(19)
                # add black background
                cr.set_source_rgb(0, 0, 0)
                cr.rectangle(0, 0, *dimensions)
                cr.fill()
                '''need to do two passes of drawing blocks, once in reverse order in full opacity, and a second time in ascending order in half-opacity to get fully-colored bars that blend together when overlapping'''

                # get list of blocks that are on screen
                on_screen_blocks = [
                    block for block in blocks
                    if block['start_x'] < dimensions[0]
                ]

                for layer in set(
                    [block['layer'] for block in on_screen_blocks]):
                    layer_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
                                                       *dimensions)
                    layer_context = cairo.Context(layer_surface)

                    in_layer_blocks = [
                        block for block in on_screen_blocks
                        if block['layer'] == layer
                    ]

                    # do first drawing pass
                    for block in in_layer_blocks:
                        block = self.makedynamic(block, dimensions)
                        if block == None:
                            continue
                        self.draw_block_cairo(block, tracks, dimensions,
                                              layer_context)

                    # do second drawing pass
                    on_screen_blocks.reverse()
                    for block in in_layer_blocks:
                        block = self.makedynamic(block, dimensions)
                        if block == None:
                            continue
                        self.draw_block_cairo(block,
                                              tracks,
                                              dimensions,
                                              layer_context,
                                              transparent=True)

                    cr.set_source_surface(layer_surface)
                    cr.paint()

                # do lyrics pass, sort by start x so starts of words are on top
                on_screen_blocks.sort(
                    lambda a, b: cmp(a['start_x'], b['start_x']))
                for block in on_screen_blocks:
                    if ('lyrics' in block):
                        self.draw_lyrics_cairo(block, tracks, dimensions, cr)

                if self.introduction or self.first_highlight:
                    framefile += 1
                    surface.write_to_png(filename)

            # other code needed to advance animation
            frame += 1
            # need to set speed
            speed = self.get_speed(speed_map, time)
            for block in list(blocks):  # move blocks to left
                end = block['end_x'] - speed
                if end < 0:
                    '''trash blocks no longer needed. benchmark shows this causes a 2% increase in processing time in medium-sized files (~1000 blocks) but up to 15% redution in big files (~10000 blocks)'''
                    blocks.remove(block)
                    continue
                block['end_x'] = end
                block['start_x'] -= speed
                if 'lyrics_end_x' in block:
                    block['lyrics_end_x'] -= speed
            last_block_end -= speed  # move video endpoint left as well
            percent = min(
                int((original_end - last_block_end) * 100.0 / original_end),
                100)
            if percent != last_percent:
                print percent, "% done"
            last_percent = percent

            time += (1 / fps)

        print "Done!"
示例#3
0
    def render(self,
               input_midi_filename,
               frame_save_dir,
               tracks,
               speed_map=[{
                   'time': 0.0,
                   'speed': 4
               }],
               dimensions=(720, 480),
               fps=29.97,
               min_pitch=34,
               max_pitch=86,
               first_frame=None,
               last_frame=None,
               every_nth_frame=1,
               do_render=1):
        """Render the animation!"""

        print "Beginning render..."
        speed = speed_map[0]['speed']
        if first_frame == None:
            first_frame = 0
        if last_frame == None:
            last_frame = 10000000  # just a large number

        print "Lexing midi..."
        blocks = []
        lexer = MidiLexer()
        midi_events = lexer.lex(input_midi_filename)

        print "Blockifying midi..."
        blocks = self.blockify(midi_events)  # convert into list of blocks

        for track in tracks:
            if 'color' in track:
                base_color = colorsys.rgb_to_hls(*track['color'])
                track['high_color'] = colorsys.hls_to_rgb(
                    base_color[0], 0.95, base_color[2])
                track['lyrics_color'] = colorsys.hls_to_rgb(
                    base_color[0], 0.7, base_color[2])
            if 'lyrics' in track:
                track['lyrics'] = self.lyrics_deque(track['lyrics'])

        # do some useful calculations on all blocks
        blocks, last_block_end = self.add_block_info(blocks, tracks, fps,
                                                     speed_map, dimensions,
                                                     min_pitch, max_pitch)

        # following used for calculating percentage done to print to console
        original_end = last_block_end
        percent = 0
        last_percent = -1

        # sort by z-index descending
        blocks.sort(lambda a, b: cmp(b['z-index'], a['z-index']))

        # for naming image files:
        frame = 0
        # for keeping track of speed changes:
        # need to initialize time
        time = -dimensions[0] / (2.0 * fps * speed_map[0]['speed'])

        if not do_render:
            print "Skipping render pass, Done!"
            return

        print "Rendering frames..."
        # generate frames while there are blocks on the screen:
        while last_block_end > (0 - speed):
            # code only for rendering blocks
            if frame >= first_frame and frame <= last_frame and frame % every_nth_frame == 0:
                # cairo setup stuff
                filename = frame_save_dir + ("frame%05i.png" % frame)
                surface = cairo.ImageSurface(cairo.FORMAT_RGB24, *dimensions)
                #surface = cairo.SVGSurface(filename, *dimensions)
                cr = cairo.Context(surface)
                cr.set_antialias(cairo.ANTIALIAS_GRAY)
                cr.select_font_face("Garamond", cairo.FONT_SLANT_NORMAL,
                                    cairo.FONT_WEIGHT_BOLD)
                cr.set_font_size(19)
                # add black background
                cr.set_source_rgb(0, 0, 0)
                cr.rectangle(0, 0, *dimensions)
                cr.fill()

                # need to do two passes of drawing blocks, once in reverse order
                # in full opacity, and a second time in ascending order in half-
                # opacityto get fully-colored bars that blend together when
                # overlapping

                # get list of blocks that are on screen
                on_screen_blocks = [
                    block for block in blocks
                    if block['start_x'] < dimensions[0] and block['end_x'] > 0
                ]
                on_screen_layers = list(
                    set([block['layer'] for block in on_screen_blocks]))

                for layer in on_screen_layers:
                    layer_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
                                                       *dimensions)
                    layer_context = cairo.Context(layer_surface)

                    in_layer_blocks = [
                        block for block in on_screen_blocks
                        if block['layer'] == layer
                    ]

                    # do first drawing pass
                    for block in in_layer_blocks:
                        self.draw_block_cairo(block, tracks, dimensions,
                                              layer_context)

                    # do second drawing pass
                    on_screen_blocks.reverse()
                    for block in in_layer_blocks:
                        self.draw_block_cairo(block,
                                              tracks,
                                              dimensions,
                                              layer_context,
                                              transparent=True)

                    cr.set_source_surface(layer_surface)
                    cr.paint()

                # do lyrics pass, sort by start x so starts of words are on top
                on_screen_blocks.sort(
                    lambda a, b: cmp(a['start_x'], b['start_x']))
                for block in on_screen_blocks:
                    if ('lyrics' in block):
                        self.draw_lyrics_cairo(block, tracks, dimensions, cr)

                #cr.save()
                surface.write_to_png(filename)

            # other code needed to advance animation
            frame += 1
            # need to set speed
            speed = self.get_speed(speed_map, time)
            for block in blocks:  # move blocks to left
                block['start_x'] -= speed
                block['end_x'] -= speed
                if 'lyrics_end_x' in block:
                    block['lyrics_end_x'] -= speed
            last_block_end -= speed  # move video endpoint left as well
            percent = int(
                min((original_end - last_block_end) * 100.0 / original_end,
                    100))
            if percent != last_percent:
                print percent, "% done"
            last_percent = percent

            time += (1 / fps)

        print "Done!"
示例#4
0
def main():
    tracks = [
        {
            'name': "track0",
            'color': (0.000, 0.996, 0.000),
            'width': TRACK_WIDTH,
            'z-index': 0
        },
        {
            'name': "track1",
            'color': (0.996, 0.000, 0.000),
            'width': TRACK_WIDTH,
            'z-index': 1
        },
        {
            'name': "track2",
            'color': (0.004, 0.996, 0.992),
            'width': TRACK_WIDTH,
            'z-index': 2
        },
        {
            'name': "track3",
            'color': (0.996, 0.855, 0.398),
            'width': TRACK_WIDTH,
            'z-index': 3
        },
        {
            'name': "track4",
            'color': (0.563, 0.980, 0.570),
            'width': TRACK_WIDTH,
            'z-index': 4
        },
        {
            'name': "track5",
            'color': (0.000, 0.461, 0.996),
            'width': TRACK_WIDTH,
            'z-index': 5
        },
        {
            'name': "track6",
            'color': (0.832, 0.996, 0.000),
            'width': TRACK_WIDTH,
            'z-index': 6
        },
        {
            'name': "track7",
            'color': (0.996, 0.574, 0.492),
            'width': TRACK_WIDTH,
            'z-index': 7
        },
        {
            'name': "track8",
            'color': (0.992, 0.535, 0.000),
            'width': TRACK_WIDTH,
            'z-index': 8
        },
        {
            'name': "track9",
            'color': (0.520, 0.660, 0.000),
            'width': TRACK_WIDTH,
            'z-index': 9
        },
        {
            'name': "track10",
            'color': (0.000, 0.680, 0.492),
            'width': TRACK_WIDTH,
            'z-index': 10
        },
        {
            'name': "track11",
            'color': (0.738, 0.773, 0.996),
            'width': TRACK_WIDTH,
            'z-index': 11
        },
        {
            'name': "track12",
            'color': (0.738, 0.824, 0.574),
            'width': TRACK_WIDTH,
            'z-index': 12
        },
        {
            'name': "track13",
            'color': (0.000, 0.723, 0.090),
            'width': TRACK_WIDTH,
            'z-index': 13
        },
        {
            'name': "track14",
            'color': (0.004, 0.813, 0.996),
            'width': TRACK_WIDTH,
            'z-index': 14
        },
        {
            'name': "track15",
            'color': (0.566, 0.813, 0.793),
            'width': TRACK_WIDTH,
            'z-index': 15
        },
        {
            'name': "track16",
            'color': (0.730, 0.531, 0.000),
            'width': TRACK_WIDTH,
            'z-index': 16
        },
        {
            'name': "track17",
            'color': (0.867, 0.996, 0.453),
            'width': TRACK_WIDTH,
            'z-index': 17
        },
        {
            'name': "track18",
            'color': (0.000, 0.996, 0.773),
            'width': TRACK_WIDTH,
            'z-index': 18
        },
        {
            'name': "track19",
            'color': (0.996, 0.895, 0.008),
            'width': TRACK_WIDTH,
            'z-index': 19
        },
        {
            'name': "track20",
            'color': (0.594, 0.996, 0.320),
            'width': TRACK_WIDTH,
            'z-index': 20
        },
        {
            'name': "track21",
            'color': (0.000, 0.996, 0.469),
            'width': TRACK_WIDTH,
            'z-index': 21
        },
        {
            'name': "track22",
            'color': (0.996, 0.430, 0.254),
            'width': TRACK_WIDTH,
            'z-index': 22
        },
        {
            'name': "track23",
            'color': (0.645, 0.996, 0.820),
            'width': TRACK_WIDTH,
            'z-index': 23
        },
        {
            'name': "track24",
            'color': (0.996, 0.691, 0.402),
            'width': TRACK_WIDTH,
            'z-index': 24
        },
        {
            'name': "track25",
            'color': (0.000, 0.605, 0.996),
            'width': TRACK_WIDTH,
            'z-index': 25
        },
    ]

    if len(sys.argv) < 3:
        print(
            "Usage: python MusAnimLauncher.py input.mid outputDirectory [--dynamic]"
        )
        sys.exit(1)
        return

    mid = sys.argv[1]

    lexer = MidiLexer()
    lexer.lex(mid)

    frames_dir = sys.argv[2] + os.sep
    os.makedirs(frames_dir)

    dynamic = len(sys.argv) >= 4 and sys.argv[3] == '--dynamic'

    speed_map = [{'time': 0.0, 'speed': 4}]

    #dimensions = 426, 240
    dimensions = 720, 480
    #dimensions = 1920, 1080

    fps = 25
    #fps = 29.97

    renderer = MusAnimRenderer()
    renderer.introduction = False
    renderer.render(mid,
                    frames_dir,
                    tracks,
                    speed_map=speed_map,
                    dimensions=dimensions,
                    min_pitch=lexer.minPitch - PITCH_GRACE,
                    max_pitch=lexer.maxPitch + PITCH_GRACE,
                    fps=fps,
                    dynamicmode=dynamic)
示例#5
0
def main():
    tracks = [
    	{ 'name': "track0",
	'color': (0.000, 0.996, 0.000),
	'width': TRACK_WIDTH,
	'z-index': 0
	},
	{ 'name': "track1",
	'color': (0.996, 0.000, 0.000),
	'width': TRACK_WIDTH,
	'z-index': 1
	},
	{ 'name': "track2",
	'color': (0.004, 0.996, 0.992),
	'width': TRACK_WIDTH,
	'z-index': 2
	},
	{ 'name': "track3",
	'color': (0.996, 0.855, 0.398),
	'width': TRACK_WIDTH,
	'z-index': 3
	},
	{ 'name': "track4",
	'color': (0.563, 0.980, 0.570),
	'width': TRACK_WIDTH,
	'z-index': 4
	},
	{ 'name': "track5",
	'color': (0.000, 0.461, 0.996),
	'width': TRACK_WIDTH,
	'z-index': 5
	},
	{ 'name': "track6",
	'color': (0.832, 0.996, 0.000),
	'width': TRACK_WIDTH,
	'z-index': 6
	},
	{ 'name': "track7",
	'color': (0.996, 0.574, 0.492),
	'width': TRACK_WIDTH,
	'z-index': 7
	},
	{ 'name': "track8",
	'color': (0.992, 0.535, 0.000),
	'width': TRACK_WIDTH,
	'z-index': 8
	},
	{ 'name': "track9",
	'color': (0.520, 0.660, 0.000),
	'width': TRACK_WIDTH,
	'z-index': 9
	},
	{ 'name': "track10",
	'color': (0.000, 0.680, 0.492),
	'width': TRACK_WIDTH,
	'z-index': 10
	},
	{ 'name': "track11",
	'color': (0.738, 0.773, 0.996),
	'width': TRACK_WIDTH,
	'z-index': 11
	},
	{ 'name': "track12",
	'color': (0.738, 0.824, 0.574),
	'width': TRACK_WIDTH,
	'z-index': 12
	},
	{ 'name': "track13",
	'color': (0.000, 0.723, 0.090),
	'width': TRACK_WIDTH,
	'z-index': 13
	},
	{ 'name': "track14",
	'color': (0.004, 0.813, 0.996),
	'width': TRACK_WIDTH,
	'z-index': 14
	},
	{ 'name': "track15",
	'color': (0.566, 0.813, 0.793),
	'width': TRACK_WIDTH,
	'z-index': 15
	},
	{ 'name': "track16",
	'color': (0.730, 0.531, 0.000),
	'width': TRACK_WIDTH,
	'z-index': 16
	},
	{ 'name': "track17",
	'color': (0.867, 0.996, 0.453),
	'width': TRACK_WIDTH,
	'z-index': 17
	},
	{ 'name': "track18",
	'color': (0.000, 0.996, 0.773),
	'width': TRACK_WIDTH,
	'z-index': 18
	},
	{ 'name': "track19",
	'color': (0.996, 0.895, 0.008),
	'width': TRACK_WIDTH,
	'z-index': 19
	},
	{ 'name': "track20",
	'color': (0.594, 0.996, 0.320),
	'width': TRACK_WIDTH,
	'z-index': 20
	},
	{ 'name': "track21",
	'color': (0.000, 0.996, 0.469),
	'width': TRACK_WIDTH,
	'z-index': 21
	},
	{ 'name': "track22",
	'color': (0.996, 0.430, 0.254),
	'width': TRACK_WIDTH,
	'z-index': 22
	},
	{ 'name': "track23",
	'color': (0.645, 0.996, 0.820),
	'width': TRACK_WIDTH,
	'z-index': 23
	},
	{ 'name': "track24",
	'color': (0.996, 0.691, 0.402),
	'width': TRACK_WIDTH,
	'z-index': 24
	},
	{ 'name': "track25",
	'color': (0.000, 0.605, 0.996),
	'width': TRACK_WIDTH,
	'z-index': 25
	},
    ]

    if len(sys.argv)<3:
      print("Usage: python MusAnimLauncher.py input.mid outputDirectory")
      sys.exit(1)
      return

    mid=sys.argv[1]

    lexer = MidiLexer()
    lexer.lex(mid)

    frames_dir = sys.argv[2]+os.sep
    os.makedirs(frames_dir)

    speed_map = [{'time': 0.0, 'speed': 4}]

    #dimensions = 426, 240
    dimensions = 720, 480
    #dimensions = 1920, 1080

    fps = 25
    #fps = 29.97

    renderer=MusAnimRenderer()
    renderer.introduction=False
    renderer.render(mid, frames_dir, tracks,
      speed_map=speed_map,
      dimensions=dimensions,
      min_pitch=lexer.minPitch-PITCH_GRACE,
      max_pitch=lexer.maxPitch+PITCH_GRACE,
      fps=fps)