Exemple #1
0
    def switch_convolver( self, mode, *dummy ):

        result = 'nothing done'

        if mode == 'off':

            if bf.is_running():
                self.bf_sources = bf.get_in_connections()
                # Allows other Brutefir, kills just our.
                Popen(f'pkill -f  "brutefir\ brutefir_config"', shell=True)
                # Brutefir 1.0m process is 'brutefir.real'
                Popen(f'pkill -f  "brutefir.real\ brutefir_config"', shell=True)
                sleep(2)
                print(f'{Fmt.BLUE}{Fmt.BOLD}(core) STOPPING BRUTEFIR (!){Fmt.END}')
                result = 'done'

        elif mode == 'on':

            if not bf.is_running():

                # This avoids that powersave loop kills Brutefir
                self.ps_reset_elapsed.set()

                result = bf.restart_and_reconnect(bf_sources=self.bf_sources,
                                                  delay=self.state["extra_delay"] )
                if result == 'done':
                    print(f'{Fmt.BLUE}{Fmt.BOLD}(core) BRUTEFIR RESUMED{Fmt.END}')
                    self._validate( self.state ) # this includes mute
                    c = Convolver()
                    c.set_xo ( self.state["xo_set"]  )
                    c.set_drc( self.state["drc_set"] )
                    del( c )
                else:
                    result = f'PANIC: {result}'

        else:
            result = 'bad option'

        self.save_state()

        return result
Exemple #2
0
 def save_state(self):
     self.state["convolver_runs"] = bf.is_running()
     with open(STATE_PATH, 'w') as f:
         f.write( json.dumps( self.state ) )
Exemple #3
0
    def __init__(self):

        # The available inputs
        self.inputs = CONFIG["sources"]
        # The state dictionary
        self.state = read_state_from_disk()
        self.state["convolver_runs"] = bf.is_running()
        # will add some informative values:
        self.state["loudspeaker"] = CONFIG["loudspeaker"]
        self.state["loudspeaker_ref_SPL"] = CONFIG["refSPL"]
        self.state["peq_set"] = get_peq_in_use()
        self.state["fs"] = jack.get_samplerate()
        # The target curves available under the 'eq' folder
        self.target_sets = self._find_target_sets()
        # The available span for tone curves
        self.bass_span   = int( (EQ_CURVES["bass_mag"].shape[0] - 1) / 2 )
        self.treble_span = int( (EQ_CURVES["treb_mag"].shape[0] - 1) / 2 )
        # Max authorised gain
        self.gain_max    = float(CONFIG["gain_max"])
        # Max authorised balance
        self.balance_max = float(CONFIG["balance_max"])
        # Initiate brutefir input connected ports (used from switch_convolver)
        self.bf_sources = bf.get_in_connections()

        # Powersave
        #   State file info
        self.state["powersave"] = False
        #
        #   Powersave loop: breaking flag
        self.ps_end = threading.Event()
        #
        #   Powersave loop:reset elapsed low level detected counter flag
        self.ps_reset_elapsed = threading.Event()
        #
        #   Convolver driving events
        def wait_PS_convolver_off():
            """ Event handler for convolver switch off requests
            """
            while True:
                # waiting ...
                self.ps_convolver_off.wait()
                print(f'(core) Thread \'waits for convolver OFF\' received event')
                self.ps_convolver_off.clear()
                self.switch_convolver('off')
        #
        def wait_PS_convolver_on():
            """ Event handler for convolver switch on requests
            """
            while True:
                # waiting ...
                self.ps_convolver_on.wait()
                print(f'(core) Thread \'waits for convolver ON\' received event')
                self.ps_convolver_on.clear()
                self.switch_convolver('on')
        #
        self.ps_convolver_off = threading.Event()
        self.ps_convolver_on  = threading.Event()
        t1 = threading.Thread( name='waits for convolver OFF',
                               target=wait_PS_convolver_off )
        t2 = threading.Thread( name='waits for convolver ON',
                               target=wait_PS_convolver_on )
        t1.start()
        t2.start()
        self._print_threads()
Exemple #4
0
def powersave_loop( convolver_off_driver, convolver_on_driver,
                    end_loop_flag, reset_elapsed_flag ):
    """ Loops forever every 1 sec reading the dBFS level on preamp input.
        If detected signal is below NOISE_FLOOR during MAX_WAIT then stops
        Brutefir. If signal level raises, then resumes Brutefir.

        Events managed here:
        convolver_off_driver:   Will set when no detected signal
        convolver_on_driver:    Will set when detected signal
        end_loop_flag:          Will check on every loop
        reset_elapsed_flag:     Will check and clear, useful when switching
                                to a no signal source to avoid killing brutefir
                                suddenly (see Preamp.select_source#NewSource)
    """


    def read_loudness_monitor():
        # Lets use LU_M (LU Momentary) from .loudness_monitor
        d = read_json_from_file(LDMON_PATH, tries=1)
        if 'LU_M' in d:
            LU_M = d["LU_M"]
        else:
            LU_M = 0.0
        dBFS = LU_M - 23.0  # LU_M is referred to -23dBFS
        return dBFS


    def loudness_monitor_is_running():
        try:
            check_output('pgrep -f loudness_monitor.py'.split()).decode()
            return True
        except:
            return False


    # Default values:
    NOISE_FLOOR = -70
    MAX_WAIT    =  60
    # CONFIG values overrides:
    if "powersave_noise_floor" in CONFIG:
        NOISE_FLOOR = CONFIG["powersave_noise_floor"]
    if "powersave_minutes" in CONFIG:
        MAX_WAIT = CONFIG["powersave_minutes"] * 60

    # Using a level meter, loudness_monitor.py is preferred,
    # if not available will use level_meter.py
    loud_mon_available = loudness_monitor_is_running()
    if loud_mon_available:
        print( f'(powersave) using \'loudness_monitor.py\'' )
    else:
        # Prepare and start a level_meter.Meter instance
        sys.path.append( f'{MAINFOLDER}/share/audiotools' )
        from level_meter import Meter
        meter = Meter(device='pre_in_loop', mode='peak', bar=False)
        meter.start()
        print( f'(powersave) using \'level_meter.py\'' )

    # Loop forever each 1 sec will check signal level
    print(f'(powersave) running')
    lowSigElapsed = 0
    while True:

        if reset_elapsed_flag.isSet():
            lowSigElapsed = 0
            reset_elapsed_flag.clear()

        # Reading level
        if loud_mon_available:
            dBFS = read_loudness_monitor()
        else:
            dBFS = meter.L

        # Level detected
        if dBFS > NOISE_FLOOR:
            if not bf.is_running():
                print(f'(powersave) signal detected, requesting to restart Brutefir')
                convolver_on_driver.set()
            lowSigElapsed = 0
        else:
            lowSigElapsed +=1

        # No level detected
        if dBFS < NOISE_FLOOR and lowSigElapsed >= MAX_WAIT:
            if bf.is_running():
                print(f'(powersave) low level during {sec2min(MAX_WAIT)}, '
                       'requesting to stop Brutefir' )
                convolver_off_driver.set()

        # Break loop
        if end_loop_flag.isSet():
            break

        sleep(1)
Exemple #5
0
    print

    for o in outs:
        if not o.isdigit():  # currently not necessary
            continue
        oname = outs[o]['name']
        delay = outs[o]['delay']
        ms = round(delay / 44100 * 1000, 3)
        print(o, oname.ljust(8), f'{str(delay).rjust(5)} samples',
              f'({ms} ms)')


if __name__ == '__main__':

    # Resuming Brutefir from powesave
    if not bf.is_running():
        print('resuming Brutefir from powersave ...')
        print(send_cmd('convolver on'))

    # Test if Brutefir is available
    test = bf.cli('')
    if not test:
        print('Brutefir not available')
        sys.exit()

    # Reading command line
    for opc in sys.argv[1:]:

        if '-h' in opc:
            print(__doc__)
            sys.exit()