Example #1
0
def other_end():    
    db_install_callbacks()

    init_data_channels('frontend')
    
    ui_in = readchild
    ui_out = writeparent

    backend = subprocess.Popen(backend_path,\
               shell=True, stdin=subprocess.PIPE,\
                stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    backend_in = backend.stdout
    backend_out = backend.stdin
    backend_info = backend.stderr

    fcntl.fcntl(backend_in,fcntl.F_SETFL,os.O_NONBLOCK)
    fcntl.fcntl(backend_info,fcntl.F_SETFL,os.O_NONBLOCK)

    global_vars = DfGlobal()

    set_default_snippets()

    console = DfInterpreter(global_vars,__main__.__dict__)

    global_vars["asynchroneous_parameters"] = {}
    global_vars["asynchroneous_parameters_id"] = 1
    global_vars["reinitialize_generators"] = reinitialize_generators
    global_vars["ui_out"] = ui_out
    global_vars["out"] = backend_out
    global_vars["ui_in"] = ui_in
    global_vars["in"] = backend_in
    global_vars["log"] = backend_info
    global_vars["interactive_python"] = console
    global_vars["drop_nows"] = 0
    global_vars["@now"] = 0.0
    global_vars["output_rate"] = 1.0
    global_vars["loop-depth"] = 0 # This is the depth of nested main_loops
    global_vars["save-loop-depth"] = 1
    global_vars["DfInterpreter.console"] = console
    global_vars["keyboard-queue"] = []
    global_vars["root.call"] = [] # list of callees
    global_vars["timer.calls"] = [] # (@now-time, callee, identifier) list
    global_vars["hud.interaction"] = False # true if hud interaction is on
    init_hud_interaction_globals()
    #reinitialize_generators()

    global_vars["sleep_amount"] = 1.0/50.0
    global_vars["regenerate_instruments"] = 0
    global_vars["current_command"] = ""
    sout = sys.stdout
    serr = sys.stderr
    sys.stdout = console
    sys.stderr = console
    console.runsource("print 'drums-frontend interactive Python shell'")
    sys.stdout = sout
    sys.stderr = serr


    def pad(x,y,p):
       if (len(x)<y):
          return p*(y-len(x)) + x
       else:
          return x
          
    global_vars["data_send_channel"] = ui_out

    def do_compile_command(cmd):
        try:
            co = code.compile_command(cmd,"<input>","exec")
        except:
            co = cmd
        return co

    def do_run_code(co,string=""):
        """ return True on error.... (via showtraceback) """
        if co:
            console = DfGlobal()["interactive_python"]
            sys.stdout = console
            sys.stderr = console
            console.runcode(co)
            traced = console.hasTracebacked()
            if traced and string:
                if g('show.code',True):
                    print "CODE FOLLOWS:\n<<<\n",string,"\n>>>\n"
            sys.stdout = sout
            sys.stderr = serr
            return traced
        else:
            return False
                
        
    def python_input(line):
        line += "\n"
        gl = DfGlobal()
        old_lines = gl["current_command"]
        nbr_spaces = count_ws(line)
        if nbr_spaces > 0:
            gl["current_command"] = old_lines + line
        else:
            oldcode = do_compile_command(old_lines)
            do_run_code(oldcode)
            newcode = do_compile_command(line)
            if newcode:
                do_run_code(newcode)
                gl["current_command"] = ""
            else:
                gl["current_command"] = line
        if gl["current_command"]:
            send_line("PYTHON","(continue)")
        

    def python_bounce(lines):
        gl = DfGlobal()
        gl["current_bounce"] = ""
        lines = eval(lines) + "\n\n"
        def runner(line):
            line += "\n"
            old_lines = gl["current_bounce"]
            nbr_spaces = count_ws(line)
            if nbr_spaces > 0:
                gl["current_bounce"] = old_lines + line
                return True
            else:
                oldcode = do_compile_command(old_lines)
                if not do_run_code(oldcode,old_lines):
                    newcode = do_compile_command(line)
                    if newcode:
                        gl["current_bounce"] = ""                        
                        if not do_run_code(newcode,line):
                            return True
                        else:
                            return False
                    else:
                        gl["current_bounce"] = line
                        return True
                else:
                    return False

        do_echo = gl("bounce.echo",False)
        
        for part in lines.split("\n"):
            stripped = part.strip()
            if stripped or gl["current_bounce"].endswith('\\\n'):
                if do_echo:
                    send_line("PYTHON'","] "+part)                
                if not runner(part):
                    break
                
        if gl["current_bounce"]:
            cmd = gl["current_bounce"] + "\n"
            code = do_compile_command(cmd)
            do_run_code(code,cmd)
            
            

    def OLDpython_bounce(lines):
        global_vars = DfGlobal()
        global_vars["current_bounce"] = ""
        lines = eval(lines) + "\n\n"
        #print "BOUNCED LINES=",lines
        def runner(line):
            line = line + "\n"
            global_vars["current_bounce"] = global_vars["current_bounce"] + line
            console = global_vars["interactive_python"]
            ui_out = global_vars["ui_out"]
            retval = True
            if ((count_ws(global_vars["current_bounce"]) >= count_ws(line)) \
                & (not line.endswith("\\\n"))):
                try:
                    co = code.compile_command(global_vars["current_bounce"],"<input>","exec")
                except:
                    co = 1
                    retval = False
            else:
                co = 0
            if co:
                sys.stdout = console
                sys.stderr = console
                console.runsource(global_vars["current_bounce"])
                sys.stdout = sout
                sys.stderr = serr
                if not global_vars["current_bounce"].strip():
                    retval = True
                global_vars["current_bounce"] = ""
                return retval
            else:
                return True
        
        for part in lines.split("\n"):
            send_line("PYTHON'","ext> "+part)
            if not runner(part):
                print "DO NOT CONTINUE FOR", part
                break

    DfGlobal()["python.bouncer.fn"] = python_bounce

    add_data_channel_handler("PYTHON",python_input)
    add_data_channel_handler("PYTHONBOUNCE",python_bounce)

    DfGlobal()["broken.line.start.ui"] = ""
    DfGlobal()["broken.line.start.backend"] = ""
    DfGlobal()["broken.line.input.backendinfo"] = ""

    DfGlobal()["no-waste-time"] = False
    DfGlobal()["default.depth"] = 8
    DfGlobal()["default.steps"] = 8


    def main_wait_for_input():
       global_vars = DfGlobal()
       backend_out = global_vars["out"]
       backend_in = global_vars["in"]
       backend_info = global_vars["log"]
       ui_out = global_vars["ui_out"]
       ui_in = global_vars["ui_in"]
       global_vars["loop-depth"] += 1
       for loop_idx in range(32):
           if global_vars["no-waste-time"]:
               do_sleep = -1
           else:
               do_sleep = 1           
           try:
              #line = ui_in.readline()
              line = my_readline(ui_in)
              if (len(line)==0):
                 global_vars["loop-depth"] -= 1
                 return -1
              do_sleep = 0
              line = global_vars["broken.line.start.ui"] + line
              if line.endswith('\n'):
                  global_vars["broken.line.start.ui"] = ""
                  if line.startswith("CONSOLE:"):
                     backend_out.write(line[8:])
                     print " >>> ", line[8:].strip()
                     backend_out.flush()
                  elif line == "MEASURED!\n":
                     initialize_measures()
                  elif line == "REGENERATE-INSTRUMENTS!\n":
                     global_vars["regenerate_instruments"] = 1
                     global_vars["reinitialize_generators"]()
                  else:
                      handle_read_line(line[0:len(line)-1])
              else:
                  print " ___ caught over-long line from ui_in"
                  global_vars["broken.line.start.ui"] = line

           except IOError, err:
              if (err.errno != errno.EWOULDBLOCK):
                 print "Error communicating with user-interface: ",err
                 global_vars["loop-depth"] -= 1
                 return -1

           try:
              #line = backend_in.readline()
              line = my_readline(backend_in)
              if (len(line)==0):
                 global_vars["loop-depth"] -= 1
                 return -1
              do_sleep = 0
              line = global_vars["broken.line.start.backend"] + line
              if line.endswith('\n'):
                  global_vars["broken.line.start.backend"] = ""
                  if (not line.startswith("@now ")) \
                  and (not line.startswith("@sid "))\
                  and (not line.startswith("@caching "))\
                  and (not line.startswith("@id "))\
                  and (not line.startswith("@ml_")):
                     print " <*> ", line.strip()
                     ui_out.write("CONSOLE: <*> "+line)
                     ui_out.flush()
                  line = line[0:len(line)-1]
                  if line.startswith("@"):
                     if ' ' in line:
                        varname = line[0:line.index(' ')]
                        varvalue = line[line.index(' ')+1:]
                        if varname == "@now":
                           varvalue = float(varvalue)
                           timer_calls = global_vars["timer.calls"]
                           while timer_calls:
                               head = timer_calls[0][0]
                               if head <= varvalue:
                                   add_root_call(timer_calls.pop(0)[1])
                               else:
                                   break                           
                     else:
                        varname = line
                        varvalue = ""
                     global_vars[varname] = varvalue

                  if line.startswith("@main_start"):
                     initialize_backend()
                     ui_out.write("CHANNUM:"+str(global_vars["sampler_channels"])+"\n")
                     ui_out.flush();
                     initialize_new_technology()
                  elif line.startswith("@now "):
                     global_vars["@now-callback"]()
                     global_vars["drop_nows"] += 1
                     if (global_vars["drop_nows"] == 25):
                        stime = int(global_vars["@now"])/int(global_vars["output_rate"])
                        mtime = int(stime/60)
                        htime = int(mtime/60)
                        mtime = mtime % 60
                        stime = stime % 60
                        timestr = str(htime)+"h"+pad(str(mtime),2,'0')+"'"+pad(str(stime),2,'0')+'"'
                        ui_out.write("SAMPLER-TIME:"+timestr+"\n")
                        ui_out.flush()
                        global_vars["drop_nows"] = 0
                        backend_out.write("mlinfo\n")
                        backend_out.flush()
                  elif line.startswith("@ml_meter "):
                     meter = map(float, line[10:].split(" "))
                     l10 = log(10.0)
                     def safe_calc_meter_value(x):
                        try:
                           if x > 0.0:
                              val = int(round(10.0*log(x)/l10))
                           else:
                              val = -100.0
                        except OverflowError:
                           val = -100.0
                        return val

                     meter = map(safe_calc_meter_value, meter)
                     mstring = "["
                     for m in meter:
                        if (m <= -100):
                           sm = "-99"
                        else:
                           sm = str(m)
                           if (len(sm)<3):
                              sm = " "*(3-len(sm))+sm
                        mstring = mstring + sm +","

                     mstring = mstring[0:len(mstring)-1] + "]dB"
                     ui_out.write("MASTER-METER:"+mstring+"\n")
                     ui_out.flush()
                  elif line.startswith("@ml_current_gain "):
                     meter = map(float, line[17:].split(" "))
                     l10 = log(10.0)
                     try:
                        meter = map(lambda x: int(round(20.0*log(x)/l10)) , meter)
                     except OverflowError:
                        meter = map(lambda x: 0, meter)
                     mstring = "["
                     for m in meter:
                        sm = str(m)
                        if (len(sm)<3):
                           sm = " "*(3-len(sm))+sm
                        mstring = mstring + sm +","

                     mstring = mstring[0:len(mstring)-1] + "]dB"
                     ui_out.write("MASTER-GAIN:"+mstring+"\n")
                     ui_out.flush()
              else:
                  print " ___ caught over-long line from backend_in"
                  global_vars["broken.line.start.backend"] = line

           except IOError, err:
              if (err.errno != errno.EWOULDBLOCK):
                 print "Error communicating with backend: ", err
                 global_vars["loop-depth"] -= 1
                 return -1
           try:
              #line = backend_info.readline()
              line = global_vars["broken.line.input.backendinfo"] + my_readline(backend_info)
              if (len(line)==0):
                 global_vars["loop-depth"] -= 1
                 return -1
              if line.endswith("\n"):
                  global_vars["broken.line.input.backendinfo"] = ""
                  do_sleep = 0
                  ui_out.write("CONSOLE: *** "+line)
                  ui_out.flush()
                  print " *** ",line.strip()
              else:
                  global_vars["broken.line.input.backendinfo"] = line
           except IOError:
              pass

           if handle_keyboard_if_root():
               do_sleep = 0
               
           if run_root_call():
               do_sleep = 0
               
           if do_sleep>0:
              #time.sleep(global_vars["sleep_amount"])
              # we now use select
              waiting_for = [ui_in,backend_in,backend_info]
              select.select(waiting_for,[],waiting_for,global_vars["sleep_amount"])
              break
           elif do_sleep<0:
              break
Example #2
0
    def main_wait_for_input():
       global_vars = DfGlobal()
       backend_out = global_vars["out"]
       backend_in = global_vars["in"]
       backend_info = global_vars["log"]
       ui_out = global_vars["ui_out"]
       ui_in = global_vars["ui_in"]
       global_vars["loop-depth"] += 1
       for loop_idx in range(32):
           if global_vars["no-waste-time"]:
               do_sleep = -1
           else:
               do_sleep = 1           
           try:
              #line = ui_in.readline()
              line = my_readline(ui_in)
              if (len(line)==0):
                 global_vars["loop-depth"] -= 1
                 return -1
              do_sleep = 0
              line = global_vars["broken.line.start.ui"] + line
              if line.endswith('\n'):
                  global_vars["broken.line.start.ui"] = ""
                  if line.startswith("CONSOLE:"):
                     backend_out.write(line[8:])
                     print " >>> ", line[8:].strip()
                     backend_out.flush()
                  elif line == "MEASURED!\n":
                     initialize_measures()
                  elif line == "REGENERATE-INSTRUMENTS!\n":
                     global_vars["regenerate_instruments"] = 1
                     global_vars["reinitialize_generators"]()
                  else:
                      handle_read_line(line[0:len(line)-1])
              else:
                  print " ___ caught over-long line from ui_in"
                  global_vars["broken.line.start.ui"] = line

           except IOError, err:
              if (err.errno != errno.EWOULDBLOCK):
                 print "Error communicating with user-interface: ",err
                 global_vars["loop-depth"] -= 1
                 return -1

           try:
              #line = backend_in.readline()
              line = my_readline(backend_in)
              if (len(line)==0):
                 global_vars["loop-depth"] -= 1
                 return -1
              do_sleep = 0
              line = global_vars["broken.line.start.backend"] + line
              if line.endswith('\n'):
                  global_vars["broken.line.start.backend"] = ""
                  if (not line.startswith("@now ")) \
                  and (not line.startswith("@sid "))\
                  and (not line.startswith("@caching "))\
                  and (not line.startswith("@id "))\
                  and (not line.startswith("@ml_")):
                     print " <*> ", line.strip()
                     ui_out.write("CONSOLE: <*> "+line)
                     ui_out.flush()
                  line = line[0:len(line)-1]
                  if line.startswith("@"):
                     if ' ' in line:
                        varname = line[0:line.index(' ')]
                        varvalue = line[line.index(' ')+1:]
                        if varname == "@now":
                           varvalue = float(varvalue)
                           timer_calls = global_vars["timer.calls"]
                           while timer_calls:
                               head = timer_calls[0][0]
                               if head <= varvalue:
                                   add_root_call(timer_calls.pop(0)[1])
                               else:
                                   break                           
                     else:
                        varname = line
                        varvalue = ""
                     global_vars[varname] = varvalue

                  if line.startswith("@main_start"):
                     initialize_backend()
                     ui_out.write("CHANNUM:"+str(global_vars["sampler_channels"])+"\n")
                     ui_out.flush();
                     initialize_new_technology()
                  elif line.startswith("@now "):
                     global_vars["@now-callback"]()
                     global_vars["drop_nows"] += 1
                     if (global_vars["drop_nows"] == 25):
                        stime = int(global_vars["@now"])/int(global_vars["output_rate"])
                        mtime = int(stime/60)
                        htime = int(mtime/60)
                        mtime = mtime % 60
                        stime = stime % 60
                        timestr = str(htime)+"h"+pad(str(mtime),2,'0')+"'"+pad(str(stime),2,'0')+'"'
                        ui_out.write("SAMPLER-TIME:"+timestr+"\n")
                        ui_out.flush()
                        global_vars["drop_nows"] = 0
                        backend_out.write("mlinfo\n")
                        backend_out.flush()
                  elif line.startswith("@ml_meter "):
                     meter = map(float, line[10:].split(" "))
                     l10 = log(10.0)
                     def safe_calc_meter_value(x):
                        try:
                           if x > 0.0:
                              val = int(round(10.0*log(x)/l10))
                           else:
                              val = -100.0
                        except OverflowError:
                           val = -100.0
                        return val

                     meter = map(safe_calc_meter_value, meter)
                     mstring = "["
                     for m in meter:
                        if (m <= -100):
                           sm = "-99"
                        else:
                           sm = str(m)
                           if (len(sm)<3):
                              sm = " "*(3-len(sm))+sm
                        mstring = mstring + sm +","

                     mstring = mstring[0:len(mstring)-1] + "]dB"
                     ui_out.write("MASTER-METER:"+mstring+"\n")
                     ui_out.flush()
                  elif line.startswith("@ml_current_gain "):
                     meter = map(float, line[17:].split(" "))
                     l10 = log(10.0)
                     try:
                        meter = map(lambda x: int(round(20.0*log(x)/l10)) , meter)
                     except OverflowError:
                        meter = map(lambda x: 0, meter)
                     mstring = "["
                     for m in meter:
                        sm = str(m)
                        if (len(sm)<3):
                           sm = " "*(3-len(sm))+sm
                        mstring = mstring + sm +","

                     mstring = mstring[0:len(mstring)-1] + "]dB"
                     ui_out.write("MASTER-GAIN:"+mstring+"\n")
                     ui_out.flush()
              else:
                  print " ___ caught over-long line from backend_in"
                  global_vars["broken.line.start.backend"] = line

           except IOError, err:
              if (err.errno != errno.EWOULDBLOCK):
                 print "Error communicating with backend: ", err
                 global_vars["loop-depth"] -= 1
                 return -1
Example #3
0
def input_timer():
   """callback for checking the input data stream"""
   global root, console, coninput, i, o, notebook, frontconsole,\
          frontinput, samplelist, in_db_name, out_db_name, info,\
          sampler_time, master_meter, master_gain, line_start
   line = ""
   while (1):
      try:
         #line = i.readline()
         line = my_readline(i)
         if (len(line)==0):
            root.quit()
            return
         line = line_start + line
         if line.endswith('\n'):
             line_start = ""
             #print "~~~~~ ", repr(line)
             line = line[0:len(line)-1]
             if line == "UI-FINISH!":
                root.quit()
                return
             if line.startswith("CONSOLE:"):
                console.config(state=NORMAL)
                console.insert(END, line[8:]+"\n")
                console.see(END)
                console.config(state=DISABLED)
                console.update()
             elif line.startswith("BOUNCE:"):
                 send_line("PYTHON","execfile('"+line[7:]+"')")
             elif line.startswith("PYTHON:"):
                frontconsole.config(state=NORMAL)
                frontconsole.insert(END, line[7:])
                frontconsole.see(END)
                frontconsole.config(state=DISABLED)
                frontconsole.update()
             elif line.startswith("PYTHON':"):
                frontconsole.config(state=NORMAL)
                frontconsole.insert(END, line[8:]+"\n")
                frontconsole.see(END)
                frontconsole.config(state=DISABLED)
                frontconsole.update()
             elif line == "FLUSHSMP!":
                samplelist.delete(0,END)
             elif line.startswith("SMP:"):
                samplelist.insert(END, line[4:])
             elif line.startswith("INDB:"):
                in_db_name = line[5:]
                frame = Frame(info)
                DfGlobal()["in_db_name"] = in_db_name
                Label(frame,text="Input database: "+in_db_name).pack(side=LEFT,fill=X,expand=0)
                cmd = "sqliteman "+in_db_name
                Button(frame,text=cmd, command=\
                       lambda: subprocess.Popen(cmd,\
                               shell=True)).pack(side=RIGHT,fill=X,expand=0)
                frame.pack(side=TOP,fill=X,expand=0)
                in_db = sqlite.connect(in_db_name)
                cur = in_db.cursor()
                cur.execute("CREATE TABLE IF NOT EXISTS frontend (name TEXT, value TEXT)")
                cur.execute("SELECT value FROM frontend WHERE name='autosave_path'")
                default_autosave = "./frontend_autosave"
                for x in cur:
                    default_autosave = x[0]
                frame = Frame(info)
                autosave_label = Label(frame,text="Current autosave file: " + default_autosave)
                autosave_label.pack(side=LEFT,fill=X,expand=0)

                in_db.commit()
                DfGlobal()["autosave_path"] = default_autosave
                send_line("PYTHON","DfGlobal()['autosave_path'] = " + repr(default_autosave))
                def chg_autosave_path(autosave_label=autosave_label):
                    path = tkFileDialog.asksaveasfilename(title="Autosave to file...")
                    DfGlobal()["autosave_path"] = path
                    db = sqlite.connect(in_db_name)
                    cr = db.cursor()
                    cr.execute("DELETE FROM frontend WHERE name='autosave_path'")
                    cr.execute("INSERT INTO frontend VALUES ('autosave_path', '"+path+"')")
                    db.commit()
                    autosave_label.configure(text="Current autosave file: " + path)
                    send_line("PYTHON","DfGlobal()['autosave_path'] = " + repr(path))


                Button(frame,text="Select...",command=chg_autosave_path).pack(side=RIGHT,fill=X,expand=0)
                Button(frame,text="Commit",command=lambda:send_line("PYTHON",\
                        "save_state(DfGlobal()['autosave_path'])")).pack(side=RIGHT,fill=X,expand=0)

                frame.pack(side=TOP,fill=X,expand=0)

                cur.execute("SELECT value FROM frontend WHERE name='setup_path'")
                default_setup = "./frontend_local_setup"
                for x in cur:
                    default_setup = x[0]
                frame = Frame(info)
                setup_label = Label(frame,text="Current setup file: " + default_setup)
                setup_label.pack(side=LEFT,fill=X,expand=0)
                in_db.commit()
                DfGlobal()["setup_path"] = default_setup
                send_line("PYTHON","DfGlobal()['setup_path'] = " + repr(default_setup))
                def chg_setup_path(autosave_label=setup_label):
                    path = tkFileDialog.askopenfilename(title="Setup script path...")
                    DfGlobal()["setup_path"] = path
                    db = sqlite.connect(in_db_name)
                    cr = db.cursor()
                    cr.execute("DELETE FROM frontend WHERE name='setup_path'")
                    cr.execute("INSERT INTO frontend VALUES ('setup_path', '"+path+"')")
                    db.commit()
                    autosave_label.configure(text="Current setup file: " + path)
                    send_line("PYTHON","DfGlobal()['setup_path'] = " + repr(path))

                Button(frame,text="Select...",command=chg_setup_path).pack(side=RIGHT,fill=X,expand=0)
                Button(frame,text="Run again",command=lambda:send_line("PYTHON",\
                        "execfile(DfGlobal()['setup_path'])")).pack(side=RIGHT,fill=X,expand=0)

                frame.pack(side=TOP,fill=X,expand=0)

             elif line.startswith("CHANNUM:"):
                nbr = int(line[8:])
                for n in range(nbr):
                   create_channel_panel(n,notebook,root)
             elif line.startswith("OUTDB:"):
                out_db_name = line[6:]
                frame = Frame(info)
                Label(frame,text="Output database: "+out_db_name).pack(side=LEFT,fill=X,expand=0)
                cmd = "sqliteman "+out_db_name
                Button(frame,text=cmd, command=\
                       lambda: subprocess.Popen(cmd,\
                               shell=True)).pack(side=RIGHT,fill=X,expand=0)
                frame.pack(side=TOP,fill=X,expand=0)
             elif line.startswith("SAMPLER-TIME:"):
                sampler_time = line[13:]
                refresh_status()
             elif line.startswith("MASTER-METER:"):
                master_meter = line[13:]
                refresh_status()
             elif line.startswith("MASTER-GAIN:"):
                master_gain = line[12:]
                refresh_status()
             elif line.startswith("SAMPLE-RATE:"):
                DfGlobal()["sample-rate"] = float(line[12:])
             else:
                handle_read_line(line)
         else:
             print " ___ caught over-long line from i"
             line_start = line

      except IOError, err:
         if (err.errno != errno.EWOULDBLOCK):
            root.quit()
            return
         else:
            break