diff --git a/__pycache__/Ui_widget.cpython-313.pyc b/__pycache__/Ui_widget.cpython-313.pyc index 1ac790b..9d56fb4 100644 Binary files a/__pycache__/Ui_widget.cpython-313.pyc and b/__pycache__/Ui_widget.cpython-313.pyc differ diff --git a/component/widget_filter/__pycache__/Ui_widget.cpython-313.pyc b/component/widget_filter/__pycache__/Ui_widget.cpython-313.pyc index 55a44f6..f41c12b 100644 Binary files a/component/widget_filter/__pycache__/Ui_widget.cpython-313.pyc and b/component/widget_filter/__pycache__/Ui_widget.cpython-313.pyc differ diff --git a/component/widget_filter/__pycache__/__init__.cpython-313.pyc b/component/widget_filter/__pycache__/__init__.cpython-313.pyc index e4f8884..a3637de 100644 Binary files a/component/widget_filter/__pycache__/__init__.cpython-313.pyc and b/component/widget_filter/__pycache__/__init__.cpython-313.pyc differ diff --git a/component/widget_filter/__pycache__/audio_filter_componet.cpython-313.pyc b/component/widget_filter/__pycache__/audio_filter_componet.cpython-313.pyc index e6435b6..f015986 100644 Binary files a/component/widget_filter/__pycache__/audio_filter_componet.cpython-313.pyc and b/component/widget_filter/__pycache__/audio_filter_componet.cpython-313.pyc differ diff --git a/component/widget_filter/__pycache__/audio_filter_model.cpython-313.pyc b/component/widget_filter/__pycache__/audio_filter_model.cpython-313.pyc new file mode 100644 index 0000000..d21318f Binary files /dev/null and b/component/widget_filter/__pycache__/audio_filter_model.cpython-313.pyc differ diff --git a/component/widget_filter/__pycache__/checkbox_header.cpython-313.pyc b/component/widget_filter/__pycache__/checkbox_header.cpython-313.pyc index d176b66..b09ea10 100644 Binary files a/component/widget_filter/__pycache__/checkbox_header.cpython-313.pyc and b/component/widget_filter/__pycache__/checkbox_header.cpython-313.pyc differ diff --git a/component/widget_filter/__pycache__/list_table_config.cpython-313.pyc b/component/widget_filter/__pycache__/list_table_config.cpython-313.pyc index 38700d9..29a737a 100644 Binary files a/component/widget_filter/__pycache__/list_table_config.cpython-313.pyc and b/component/widget_filter/__pycache__/list_table_config.cpython-313.pyc differ diff --git a/component/widget_filter/__pycache__/resources.cpython-313.pyc b/component/widget_filter/__pycache__/resources.cpython-313.pyc index 760073e..835b1ae 100644 Binary files a/component/widget_filter/__pycache__/resources.cpython-313.pyc and b/component/widget_filter/__pycache__/resources.cpython-313.pyc differ diff --git a/component/widget_filter/audio_filter_componet.py b/component/widget_filter/audio_filter_componet.py index 0267bc8..00a2ace 100644 --- a/component/widget_filter/audio_filter_componet.py +++ b/component/widget_filter/audio_filter_componet.py @@ -12,6 +12,7 @@ from Ui_widget import Ui_Widget from checkbox_header import SCheckBoxHeaderView +# from component.widget_filter.checkbox_header import SCheckBoxHeaderView from typing import List, Dict, Optional, Any @@ -676,69 +677,81 @@ class AudioFilterWidget(QWidget): if __name__ == "__main__": import sys from PySide6.QtWidgets import QApplication + from audio_filter_model import AudioFilterModel, ChannelParams, FilterParams, FilterType app = QApplication(sys.argv) # Create and show widget + # widget = AudioFilterWidget() + # widget.setWindowTitle("Audio Filter Widget") + # widget.resize(800, 600) + + # widget.set_channel_id(2) + # widget.set_channel("channel_2") + + # test_case_3 = { + # 'delay_data2': 100.0, # 最大延迟 + # 'vol_data2': -80.0, # 最小音量 + # 'mix_right_data2': 100.0, # 最大混音 + # 'mix_left_data2': 0.0, # 最小混音 + # 'filterType2_1': 2, # 低架滤波器 + # 'fc2_1': 20000.0, # 最大频率 + # 'q2_1': 10.0, # 最大Q值 + # 'gain2_1': 12.0, # 最大增益 + # 'slope2_1': 4.0, # 最大斜率 + # 'filterType2_2': 3, # 高架滤波器 + # 'fc2_2': 20.0, # 最小频率 + # 'q2_2': 0.1, # 最小Q值 + # 'gain2_2': -12.0, # 最小增益 + # 'slope2_2': 1.0 # 最小斜率 + # } + + # widget.set_all_params(test_case_3) + + # # 获取所有参数 + # params = widget.get_all_params() + # print("params:", params) + + # widget.show() + + # 创建模型实例 + model = AudioFilterModel(channel_id=2, channel_name="channel_2") + + # 设置通道参数 + model.channel_params = ChannelParams( + delay=100.0, + volume=-80.0, + mix_right=100.0, + mix_left=0.0 + ) + + # 添加滤波器 + model.add_filter(FilterParams( + filter_type=FilterType.HIGHPASS, + frequency=20000.0, + q_value=10.0, + gain=12.0, + slope=4.0 + )) + + model.add_filter(FilterParams( + filter_type=FilterType.ALLPASS, + frequency=20.0, + q_value=0.1, + gain=-12.0, + slope=1.0 + )) + + widget_params = model.to_widget_params() + print("widget_params:", widget_params) + widget = AudioFilterWidget() - widget.setWindowTitle("Audio Filter Widget") - widget.resize(800, 600) - - # 测试数据 - # widget.set_filters_count(2) - # widget.set_filter_data(0, { - # 'filter_name': 'peak', - # 'filter_type': 'PEAK', - # 'freq': 100, - # 'q': 1.0, - # 'gain': 0.0, - # 'slope': 1.0, - # 'enabled': True - # }) - # widget.set_filter_data(1, { - # 'filter_name': 'lowpass', - # 'filter_type': 'LOWPASS', - # 'freq': 1000, - # 'q': 0.7, - # 'gain': 0.0, - # 'slope': 2.0, - # 'enabled': True - # }) - - # widget.set_param_data({ - # 'delay_data1': 30, - # 'ENT_volume_data1': 2, - # 'ENT_mx_right_data': 3, - # 'ENT_mix_left_data': 4 - # }) + widget.set_channel_id(model.channel_id) + widget.set_channel_name(model.channel_name) + widget.set_all_params(widget_params) - widget.set_channel_id(2) - widget.set_channel("channel_2") - - test_case_3 = { - 'delay_data2': 100.0, # 最大延迟 - 'vol_data2': -80.0, # 最小音量 - 'mix_right_data2': 100.0, # 最大混音 - 'mix_left_data2': 0.0, # 最小混音 - 'filterType2_1': 2, # 低架滤波器 - 'fc2_1': 20000.0, # 最大频率 - 'q2_1': 10.0, # 最大Q值 - 'gain2_1': 12.0, # 最大增益 - 'slope2_1': 4.0, # 最大斜率 - 'filterType2_2': 3, # 高架滤波器 - 'fc2_2': 20.0, # 最小频率 - 'q2_2': 0.1, # 最小Q值 - 'gain2_2': -12.0, # 最小增益 - 'slope2_2': 1.0 # 最小斜率 - } - - widget.set_all_params(test_case_3) - - # widget.set_all_params(test_params) - - # 获取所有参数 params = widget.get_all_params() - print("aaaa params:", params) - + print("params:", params) widget.show() + sys.exit(app.exec()) \ No newline at end of file diff --git a/component/widget_filter/audio_filter_model.py b/component/widget_filter/audio_filter_model.py new file mode 100644 index 0000000..48eb001 --- /dev/null +++ b/component/widget_filter/audio_filter_model.py @@ -0,0 +1,134 @@ +from dataclasses import dataclass, asdict +from typing import List, Dict, Any, Optional +from enum import Enum + +class FilterType(Enum): + PEAK = 0 + LOWPASS = 1 + HIGHPASS = 2 + ALLPASS = 3 + +@dataclass +class FilterParams: + filter_type: FilterType + frequency: float + q_value: float + gain: float + slope: float + enabled: bool = True + + def to_dict(self, channel_id: int, filter_num: int) -> Dict[str, Any]: + """转换为与组件兼容的字典格式""" + return { + f'filterType{channel_id}_{filter_num}': self.filter_type.value, + f'fc{channel_id}_{filter_num}': self.frequency, + f'q{channel_id}_{filter_num}': self.q_value, + f'gain{channel_id}_{filter_num}': self.gain, + f'slope{channel_id}_{filter_num}': self.slope + } + + @classmethod + def from_dict(cls, data: Dict[str, Any], channel_id: int, filter_num: int) -> 'FilterParams': + """从字典创建FilterParams实例""" + prefix = f'{channel_id}_{filter_num}' + return cls( + filter_type=FilterType(data.get(f'filterType{prefix}', 0)), + frequency=data.get(f'fc{prefix}', 0.0), + q_value=data.get(f'q{prefix}', 0.0), + gain=data.get(f'gain{prefix}', 0.0), + slope=data.get(f'slope{prefix}', 0.0) + ) + +@dataclass +class ChannelParams: + delay: float + volume: float + mix_right: float + mix_left: float + + def to_dict(self, channel_id: int) -> Dict[str, Any]: + """转换为与组件兼容的字典格式""" + return { + f'delay_data{channel_id}': self.delay, + f'vol_data{channel_id}': self.volume, + f'mix_right_data{channel_id}': self.mix_right, + f'mix_left_data{channel_id}': self.mix_left + } + + @classmethod + def from_dict(cls, data: Dict[str, Any], channel_id: int) -> 'ChannelParams': + """从字典创建ChannelParams实例""" + return cls( + delay=data.get(f'delay_data{channel_id}', 0.0), + volume=data.get(f'vol_data{channel_id}', 0.0), + mix_right=data.get(f'mix_right_data{channel_id}', 0.0), + mix_left=data.get(f'mix_left_data{channel_id}', 0.0) + ) + +class AudioFilterModel: + def __init__(self, channel_id: int, channel_name: str): + self.channel_id = channel_id + self.channel_name = channel_name + self.channel_params = ChannelParams(0.0, 0.0, 0.0, 0.0) + self.filters: List[FilterParams] = [] + + def add_filter(self, filter_params: FilterParams): + """添加新的滤波器""" + self.filters.append(filter_params) + + def remove_filter(self, index: int): + """移除指定索引的滤波器""" + if 0 <= index < len(self.filters): + self.filters.pop(index) + + def update_filter(self, index: int, filter_params: FilterParams): + """更新指定索引的滤波器参数""" + if 0 <= index < len(self.filters): + self.filters[index] = filter_params + + def to_widget_params(self) -> Dict[str, Any]: + """转换为AudioFilterWidget兼容的参数格式""" + params = self.channel_params.to_dict(self.channel_id) + + for i, filter_param in enumerate(self.filters, 1): + params.update(filter_param.to_dict(self.channel_id, i)) + + return params + + def from_widget_params(self, params: Dict[str, Any]): + """从AudioFilterWidget参数更新模型""" + self.channel_params = ChannelParams.from_dict(params, self.channel_id) + + self.filters.clear() + filter_count = 1 + while True: + if f'filterType{self.channel_id}_{filter_count}' in params: + filter_param = FilterParams.from_dict(params, self.channel_id, filter_count) + self.filters.append(filter_param) + filter_count += 1 + else: + break + + def save_to_file(self, filepath: str): + """保存配置到文件""" + import json + data = { + 'channel_id': self.channel_id, + 'channel_name': self.channel_name, + 'channel_params': asdict(self.channel_params), + 'filters': [asdict(f) for f in self.filters] + } + with open(filepath, 'w') as f: + json.dump(data, f, indent=2) + + @classmethod + def load_from_file(cls, filepath: str) -> 'AudioFilterModel': + """从文件加载配置""" + import json + with open(filepath, 'r') as f: + data = json.load(f) + + model = cls(data['channel_id'], data['channel_name']) + model.channel_params = ChannelParams(**data['channel_params']) + model.filters = [FilterParams(**f) for f in data['filters']] + return model \ No newline at end of file