示例#1
0
def test_codec_ComplexLowPass():
    filter = ComplexLowPass(FilterType.BUTTERWORTH, 2, 48000, 100)
    output = json.dumps(filter.to_json())
    assert output == '{"_type": "ComplexLowPass", "filter_type": "BW", "order": 2, "fs": 48000, "fc": 100.0}'
    decoded = filter_from_json(json.loads(output))
    assert decoded is not None
    assert isinstance(decoded, ComplexLowPass)
    assert filter.fs == decoded.fs
    assert filter.type == decoded.type
    assert filter.order == decoded.order
    assert filter.freq == decoded.freq
    assert decoded.get_transfer_function() is not None
示例#2
0
 def create_pass_filter(self):
     '''
     Creates a predefined high or low pass filter.
     :return: the filter.
     '''
     if self.filterType.currentText() == 'Low Pass':
         filt = ComplexLowPass(FilterType[self.passFilterType.currentText().upper().replace('-', '_')],
                               self.filterOrder.value(), self.__signal.fs, self.freq.value())
     else:
         filt = ComplexHighPass(FilterType[self.passFilterType.currentText().upper().replace('-', '_')],
                                self.filterOrder.value(), self.__signal.fs, self.freq.value())
     filt.id = self.__selected_id
     return filt
示例#3
0
    def __convert_to_ffmpeg_filter_complex(self,
                                           audio_input,
                                           c_name,
                                           channel_idx,
                                           sig,
                                           low_pass_main_bm=False):
        '''
        Formats a channel to a ffmpeg filter chain.
        :param audio_input:the ffmpeg input channel that contains the audio track.
        :param c_name: the channel name we're processing (FL, FR etc)
        :param channel_idx: the channel idx, 0 based.
        :param sig: the signal containing the filter.
        :return: a formatted filter string.
        '''
        f_idx = 0
        # extract a single channel, convert it to dbl sample format
        # pipe it through each biquad in the matching signal
        # convert back to 32bit into the original fs and place in a named mono stream
        #   [0:a]pan=1c|c0=c<channel_num>[<c_name>];[L]aformat=sample_fmts=dbl[Lin];[Lin]biquad=b0=1.00080054343984:b1=-1.99150225042309:b2=0.990752403334702:a0=1.0:a1=-1.99150965346467:a2=0.991545543732965[L1];[L1]biquad=b0=0.999200096917323:b1=-1.98991663875369:b2=0.990752403395918:a0=1.0:a1=-1.98990924163382:a2=0.989959897433105[L2];[L2]aformat=sample_fmts=s32:sample_rates=48000:channel_layouts=mono[Lout];
        if low_pass_main_bm:
            c_name = f"BM{c_name}"
        filt = f"{audio_input}pan=1c|c0=c{channel_idx}[{c_name}];"
        filt += f"[{c_name}]aformat=sample_fmts=dbl[{c_name}_{f_idx}];"
        if sig is not None:
            sig_filter = sig.active_filter.resample(int(self.__sample_rate),
                                                    copy_listener=False)
            for f in sig_filter.filters:
                for bq in format_biquad(f):
                    filt += f"[{c_name}_{f_idx}]biquad={bq}[{c_name}_{f_idx + 1}];"
                    f_idx += 1

        # apply BM high or low pass filter after the filters are applied
        bmpf = None
        if low_pass_main_bm:
            bmpf = ComplexLowPass(FilterType.LINKWITZ_RILEY, 4,
                                  int(self.__sample_rate), self.__bm_fs)
        elif self.bass_manage is True and (self.lfe_idx - 1) != channel_idx:
            bmpf = ComplexHighPass(FilterType.LINKWITZ_RILEY, 4,
                                   int(self.__sample_rate), self.__bm_fs)
        if bmpf:
            for bq in format_biquad(bmpf):
                filt += f"[{c_name}_{f_idx}]biquad={bq}[{c_name}_{f_idx + 1}];"
                f_idx += 1

        # add a passthrough filter if we have no other filters to add
        if f_idx == 0:
            filt += f"[{c_name}_{f_idx}]biquad={format_biquad(Passthrough())[0]}[{c_name}_{f_idx + 1}];"
            f_idx += 1

        # gain adjustment
        if not math.isclose(self.filtered_audio_offset, 0.0):
            filt += f"[{c_name}_{f_idx}]volume=volume={self.filtered_audio_offset:+g}dB[{c_name}_{f_idx + 1}];"
            f_idx += 1

        # enforce sample format
        filt += f"[{c_name}_{f_idx}]aformat=sample_fmts=s32:sample_rates={self.__sample_rate}"

        return filt
示例#4
0
def filter_from_json(o):
    '''
    Converts a dict (parsed from json) to a filter.
    :param o: the dict.
    :return: the filter.
    '''
    from model.iir import Passthrough, PeakingEQ, LowShelf, HighShelf, FirstOrder_LowPass, \
        FirstOrder_HighPass, SecondOrder_LowPass, SecondOrder_HighPass, AllPass, CompleteFilter, ComplexLowPass, \
        FilterType, ComplexHighPass

    filt = None
    if '_type' not in o:
        raise ValueError(f"{o} is not a filter")
    if o['_type'] == Passthrough.__name__:
        if 'fs' in o:
            filt = Passthrough(fs=int(o['fs']))
        else:
            filt = Passthrough()
    elif o['_type'] == Gain.__name__:
        filt = Gain(o['fs'], o['gain'])
    elif o['_type'] == PeakingEQ.__name__:
        filt = PeakingEQ(o['fs'], o['fc'], o['q'], o['gain'])
    elif o['_type'] == LowShelf.__name__:
        filt = LowShelf(o['fs'], o['fc'], o['q'], o['gain'], o['count'])
    elif o['_type'] == HighShelf.__name__:
        filt = HighShelf(o['fs'], o['fc'], o['q'], o['gain'], o['count'])
    elif o['_type'] == FirstOrder_LowPass.__name__:
        filt = FirstOrder_LowPass(o['fs'], o['fc'], o['q'])
    elif o['_type'] == FirstOrder_HighPass.__name__:
        filt = FirstOrder_HighPass(o['fs'], o['fc'], o['q'])
    elif o['_type'] == SecondOrder_LowPass.__name__:
        filt = SecondOrder_LowPass(o['fs'], o['fc'], o['q'])
    elif o['_type'] == SecondOrder_HighPass.__name__:
        filt = SecondOrder_HighPass(o['fs'], o['fc'], o['q'])
    elif o['_type'] == AllPass.__name__:
        filt = AllPass(o['fs'], o['fc'], o['q'])
    elif o['_type'] == CompleteFilter.__name__:
        kwargs = {}
        if 'fs' in o:
            kwargs['fs'] = o['fs']
        filt = CompleteFilter(
            filters=[filter_from_json(x) for x in o['filters']],
            description=o['description'],
            **kwargs)
    elif o['_type'] == ComplexLowPass.__name__:
        filt = ComplexLowPass(FilterType(o['filter_type']), o['order'],
                              o['fs'], o['fc'])
    elif o['_type'] == ComplexHighPass.__name__:
        filt = ComplexHighPass(FilterType(o['filter_type']), o['order'],
                               o['fs'], o['fc'])
    if filt is None:
        raise ValueError(f"{o._type} is an unknown filter type")
    else:
        if filt.id == -1:
            filt.id = uuid4()
        return filt