Exemple #1
0
def test_codec_signal():
    fs = 1000
    peak = LowShelf(fs, 30, 1, 10,
                    count=2).get_transfer_function().get_magnitude()
    avg = LowShelf(fs, 30, 1, 10).get_transfer_function().get_magnitude()
    median = LowShelf(fs, 30, 1, 10).get_transfer_function().get_magnitude()
    filt = CompleteFilter()
    filt.save(HighShelf(fs, 60, 1, 5, count=2))
    data = SingleChannelSignalData('test',
                                   fs,
                                   xy_data=[avg, peak, median],
                                   filter=filt,
                                   duration_seconds=123456,
                                   start_seconds=123,
                                   offset=4.2)
    output = json.dumps(signaldata_to_json(data))
    assert output is not None
    decoded = signaldata_from_json(json.loads(output), None)
    assert decoded is not None
    assert isinstance(decoded, SingleChannelSignalData)
    assert decoded.name == data.name
    assert decoded.fs == data.fs
    assert decoded.filter is not None
    assert type(decoded.filter) is type(data.filter)
    assert decoded.filter.id != -1
    assert decoded.filter.description == data.filter.description
    assert decoded.filter.filters == data.filter.filters
    assert decoded.current_unfiltered is not None
    assert len(decoded.current_unfiltered) == 3
    assert decoded.current_unfiltered == data.current_unfiltered
    assert decoded.duration_hhmmss == data.duration_hhmmss
    assert decoded.start_hhmmss == data.start_hhmmss
    assert decoded.end_hhmmss == data.end_hhmmss
    assert decoded.offset == data.offset
Exemple #2
0
def optimise_filters(filters, fs, to_save):
    '''
    Attempts to optimise the no of filters required.
    :param filters: the filters to optimise.
    :param fs: the sigma fs.
    :param to_save: how many filters we want to save.
    :return: the optimised filters.
    '''
    unstackable = sorted(
        [f for f in filters if isinstance(f, Shelf) and f.count > 1],
        key=lambda f: f.count,
        reverse=True)
    unstackable = sorted(unstackable,
                         key=lambda f: f.gain * f.count,
                         reverse=True)
    weights = [abs(w.gain * w.count) for w in unstackable]
    total_weight = sum(weights)
    allocated = []
    for idx, weight in enumerate(weights):
        weight = float(weight)
        p = weight / total_weight
        max_amount = unstackable[idx].count - 1
        distributed_amount = min(round(p * (to_save - sum(allocated))),
                                 max_amount)
        total_weight -= weight
        allocated.append(distributed_amount)
    new_filts = [f for f in filters if not isinstance(f, Shelf) or f.count < 2]
    for idx, s in enumerate(unstackable):
        reduce_by = allocated[idx]
        if reduce_by > 0:
            total_gain = s.gain * s.count
            new_count = s.count - reduce_by
            if new_count > 0:
                new_gain = total_gain / new_count
                tmp_shelf = LowShelf(fs,
                                     s.freq,
                                     s.q,
                                     new_gain,
                                     count=new_count)
                average_s = (tmp_shelf.q_to_s() + s.q_to_s()) / 2
                new_shelf = LowShelf(fs,
                                     s.freq,
                                     s_to_q(average_s, new_gain),
                                     new_gain,
                                     count=new_count)
                logger.info(f"Replacing {s} with {new_shelf}")
                new_filts.append(new_shelf)
            else:
                raise ValueError(
                    f"Attempted to reduce shelf count to 0 from {s.count}")
        else:
            new_filts.append(s)
    return new_filts
Exemple #3
0
def test_codec_StackedLowShelf():
    filter = LowShelf(48000, 20, 1.5, 2.5, count=5)
    output = json.dumps(filter.to_json())
    assert output == '{"_type": "LowShelf", "fs": 48000, "fc": 20.0, "q": 1.5, "gain": 2.5, "count": 5}'
    decoded = filter_from_json(json.loads(output))
    assert decoded is not None
    assert isinstance(decoded, LowShelf)
    assert filter.fs == decoded.fs
    assert filter.q == decoded.q
    assert filter.gain == decoded.gain
    assert filter.freq == decoded.freq
    assert filter.count == decoded.count
    assert decoded.get_transfer_function() is not None
Exemple #4
0
 def create_shaping_filter(self):
     '''
     Creates a filter of the specified type.
     :return: the filter.
     '''
     filt = None
     if self.filterType.currentText() == 'Low Shelf':
         filt = LowShelf(self.__signal.fs, self.freq.value(),
                         self.filterQ.value(), self.filterGain.value(),
                         self.filterCount.value())
     elif self.filterType.currentText() == 'High Shelf':
         filt = HighShelf(self.__signal.fs, self.freq.value(),
                          self.filterQ.value(), self.filterGain.value(),
                          self.filterCount.value())
     elif self.filterType.currentText() == 'PEQ':
         filt = PeakingEQ(self.__signal.fs, self.freq.value(),
                          self.filterQ.value(), self.filterGain.value())
     elif self.filterType.currentText() == 'Gain':
         filt = Gain(self.__signal.fs, self.filterGain.value())
     elif self.filterType.currentText() == 'Variable Q LPF':
         filt = SecondOrder_LowPass(self.__signal.fs, self.freq.value(),
                                    self.filterQ.value())
     elif self.filterType.currentText() == 'Variable Q HPF':
         filt = SecondOrder_HighPass(self.__signal.fs, self.freq.value(),
                                     self.filterQ.value())
     if filt is None:
         raise ValueError(
             f"Unknown filter type {self.filterType.currentText()}")
     else:
         filt.id = self.__selected_id
     return filt
Exemple #5
0
def xml_to_filt(file, fs=1000, unroll=False):
    ''' Extracts a set of filters from the provided minidsp file '''
    from model.iir import PeakingEQ, LowShelf, HighShelf

    filts = __extract_filters(file)
    output = []
    for filt_tup, count in filts.items():
        filt_dict = dict(filt_tup)
        if filt_dict['type'] == 'SL':
            for i in range(0, count if unroll is True else 1):
                filt = LowShelf(fs, float(filt_dict['freq']), float(filt_dict['q']), float(filt_dict['boost']),
                                count=1 if unroll is True else count)
                output.append(filt)
        elif filt_dict['type'] == 'SH':
            for i in range(0, count if unroll is True else 1):
                filt = HighShelf(fs, float(filt_dict['freq']), float(filt_dict['q']), float(filt_dict['boost']),
                                 count=1 if unroll is True else count)
                output.append(filt)
        elif filt_dict['type'] == 'PK':
            for i in range(0, count):
                filt = PeakingEQ(fs, float(filt_dict['freq']), float(filt_dict['q']), float(filt_dict['boost']))
                output.append(filt)
        else:
            logger.info(f"Ignoring unknown filter type {filt_dict}")
    return output
Exemple #6
0
 def __make_default_filter(self):
     ''' Creates a new filter using the default preferences. '''
     return LowShelf(self.__signal.fs,
                     self.__preferences.get(FILTERS_DEFAULT_FREQ),
                     self.__preferences.get(FILTERS_DEFAULT_Q),
                     0.0,
                     f_id=uuid4())
Exemple #7
0
def test_codec_CompleteFilter():
    filter = CompleteFilter(filters=[PeakingEQ(1000, 50, 3.2, -5),
                                     LowShelf(1000, 25, 1, 3.2, count=3),
                                     ComplexHighPass(FilterType.BUTTERWORTH, 6, 1000, 12)],
                            description='Hello from me')
    output = json.dumps(filter.to_json())
    expected = '{"_type": "CompleteFilter", "description": "Hello from me", "fs": 1000, "filters": [' \
               '{"_type": "ComplexHighPass", "filter_type": "BW", "order": 6, "fs": 1000, "fc": 12.0}, ' \
               '{"_type": "LowShelf", "fs": 1000, "fc": 25.0, "q": 1.0, "gain": 3.2, "count": 3}, ' \
               '{"_type": "PeakingEQ", "fs": 1000, "fc": 50.0, "q": 3.2, "gain": -5.0}' \
               ']}'
    assert output == expected
    decoded = filter_from_json(json.loads(output))
    assert decoded is not None
    assert isinstance(decoded, CompleteFilter)
    assert decoded.description == 'Hello from me'
    assert decoded.filters is not None
    assert len(decoded.filters) == len(filter.filters)
    assert decoded.getTransferFunction() is not None
    assert isinstance(decoded.filters[0], filter.filters[0].__class__)
    assert filter.filters[0].fs == decoded.filters[0].fs
    assert filter.filters[0].type == decoded.filters[0].type
    assert filter.filters[0].order == decoded.filters[0].order
    assert filter.filters[0].freq == decoded.filters[0].freq
    assert isinstance(decoded.filters[1], filter.filters[1].__class__)
    assert filter.filters[1].fs == decoded.filters[1].fs
    assert filter.filters[1].q == decoded.filters[1].q
    assert filter.filters[1].gain == decoded.filters[1].gain
    assert filter.filters[1].freq == decoded.filters[1].freq
    assert filter.filters[1].count == decoded.filters[1].count
    assert isinstance(decoded.filters[2], filter.filters[2].__class__)
    assert filter.filters[2].fs == decoded.filters[2].fs
    assert filter.filters[2].q == decoded.filters[2].q
    assert filter.filters[2].gain == decoded.filters[2].gain
    assert filter.filters[2].freq == decoded.filters[2].freq
Exemple #8
0
 def __convert_to_filter(filter_params, id):
     ft = int(filter_params['FilterType']) if SyncHTP1Dialog.__has_filter_type(filter_params) else 0
     if ft == 0:
         return PeakingEQ(HTP1_FS, filter_params['Fc'], filter_params['Q'], filter_params['gaindB'], f_id=id)
     elif ft == 1:
         return LowShelf(HTP1_FS, filter_params['Fc'], filter_params['Q'], filter_params['gaindB'], f_id=id)
     elif ft == 2:
         return HighShelf(HTP1_FS, filter_params['Fc'], filter_params['Q'], filter_params['gaindB'], f_id=id)
Exemple #9
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