Exemple #1
0
 def build(self):
     vbodata = []
     idxdata = []
     for i,g in enumerate(self.line.glyphs):
         if get_opts().instant:
             tleft = tright = g.t1
         else:
             tleft = map_to(map_from(g.x + g.glyph.left, g.tx1, g.tx2), g.t1, g.t2)
             tright = map_to(map_from(g.x + g.glyph.right, g.tx1, g.tx2), g.t1, g.t2)
         const_vbodata = [self.line.start, self.line.end]
         const_vbodata += list(i/255.0 for i in sum(g.colors + g.colors_on, ()))
         vbodata.append(
             [g.x + g.glyph.left, g.y + g.glyph.bot,
             g.glyph.tex_left, g.glyph.tex_bot,
             tleft] + const_vbodata)
         vbodata.append(
             [g.x + g.glyph.left, g.y + g.glyph.top,
             g.glyph.tex_left, g.glyph.tex_top,
             tleft] + const_vbodata)
         vbodata.append(
             [g.x + g.glyph.right, g.y + g.glyph.top,
             g.glyph.tex_right, g.glyph.tex_top,
             tright] + const_vbodata)
         vbodata.append(
             [g.x + g.glyph.right, g.y + g.glyph.bot,
             g.glyph.tex_right, g.glyph.tex_bot,
             tright] + const_vbodata)
         idxdata += (i*4, i*4+1, i*4+2, i*4+2, i*4+3, i*4)
     self.vbo = vbo.VBO(np.asarray(vbodata, np.float32), gl.GL_STATIC_DRAW, gl.GL_ARRAY_BUFFER)
     self.ibo = vbo.VBO(np.asarray(idxdata, np.uint16), gl.GL_STATIC_DRAW, gl.GL_ELEMENT_ARRAY_BUFFER)
     self.count = len(self.line.glyphs)
Exemple #2
0
    def __init__(self, display):
        self.last_audio_reconfig = 0
        self.audio_reconfig_pending = False
        self.volume = 0.5
        self.song = None
        self.display = display
        self.opts = opts = util.get_opts()
        self.mpv = mpv.Context()
        self.gl = None
        self.mpv.initialize()
        if opts.mpv_msg_level:
            self.mpv.set_property("msg-level", opts.mpv_msg_level)
        self.mpv.set_property("audio-file-auto", "no")
        self.mpv.set_property("terminal", True)
        self.mpv.set_property("quiet", True)
        if opts.mpv_ao:
            self.mpv.set_property("ao", opts.mpv_ao)
        elif opts.mpv_audio_device:
            self.mpv.set_property("audio-device", opts.mpv_audio_device)
        self.mpv.set_property("fs", True)
        if opts.mpv_ao == "jack":
            self.mpv.set_property("jack-autostart", "yes")
        self.mpv.set_property(
            "af",
            '@lavfi:lavfi="pan=stereo|c0=c0|c1=c1",@rb:rubberband=pitch=speed')
        if opts.mpv_options:
            for opt in shlex.split(opts.mpv_options):
                if "=" not in opt:
                    key, val = opt, True
                else:
                    key, val = opt.split("=", 1)
                self.mpv.set_property(key, val)
        self.poll_props = {"audio-pts": None}
        for i in self.poll_props:
            self.mpv.get_property_async(i)

        if display:
            if opts.mpv_hwdec:
                self.mpv.set_property("hwdec", opts.mpv_hwdec)
            vo = opts.mpv_vo
            if vo in ("opengl-cb", "libmpv"):
                vo = "libmpv"
                self.mpv.set_property("video-sync", "display-vdrop")
                self.mpv.set_property("display-fps", display.fps or opts.fps)

                def gpa(name):
                    return display.get_proc_address(name)

                self.gl = mpv.OpenGLRenderContext(self.mpv, gpa,
                                                  **display.get_mpv_params())
            else:
                self.gl = None
            self.mpv.set_property("vo", vo)
            self.solid_renderer = graphics.get_solid_renderer()
        else:
            self.gl = None
            self.mpv.set_property("vo", "null")
            self.mpv.set_property("vid", "no")
Exemple #3
0
def Display(*args, **kwargs):
    global _display
    display = util.get_opts().display

    if display == "glut":
        from blitzloop.backend import glut
        _display = glut.Display(*args, **kwargs)
    elif display == "rpi":
        from blitzloop.backend import rpi
        _display = rpi.Display(*args, **kwargs)
    return _display
Exemple #4
0
    def __init__(self, display):
        self.last_audio_reconfig = 0
        self.audio_reconfig_pending = False
        self.volume = 0.5
        self.song = None
        self.display = display
        self.opts = opts = util.get_opts()
        self.mpv = mpv.Context()
        self.gl = None
        self.mpv.initialize()
        if opts.mpv_msg_level:
            self.mpv.set_property("msg-level", opts.mpv_msg_level)
        self.mpv.set_property("audio-file-auto", "no")
        self.mpv.set_property("terminal", True)
        self.mpv.set_property("quiet", True)
        if opts.mpv_ao:
            self.mpv.set_property("ao", opts.mpv_ao)
        elif opts.mpv_audio_device:
            self.mpv.set_property("audio-device", opts.mpv_audio_device)
        self.mpv.set_property("fs", True)
        if opts.mpv_ao == "jack":
            self.mpv.set_property("jack-autostart", "yes")
        self.mpv.set_property("af", '@lavfi:lavfi="pan=stereo|c0=c0|c1=c1",@rb:rubberband=pitch=speed')
        if opts.mpv_options:
            for opt in shlex.split(opts.mpv_options):
                if "=" not in opt:
                    key, val = opt, True
                else:
                    key, val = opt.split("=", 1)
                self.mpv.set_property(key, val)
        self.poll_props = {"audio-pts": None}
        for i in self.poll_props:
            self.mpv.get_property_async(i)

        if display:
            if opts.mpv_hwdec:
                self.mpv.set_property("hwdec", opts.mpv_hwdec)
            vo = opts.mpv_vo
            if vo in ("opengl-cb", "libmpv"):
                vo = "libmpv"
                self.mpv.set_property("video-sync", "display-vdrop")
                self.mpv.set_property("display-fps", display.fps or opts.fps)
                def gpa(name):
                    return display.get_proc_address(name)
                self.gl = mpv.OpenGLRenderContext(self.mpv, gpa,
                                                  **display.get_mpv_params())
            else:
                self.gl = None
            self.mpv.set_property("vo", vo)
            self.solid_renderer = graphics.get_solid_renderer()
        else:
            self.gl = None
            self.mpv.set_property("vo", "null")
            self.mpv.set_property("vid", "no")
Exemple #5
0
    def toggle_fullscreen(self):
        if self.fullscreen:
            glfw.set_window_monitor(self.window, None, *self.saved_size,
                                    util.get_opts().fps)
        else:
            self.saved_size = self.x, self.y, self.win_width, self.win_height
            monitor = glfw.get_primary_monitor()
            mode = glfw.get_video_mode(monitor)
            glfw.set_window_monitor(self.window, monitor, 0, 0,
                                    mode.size.width, mode.size.height,
                                    mode.refresh_rate)

        self.fullscreen = not self.fullscreen
Exemple #6
0
    def toggle_fullscreen(self):
        if self.fullscreen:
            glfw.set_window_monitor(self.window, None, *self.saved_size,
                                    util.get_opts().fps)
        else:
            self.saved_size = self.x, self.y, self.win_width, self.win_height
            monitor = glfw.get_primary_monitor()
            mode = glfw.get_video_mode(monitor)
            glfw.set_window_monitor(self.window, monitor, 0, 0,
                                    mode.size.width, mode.size.height,
                                    mode.refresh_rate)

        self.fullscreen = not self.fullscreen
Exemple #7
0
def Display(*args, **kwargs):
    global _display
    display = util.get_opts().display

    if display == "glut":
        from blitzloop.backend import glut
        _display = glut.Display(*args, **kwargs)
    elif display == "glfw":
        from blitzloop.backend import glfw
        _display = glfw.Display(*args, **kwargs)
    elif display == "rpi":
        from blitzloop.backend import rpi
        _display = rpi.Display(*args, **kwargs)
    elif display == "kms":
        from blitzloop.backend import kms
        _display = kms.Display(*args, **kwargs)
    else:
        raise Exception("Unknown display: %s" % display)
    return _display
Exemple #8
0
    def __init__(self, display):
        self.volume = 0.5
        self.song = None
        self.display = display
        opts = util.get_opts()
        self.mpv = mpv.Context()
        self.mpv.initialize()
        self.mpv.set_property("audio-file-auto", "no")
        self.mpv.set_property("terminal", True)
        self.mpv.set_property("quiet", True)
        self.mpv.set_property("ao", opts.mpv_ao)
        self.mpv.set_property("fs", True)
        if opts.mpv_ao == "jack":
            self.mpv.set_property("jack-autostart", "yes")
        self.mpv.set_property("af", "@pan:pan=2:[1,0,0,1],@rb:rubberband")
        for optval in opts.mpv_options.split():
            opt, val = optval.split("=", 1)
            self.mpv.set_property(opt, val)
        self.poll_props = {"audio-pts": None}
        for i in self.poll_props:
            self.mpv.get_property_async(i)

        if display:
            if opts.mpv_vo == "opengl-cb":
                self.mpv.set_property("video-sync", "display-vdrop")
                self.mpv.set_property("display-fps", opts.fps)

                def gpa(name):
                    return display.get_proc_address(name)

                self.gl = self.mpv.opengl_cb_api()
                self.gl.init_gl(None, gpa)
            else:
                self.gl = None
            self.mpv.set_property("vo", opts.mpv_vo)
            self.solid_renderer = graphics.get_solid_renderer()
        else:
            self.gl = None
            self.mpv.set_property("vo", "null")
            self.mpv.set_property("vid", "no")
Exemple #9
0
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

import numpy as np
import PIL

from OpenGL import arrays
from OpenGL.arrays import vbo

from blitzloop import texture_font
from blitzloop.util import map_from, map_to, get_opts
from blitzloop.matrix import Matrix

if get_opts().display in ("glut", ):
    import OpenGL.GL as gl
    import OpenGL.GL.shaders as shaders
    import OpenGL.GLU as glu
else:
    import OpenGL.GLES2 as gl
    import OpenGL.GLES2.shaders as shaders
    glu = None

vs_karaoke = """
attribute vec4 coords;

attribute vec3 border_color;
attribute vec3 fill_color;
attribute vec3 outline_color;
attribute vec3 border_color_on;
Exemple #10
0
def entry():
    data_home = os.getenv('XDG_DATA_HOME', '~/.local/share')
    songs_dir = os.path.join(data_home, 'blitzloop', 'songs')

    def csv_list(s):
        return s.split(",")

    parser = util.get_argparser()
    parser.add_argument(
        '--songdir', default=os.path.expanduser(songs_dir),
        help='directory with songs')
    parser.add_argument('--host', default='0.0.0.0', help='IP to listen on')
    parser.add_argument(
        '--port', default=10111, type=int,
        help='port for the UI')
    parser.add_argument(
        '--width', type=int, default=1024,
        help='width of blitzloop window (ignored in fs)')
    parser.add_argument(
        '--height', type=int, default=768,
        help='height of blitzloop window (ignored in fs)')
    parser.add_argument(
        '--no-audioengine', action="store_true",
        help='Disable JACK-based audio engine (mic echo effect)')
    parser.add_argument(
        '--mics', type=csv_list, default=["system:capture_1"],
        help='Mic input connections (list of JACK ports)')
    opts = util.get_opts()

    songs_dir = os.path.expanduser(opts.songdir)

    print("Loading song DB...")
    song_database = songlist.SongDatabase(songs_dir)
    print("Done.")

    display = graphics.Display(opts.width, opts.height, opts.fullscreen)
    renderer = graphics.get_renderer().KaraokeRenderer(display)
    mpv = mpvplayer.Player(display)

    if not opts.no_audioengine and opts.mics:
        from blitzloop._audio import AudioEngine
        print(repr(opts.mics))
        audio = AudioEngine([s.encode("ascii") for s in opts.mics])
        print("Engine sample rate: %dHz" % audio.sample_rate)

    queue = songlist.SongQueue()

    class AudioConfig(object):
        def __init__(self):
            self.nmics = len(opts.mics) if not opts.no_audioengine else 0
            self.volume = 80
            if opts.no_audioengine:
                self.mic_channels = []
            else:
                self.mic_channels = [{"volume": 80} for i in range(self.nmics)]
            self.mic_feedback = 20
            self.mic_delay = 12
            self.headstart = 30

        def update(self, song=None):
            mpv.set_volume(((self.volume / 100.0) ** 2) * 0.5)
            if not opts.no_audioengine:
                for i, j in enumerate(self.mic_channels):
                    audio.set_mic_volume(i, ((j["volume"] / 100.0) ** 2) * 2.0)
                audio.set_mic_feedback(self.mic_feedback / 100.0)
                audio.set_mic_delay(self.mic_delay / 100.0)

    audio_config = AudioConfig()

    web.database = song_database
    web.queue = queue
    web.audio_config = audio_config
    server = web.ServerThread(host=opts.host, port=opts.port)
    server.start()

    idle_screen = idlescreen.IdleScreen(display)

    def main_render():
        # Wait for element in queue
        print("Waiting for song to appear in queue...")
        qe = None
        with queue.lock:
            if len(queue) != 0:
                qe = queue[0]
        if not qe:
            idle_screen.reset()
            graphics.get_renderer().clear(0, 0, 0, 1)
            for f in idle_screen:
                audio_config.update()
                yield None
                graphics.get_renderer().clear(0, 0, 0, 1)
                if not qe:
                    with queue.lock:
                        if len(queue) != 0:
                            qe = queue[0]
                            idle_screen.close()

        for i in range(2):
            yield None
            graphics.get_renderer().clear(0, 0, 0, 1)

        print("Loading audio/video...")
        mpv.load_song(qe.song)
        display.set_aspect(mpv.aspect)

        def update_params(defer=False):
            mpv.set_speed(1.0 / (2**(qe.speed / 12.0)))
            mpv.set_pitch(2**(qe.pitch / 12.0))
            for i, j in enumerate(qe.channels):
                mpv.set_channel(i, j["volume"] / 10., defer=defer)
            mpv.set_pause(qe.pause)

        update_params(True)
        mpv.update_mixer(force=True)

        print("Laying out song...")
        renderer.reset()
        variant_key = list(qe.song.variants.keys())[qe.variant]
        song_layout = layout.SongLayout(qe.song, variant_key, renderer)
        print("Loaded.")

        song_time = -10
        stopping = False
        while not (mpv.eof_reached() or (stopping and qe.pause)):
            while qe.commands:
                cmd, arg = qe.commands.pop(0)
                if cmd == "seek":
                    mpv.seek(arg)
                elif cmd == "seekto":
                    mpv.seek_to(arg)
            mpv.draw()
            mpv.poll()
            song_time = mpv.get_song_time() or song_time

            if qe.stop and not stopping:
                stopping = True
                mpv.fade_out = 2
                mpv.duration = min(mpv.duration, song_time + 2)

            if not stopping:
                mpv.draw_fade(song_time)

            speed = 2**(qe.speed / 12.0)
            renderer.draw(song_time + audio_config.headstart / 100.0 * speed,
                          song_layout)

            if stopping:
                fade = mpv.draw_fade(song_time)
                mpv.set_fadevol(max(fade * 1.3 - 0.3, 0))

            update_params()
            audio_config.update(qe.song)
            yield None
            mpv.flip()

        graphics.get_renderer().clear(0, 0, 0, 1)
        for i in range(2):
            yield None
            graphics.get_renderer().clear(0, 0, 0, 1)

        print("Song complete.")
        del song_layout
        try:
            queue.pop(qe.qid)
        except (IndexError, KeyError):
            pass
        mpv.stop()
        display.set_aspect(None)

    def main():
        while True:
            for i in main_render():
                yield i

    def exit():
        print("Exit handler called")
        mpv.shutdown()
        if not opts.no_audioengine:
            audio.shutdown()
        server.stop()
        print("Exit handler done")

    def key(k):
        if k == 'KEY_ESCAPE':
            display.queue_exit()
        elif k == 'f':
            display.toggle_fullscreen()

    display.set_render_gen(main)
    display.set_keyboard_handler(key)
    display.set_exit_handler(exit)
    display.main_loop()
    threads = threading.enumerate()
    if len(threads) > 1:
        print("Loose threads: %r" % threads)
Exemple #11
0
parser.add_argument('--width',
                    type=int,
                    default=1024,
                    help='width of blitzloop window (ignored in fs)')
parser.add_argument('--height',
                    type=int,
                    default=768,
                    help='height of blitzloop window (ignored in fs)')
parser.add_argument('--no-audioengine',
                    action="store_true",
                    help='Disable JACK-based audio engine (mic echo effect)')
parser.add_argument('--mics',
                    type=csv_list,
                    default=["system:capture_1"],
                    help='Mic input connections (list of JACK ports)')
opts = util.get_opts()

songs_dir = os.path.expanduser(opts.songdir)

print("Loading song DB...")
song_database = songlist.SongDatabase(songs_dir)
print("Done.")

display = graphics.Display(opts.width, opts.height, opts.fullscreen)
renderer = graphics.get_renderer().KaraokeRenderer(display)
mpv = mpvplayer.Player(display)

if not opts.no_audioengine and opts.mics:
    print(repr(opts.mics))
    audio = AudioEngine([s.encode("ascii") for s in opts.mics])
    print("Engine sample rate: %dHz" % audio.sample_rate)
Exemple #12
0
def entry():
    parser = util.get_argparser()
    parser.add_argument('songpath',
                        metavar='SONGPATH',
                        help='path to the song file')
    parser.add_argument('--show-timings',
                        dest='st',
                        action='store_true',
                        help='show mpv timings')
    parser.add_argument('--offset',
                        type=float,
                        default=0.0,
                        help='song offset')
    parser.add_argument('--variant', type=int, default=0, help='song variant')
    opts = util.get_opts()

    fullscreen = opts.fullscreen
    s = song.Song(opts.songpath)

    headstart = 0.3

    if fullscreen:
        display = graphics.Display(1920, 1200, fullscreen, None)
    else:
        display = graphics.Display(1280, 720, fullscreen, None)
    print(display.width, display.height)

    mpv = mpvplayer.Player(display)
    mpv.load_song(s)

    display.set_aspect(mpv.aspect)

    renderer = graphics.get_renderer().KaraokeRenderer(display)
    song_layout = layout.SongLayout(s,
                                    list(s.variants.keys())[opts.variant],
                                    renderer)

    song_time = -10

    speed_i = 0
    pitch_i = 0
    channels_i = s.channel_defaults

    for idx, val in enumerate(channels_i):
        mpv.set_channel(idx, val / 10.0)

    if opts.offset:
        mpv.seek_to(opts.offset)

    def render():
        t = time.time()
        nonlocal song_time
        while not mpv.eof_reached():
            graphics.get_renderer().clear(0, 0, 0, 1)
            t1 = time.time()
            mpv.draw()
            dt = time.time() - t1
            mpv.poll()
            song_time = mpv.get_song_time() or song_time
            mpv.draw_fade(song_time)
            renderer.draw(song_time + headstart * 2**(speed_i / 12.0),
                          song_layout)
            yield None
            t2 = time.time()
            if opts.st:
                print("T:%7.3f/%7.3f B:%7.3f FPS:%.2f draw:%.3f" %
                      (song_time, mpv.duration, s.timing.time2beat(song_time),
                       (1.0 / (t2 - t)), dt))
            t = t2
            mpv.flip()
        mpv.shutdown()
        os._exit(0)

    pause = False

    CH_UP = "+456"
    CH_DOWN = "-123"

    def key(k):
        nonlocal speed_i, pitch_i, pause
        if k == 'KEY_ESCAPE':
            mpv.shutdown()
            os._exit(0)
        elif k == 'f':
            display.toggle_fullscreen()
        elif k == '[' and speed_i > -12:
            speed_i -= 1
            print("Speed: %d" % speed_i)
            mpv.set_speed(2**(-speed_i / 12.0))
        elif k == ']' and speed_i < 12:
            speed_i += 1
            print("Speed: %d" % speed_i)
            mpv.set_speed(2**(-speed_i / 12.0))
        elif k == 'KEY_UP' and pitch_i < 12:
            pitch_i += 1
            print("Pitch: %d" % pitch_i)
            mpv.set_pitch(2**(pitch_i / 12.0))
        elif k == 'KEY_DOWN' and pitch_i > -12:
            pitch_i -= 1
            print("Pitch: %d" % pitch_i)
            mpv.set_pitch(2**(pitch_i / 12.0))
        elif k in CH_UP:
            idx = CH_UP.index(k)
            if len(channels_i) > idx and channels_i[idx] < 30:
                channels_i[idx] += 1
                print("Channel %d: %d" % (idx, channels_i[idx]))
                mpv.set_channel(idx, channels_i[idx] / 10.0)
        elif k in CH_DOWN:
            idx = CH_DOWN.index(k)
            if len(channels_i) > idx and channels_i[idx] > 0:
                channels_i[idx] -= 1
                print("Channel %d: %d" % (idx, channels_i[idx]))
                mpv.set_channel(idx, channels_i[idx] / 10.0)
        elif k == 'KEY_LEFT':
            mpv.seek(-10)
        elif k == 'KEY_RIGHT':
            mpv.seek(10)
        elif k == ' ':
            pause = not pause
            t = time.time()
            mpv.set_pause(pause)
            print("P %.03f" % (time.time() - t))

    mpv.play()
    display.set_render_gen(render)
    display.set_keyboard_handler(key)
    display.main_loop()
    mpv.shutdown()
Exemple #13
0
def entry():
    parser = util.get_argparser()
    parser.add_argument(
        'songpath', metavar='SONGPATH', help='path to the song file')
    parser.add_argument(
        '--show-timings', dest='st', action='store_true',
        help='show mpv timings')
    parser.add_argument(
        '--offset', type=float, default=0.0, help='song offset')
    parser.add_argument(
        '--variant', type=int, default=0, help='song variant')
    opts = util.get_opts()

    fullscreen = opts.fullscreen
    s = song.Song(opts.songpath)

    headstart = 0.3

    if fullscreen:
        display = graphics.Display(1920, 1200, fullscreen, None)
    else:
        display = graphics.Display(1280, 720, fullscreen, None)
    print(display.width, display.height)

    mpv = mpvplayer.Player(display)
    mpv.load_song(s)

    display.set_aspect(mpv.aspect)

    renderer = graphics.get_renderer().KaraokeRenderer(display)
    song_layout = layout.SongLayout(s, list(s.variants.keys())[opts.variant], renderer)

    song_time = -10

    speed_i = 0
    pitch_i = 0
    channels_i = s.channel_defaults

    for idx, val in enumerate(channels_i):
        mpv.set_channel(idx, val / 10.0)

    if opts.offset:
        mpv.seek_to(opts.offset)

    def render():
        t = time.time()
        nonlocal song_time
        while not mpv.eof_reached():
            graphics.get_renderer().clear(0, 0, 0, 1)
            t1 = time.time()
            mpv.draw()
            dt = time.time() - t1
            mpv.poll()
            song_time = mpv.get_song_time() or song_time
            mpv.draw_fade(song_time)
            renderer.draw(song_time + headstart * 2**(speed_i/12.0), song_layout)
            yield None
            t2 = time.time()
            if opts.st:
                print("T:%7.3f/%7.3f B:%7.3f FPS:%.2f draw:%.3f" % (song_time, mpv.duration, s.timing.time2beat(song_time), (1.0/(t2-t)), dt))
            t = t2
            mpv.flip()
        mpv.shutdown()
        os._exit(0)

    pause = False

    CH_UP = "+456"
    CH_DOWN = "-123"

    def key(k):
        nonlocal speed_i, pitch_i, pause
        if k == 'KEY_ESCAPE':
            mpv.shutdown()
            os._exit(0)
        elif k == 'f':
            display.toggle_fullscreen()
        elif k == '[' and speed_i > -12:
            speed_i -= 1
            print("Speed: %d" % speed_i)
            mpv.set_speed(2**(-speed_i/12.0))
        elif k == ']' and speed_i < 12:
            speed_i += 1
            print("Speed: %d" % speed_i)
            mpv.set_speed(2**(-speed_i/12.0))
        elif k == 'KEY_UP' and pitch_i < 12:
            pitch_i += 1
            print("Pitch: %d" % pitch_i)
            mpv.set_pitch(2**(pitch_i/12.0))
        elif k == 'KEY_DOWN' and pitch_i > -12:
            pitch_i -= 1
            print("Pitch: %d" % pitch_i)
            mpv.set_pitch(2**(pitch_i/12.0))
        elif k in CH_UP:
            idx = CH_UP.index(k)
            if len(channels_i) > idx and channels_i[idx] < 30:
                channels_i[idx] += 1
                print("Channel %d: %d" % (idx, channels_i[idx]))
                mpv.set_channel(idx, channels_i[idx]/10.0)
        elif k in CH_DOWN:
            idx = CH_DOWN.index(k)
            if len(channels_i) > idx and channels_i[idx] > 0:
                channels_i[idx] -= 1
                print("Channel %d: %d" % (idx, channels_i[idx]))
                mpv.set_channel(idx, channels_i[idx]/10.0)
        elif k == 'KEY_LEFT':
            mpv.seek(-10)
        elif k == 'KEY_RIGHT':
            mpv.seek(10)
        elif k == ' ':
            pause = not pause
            t = time.time()
            mpv.set_pause(pause)
            print("P %.03f" % (time.time()-t))

    mpv.play()
    display.set_render_gen(render)
    display.set_keyboard_handler(key)
    display.main_loop()
    mpv.shutdown()
Exemple #14
0
import sys

from blitzloop import graphics, layout, mpvplayer, song, util


parser = util.get_argparser()
parser.add_argument(
    'songpath', metavar='SONGPATH', help='path to the song file')
parser.add_argument(
    'quant', metavar='QUANT', type=int, help='quantization of the song')
parser.add_argument(
    '--speed', default=1.0, type=float, help='divisor of the audio speed')
parser.add_argument(
    '--position', default=0.0, type=float,
    help='starting position in the song, in seconds')
opts = util.get_opts()

s = song.Song(opts.songpath, ignore_steps=True)
display = graphics.Display(1280,720)
renderer = graphics.get_renderer().KaraokeRenderer(display)
layout = layout.SongLayout(s, list(s.variants.keys())[-1], renderer)

step = 0

cur_beat = 0

compound = None
compounds = iter(s.compounds)

mpv = mpvplayer.Player(None)
mpv.load_song(s)
Exemple #15
0
def entry():
    data_home = os.getenv('XDG_DATA_HOME', '~/.local/share')
    songs_dir = os.path.join(data_home, 'blitzloop', 'songs')

    def csv_list(s):
        return s.split(",")

    parser = util.get_argparser()
    parser.add_argument('--songdir',
                        default=os.path.expanduser(songs_dir),
                        help='directory with songs')
    parser.add_argument('--host', default='0.0.0.0', help='IP to listen on')
    parser.add_argument('--port',
                        default=10111,
                        type=int,
                        help='port for the UI')
    parser.add_argument('--width',
                        type=int,
                        default=1024,
                        help='width of blitzloop window (ignored in fs)')
    parser.add_argument('--height',
                        type=int,
                        default=768,
                        help='height of blitzloop window (ignored in fs)')
    parser.add_argument(
        '--no-audioengine',
        action="store_true",
        help='Disable JACK-based audio engine (mic echo effect)')
    parser.add_argument('--mics',
                        type=csv_list,
                        default=["system:capture_1"],
                        help='Mic input connections (list of JACK ports)')
    opts = util.get_opts()

    songs_dir = os.path.expanduser(opts.songdir)

    print("Loading song DB...")
    song_database = songlist.SongDatabase(songs_dir)
    print("Done.")

    display = graphics.Display(opts.width, opts.height, opts.fullscreen)
    renderer = graphics.get_renderer().KaraokeRenderer(display)
    mpv = mpvplayer.Player(display)

    if not opts.no_audioengine and opts.mics:
        from blitzloop._audio import AudioEngine
        print(repr(opts.mics))
        audio = AudioEngine([s.encode("ascii") for s in opts.mics])
        print("Engine sample rate: %dHz" % audio.sample_rate)

    queue = songlist.SongQueue()

    class AudioConfig(object):
        def __init__(self):
            self.nmics = len(opts.mics) if not opts.no_audioengine else 0
            self.volume = 80
            if opts.no_audioengine:
                self.mic_channels = []
            else:
                self.mic_channels = [{"volume": 80} for i in range(self.nmics)]
            self.mic_feedback = 20
            self.mic_delay = 12
            self.headstart = 30

        def update(self, song=None):
            mpv.set_volume(((self.volume / 100.0)**2) * 0.5)
            if not opts.no_audioengine:
                for i, j in enumerate(self.mic_channels):
                    audio.set_mic_volume(i, ((j["volume"] / 100.0)**2) * 2.0)
                audio.set_mic_feedback(self.mic_feedback / 100.0)
                audio.set_mic_delay(self.mic_delay / 100.0)

    audio_config = AudioConfig()

    web.database = song_database
    web.queue = queue
    web.audio_config = audio_config
    server = web.ServerThread(host=opts.host, port=opts.port)
    server.start()

    idle_screen = idlescreen.IdleScreen(display)

    def main_render():
        # Wait for element in queue
        print("Waiting for song to appear in queue...")
        qe = None
        with queue.lock:
            if len(queue) != 0:
                qe = queue[0]
        if not qe:
            idle_screen.reset()
            graphics.get_renderer().clear(0, 0, 0, 1)
            for f in idle_screen:
                audio_config.update()
                yield None
                graphics.get_renderer().clear(0, 0, 0, 1)
                if not qe:
                    with queue.lock:
                        if len(queue) != 0:
                            qe = queue[0]
                            idle_screen.close()

        for i in range(2):
            yield None
            graphics.get_renderer().clear(0, 0, 0, 1)

        print("Loading audio/video...")
        mpv.load_song(qe.song)
        display.set_aspect(mpv.aspect)

        def update_params(defer=False):
            mpv.set_speed(1.0 / (2**(qe.speed / 12.0)))
            mpv.set_pitch(2**(qe.pitch / 12.0))
            for i, j in enumerate(qe.channels):
                mpv.set_channel(i, j["volume"] / 10., defer=defer)
            mpv.set_pause(qe.pause)

        update_params(True)
        mpv.update_mixer(force=True)

        print("Laying out song...")
        renderer.reset()
        variant_key = list(qe.song.variants.keys())[qe.variant]
        song_layout = layout.SongLayout(qe.song, variant_key, renderer)
        print("Loaded.")

        song_time = -10
        stopping = False
        while not (mpv.eof_reached() or (stopping and qe.pause)):
            while qe.commands:
                cmd, arg = qe.commands.pop(0)
                if cmd == "seek":
                    mpv.seek(arg)
                elif cmd == "seekto":
                    mpv.seek_to(arg)
            mpv.draw()
            mpv.poll()
            song_time = mpv.get_song_time() or song_time

            if qe.stop and not stopping:
                stopping = True
                mpv.fade_out = 2
                mpv.duration = min(mpv.duration, song_time + 2)

            if not stopping:
                mpv.draw_fade(song_time)

            speed = 2**(qe.speed / 12.0)
            renderer.draw(song_time + audio_config.headstart / 100.0 * speed,
                          song_layout)

            if stopping:
                fade = mpv.draw_fade(song_time)
                mpv.set_fadevol(max(fade * 1.3 - 0.3, 0))

            update_params()
            audio_config.update(qe.song)
            yield None
            mpv.flip()

        graphics.get_renderer().clear(0, 0, 0, 1)
        for i in range(2):
            yield None
            graphics.get_renderer().clear(0, 0, 0, 1)

        print("Song complete.")
        del song_layout
        try:
            queue.pop(qe.qid)
        except (IndexError, KeyError):
            pass
        mpv.stop()
        display.set_aspect(None)

    def main():
        while True:
            for i in main_render():
                yield i

    def exit():
        print("Exit handler called")
        mpv.shutdown()
        if not opts.no_audioengine:
            audio.shutdown()
        server.stop()
        print("Exit handler done")

    def key(k):
        if k == 'KEY_ESCAPE':
            display.queue_exit()
        elif k == 'f':
            display.toggle_fullscreen()

    display.set_render_gen(main)
    display.set_keyboard_handler(key)
    display.set_exit_handler(exit)
    display.main_loop()
    threads = threading.enumerate()
    if len(threads) > 1:
        print("Loose threads: %r" % threads)
Exemple #16
0
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA

import numpy as np
import PIL

from OpenGL import arrays
from OpenGL.arrays import vbo

from blitzloop import texture_font
from blitzloop.util import map_from, map_to, get_opts
from blitzloop.matrix import Matrix

if get_opts().display in ("glut",):
    import OpenGL.GL as gl
    import OpenGL.GL.shaders as shaders
    import OpenGL.GLU as glu
else:
    import OpenGL.GLES2 as gl
    import OpenGL.GLES2.shaders as shaders
    glu = None


vs_karaoke = """
attribute vec4 coords;

attribute vec3 border_color;
attribute vec3 fill_color;
attribute vec3 outline_color;