[feature] 新增滤波器数据从.csv中导入

This commit is contained in:
Sam 2025-02-26 01:30:51 +08:00
parent d5d88850d9
commit 8619d64f3c
35 changed files with 420 additions and 237 deletions

254
app.py
View File

@ -11,7 +11,7 @@ from component.widget_filter.audio_filter_model import AudioFilterModel
from component.widget_filter.audio_filter_controller import AudioFilterController
from component.widget_card.widget_card import ParamData
from component.widget_log.widget_log import Widget_Log
from persistence.data_store_manager_origin import DataStoreManager
from persistence.data_store_manager import DataStoreManager
from persistence.data_store_origin import DataStore
from param_struct_test.service_manager import ServiceManager
from application.application_controller import ApplicationController
@ -97,7 +97,7 @@ class MainWindow(QWidget):
if param_info.get('name') == selected_name:
return True
return False
# app.py
def update_channel_from_card(self):
"""根据选中的卡片更新通道数据"""
try:
@ -105,80 +105,98 @@ class MainWindow(QWidget):
selected_param_name, selected_project_name = self.widget_card.get_selected_param_name()
logger.info(f"selected_param_name: {selected_param_name}, selected_project_name: {selected_project_name}")
# 2. 获取项目数据
projects = self.data_manager.get_projects()
project_name = projects[0]
project_data = self.data_manager.get_project(project_name)
if not project_data or 'params' not in project_data:
logger.error("Project data not found or invalid")
if not selected_param_name or not selected_project_name:
logger.warning("未选择参数或项目")
return
# 3. 查找匹配的参数数据
param_data = None
for key, param_info in project_data['params'].items():
if param_info.get('name') == selected_param_name:
param_data = param_info
break
if not param_data or 'channels' not in param_data:
logger.error(f"Parameter data not found for name: {selected_param_name}")
# 2. 获取参数数据
param_data = self.data_manager.get_param_data(selected_project_name, selected_param_name)
# 新增: 根据参数名称查找对应的参数键并更新current_param
# project_names = self.data_manager.get_projects()
# project_data = self.data_manager.get_project(project_names[0])
# if project_data and 'params' in project_data:
# for param_key, param_info in project_data['params'].items():
# if param_info.get('name') == selected_param_name:
# # 找到匹配的参数键更新current_param
# self.data_manager.current_param = param_key
# logger.info(f"已更新当前参数键: {param_key}")
# break
self.data_manager.current_param = param_data
if not param_data:
logger.error(f"未找到参数数据: {selected_param_name}")
return
# 4. 处理每个通道的数据
for channel_id, channel_data in param_data['channels'].items():
# 3. 处理每个通道的数据
for channel_id, channel_data in param_data.items():
try:
channel_id = int(channel_id) - 1 # JSON中通道从1开始程序中从0开始
channel_id = int(channel_id)
if 0 <= channel_id < len(self.filter_controllers):
controller = self.filter_controllers[channel_id]
controller.update_from_card_data(channel_data)
# controller.update_ui()
except Exception as e:
logger.error(f"Error processing channel {channel_id}: {str(e)}")
logger.error(f"处理通道 {channel_id} 时出错: {str(e)}")
continue
logger.info("Successfully updated all channels from card data")
logger.info("成功从卡片数据更新所有通道")
except Exception as e:
logger.error(f"Error updating channel from card: {str(e)}")
logger.error(f"从卡片更新通道时出错: {str(e)}")
def load_default_project(self):
"""Load the first available project or create a default one if none exists"""
try:
# 获取项目列表
projects = self.data_manager.get_projects()
if not projects:
# Create default project if none exists
logger.info("Creating default project...")
self.data_manager.create_project("default", "Default project configuration")
# 如果没有项目,创建默认项目
logger.info("创建默认项目...")
self.data_manager.create_project("default", "默认项目配置")
projects = ["default"]
# Load the first project
project_name = projects[0]
project_data = self.data_manager.get_project(project_name)
logger.info(f"Loading project: {project_name}")
if project_data and 'params' in project_data:
self.widget_card.list_widget.clear()
# 将字符串转换为 ParamData 对象
param_objects = [
ParamData(name=param_data['name'])
for param_data in project_data['params'].values()
]
card_data = CardData(
name=project_data['name'],
date=project_data['created_at'].split('T')[0],
description=project_data['description'],
params=param_objects # 使用 ParamData 对象列表
)
# 清空当前卡片列表
self.widget_card.list_widget.clear()
self.widget_card.add_card_item(card_data)
# 遍历所有项目并加载
for project_name in projects:
# 从数据管理器获取项目数据
project_data = self.data_manager.get_project(project_name)
#to do:目前支持一个项目
self.data_manager._store.current_project = project_name
if not project_data:
logger.warning(f"无法加载项目: {project_name}")
continue
logger.info(f"加载项目: {project_name}")
# 检查项目数据是否包含参数
if 'params' in project_data:
# 创建参数对象列表
param_objects = []
for param_id, param_data in project_data['params'].items():
if isinstance(param_data, dict) and 'name' in param_data:
param_objects.append(ParamData(name=param_data['name']))
# 创建卡片数据
card_data = CardData(
name=project_data.get('name', project_name),
date=project_data.get('created_at', '').split('T')[0] if 'created_at' in project_data else '',
description=project_data.get('description', ''),
params=param_objects
)
# 添加卡片到界面
self.widget_card.add_card_item(card_data)
logger.info(f"已添加项目卡片 '{project_data.get('name', project_name)}' 包含 {len(param_objects)} 个参数")
else:
logger.warning(f"项目 '{project_name}' 没有参数数据")
except Exception as e:
logger.error(f"Error loading default project: {e}")
logger.error(f"加载默认项目时出错: {str(e)}")
import traceback
logger.error(traceback.format_exc())
def load_config(self):
"""加载通道配置文件"""
@ -219,9 +237,83 @@ class MainWindow(QWidget):
print("setup_connections")
self.widget_channel.channel_btn_clicked.connect(self.on_channel_btn_clicked)
self.widget_card.parameterSelected.connect(self.on_widget_card_parameter_selected)
# 连接编辑信号
self.widget_card.itemEdited.connect(self.on_widget_card_item_edited)
# 连接参数添加信号
self.widget_card.parameterAdded.connect(self.on_widget_card_parameter_added)
# data_store_manager.current_param
def on_widget_card_parameter_selected(self, param_name: str, project_name: str):
logger.info(f"on_widget_card_parameter_selected: {param_name}, {project_name}")
try:
# 获取参数数据
param_data = self.data_manager.get_param_data(project_name, param_name)
if not param_data:
logger.warning(f"未找到参数数据: {param_name}")
return
# 更新所有通道的滤波器数据
for channel_id, channel_data in param_data.items():
try:
channel_id = int(channel_id)
if 0 <= channel_id < len(self.filter_controllers):
controller = self.filter_controllers[channel_id]
controller.update_from_card_data(channel_data)
except Exception as e:
logger.error(f"处理通道 {channel_id} 时出错: {str(e)}")
continue
logger.info(f"成功从参数 {param_name} 更新所有通道")
except Exception as e:
logger.error(f"参数选择更新出错: {str(e)}")
import traceback
logger.error(traceback.format_exc())
def on_widget_card_item_edited(self, edit_type, old_value, new_value, project_name):
"""处理卡片项目编辑事件"""
if edit_type == "parameter_name":
try:
# 查找项目文件名
projects = self.data_manager.get_projects()
project_filename = None
for proj_filename in projects:
project_data = self.data_manager.get_project(proj_filename)
if project_data and project_data.get('name') == project_name:
project_filename = proj_filename
# 1. 更新JSON中的参数名
if 'params' in project_data:
for param_id, param_info in project_data['params'].items():
if param_info.get('name') == old_value:
# 更新参数名
param_info['name'] = new_value
# 保存更新后的项目数据
self.data_manager.update_project(proj_filename, project_data)
logger.info(f"已更新参数名: {old_value} -> {new_value}")
# 2. 重命名参数文件
params_dir = os.path.join("data", "projects", "params")
for file in os.listdir(params_dir):
# 查找与旧参数名匹配的文件
if file.startswith(f"{project_name}_") and file.endswith('.csv'):
param_part = file[len(project_name)+1:-4] # 提取参数名部分
if param_part == old_value:
old_path = os.path.join(params_dir, file)
new_path = os.path.join(params_dir, f"{project_name}_{new_value}.csv")
try:
os.rename(old_path, new_path)
logger.info(f"已重命名参数文件: {old_path} -> {new_path}")
except Exception as e:
logger.error(f"重命名参数文件失败: {str(e)}")
break
break
except Exception as e:
logger.error(f"处理参数编辑时出错: {str(e)}")
import traceback
logger.error(traceback.format_exc())
def set_default_filter_widget(self, channel_id: int):
while self.widget_main.ui.verticalLayout_Filter.count():
@ -242,6 +334,7 @@ class MainWindow(QWidget):
# Add the selected channel's filter widget to the layout
filter_widget = self.widget_filter_list[channel_id]
self.widget_main.ui.verticalLayout_Filter.addWidget(filter_widget)
filter_widget.ui.groupBox_4.setTitle(f"Channel {channel_id+1}")
filter_widget.show()
def test_communication(self):
@ -352,6 +445,59 @@ class MainWindow(QWidget):
return channel_data
def on_widget_card_parameter_added(self, param_name: str, project_name: str):
"""处理添加新参数的事件"""
logger.info(f"添加新参数: {param_name}, 项目: {project_name}")
try:
# 获取项目列表
projects = self.data_manager.get_projects()
project_found = False
project_filename = None
# 查找对应的项目文件名
for proj_filename in projects:
project_data = self.data_manager.get_project(proj_filename)
if project_data and project_data.get('name') == project_name:
project_found = True
project_filename = proj_filename
# 创建空的通道数据结构
empty_channel_data = {}
for i in range(len(self.filter_controllers)):
empty_channel_data[i] = {
'delay_data': 0.0,
'vol_data': 0.0,
'mix_left_data': 0.0,
'mix_right_data': 0.0,
'filters': []
}
# 保存新参数 - 使用项目文件名
self.data_manager.save_param(project_filename, param_name, empty_channel_data, "")
# 重命名参数文件使用项目的name字段而不是文件名
old_param_path = os.path.join("data", "projects", "params", f"{project_filename}_{param_name}.csv")
new_param_path = os.path.join("data", "projects", "params", f"{project_name}_{param_name}.csv")
if os.path.exists(old_param_path):
try:
os.rename(old_param_path, new_param_path)
logger.info(f"已重命名参数文件: {old_param_path} -> {new_param_path}")
except Exception as e:
logger.error(f"重命名参数文件失败: {str(e)}")
logger.info(f"已创建新参数: {param_name}, 文件名: {project_name}_{param_name}.csv")
break
if not project_found:
logger.warning(f"未找到项目: {project_name}")
except Exception as e:
logger.error(f"创建参数时出错: {str(e)}")
import traceback
logger.error(traceback.format_exc())
if __name__ == '__main__':
import sys
from PySide6.QtWidgets import QApplication

View File

@ -34,6 +34,8 @@ class CardData:
class Widget_Card(QWidget):
parameterSelected = Signal(str, str) # Signal that emits (parameter_name, project_name)
itemEdited = Signal(str, str, str, str) # Signal that emits (edit_type, old_value, new_value, project_name)
parameterAdded = Signal(str, str) # Signal that emits (parameter_name, project_name)
def __init__(self):
super().__init__()
@ -44,6 +46,11 @@ class Widget_Card(QWidget):
self.list_widget.itemDelegate().parameterSelected.connect(
lambda param_name, project_name: self.parameterSelected.emit(param_name, project_name)
)
# Connect the itemDelegate's itemEdited signal
self.list_widget.itemDelegate().itemEdited.connect(
lambda edit_type, old_value, new_value, project_name: self.itemEdited.emit(edit_type, old_value, new_value, project_name)
)
def setup_ui(self):
self.setWindowTitle("卡片列表示例")
@ -280,6 +287,9 @@ class Widget_Card(QWidget):
item_height = self.calculate_item_height(data)
item.setSizeHint(QSize(380, item_height))
# 发射参数添加信号
self.parameterAdded.emit(new_param.name, data.name)
# 刷新显示
self.list_widget.viewport().update()
@ -320,8 +330,24 @@ class Widget_Card(QWidget):
return None, None
def add_parameter(self, param_name: str):
"""添加新参数到当前选中的项目"""
current_item = self.list_widget.currentItem()
if current_item:
card_data = current_item.data(Qt.ItemDataRole.UserRole)
card_data.params.append(ParamData(name=param_name))
# 更新UI
self.list_widget.viewport().update()
# 发射参数添加信号
self.parameterAdded.emit(param_name, card_data.name)
return True
return False
class CardItemDelegate(QStyledItemDelegate):
parameterSelected = Signal(str, str) # Signal that emits (parameter_name, project_name)
itemEdited = Signal(str, str, str, str) # Signal that emits (edit_type, old_value, new_value, project_name)
def __init__(self, parent=None):
super().__init__(parent)
@ -343,12 +369,13 @@ class CardItemDelegate(QStyledItemDelegate):
desc_rect = self.getDescriptionRect(option.rect)
if event.type() == QEvent.MouseButtonDblClick:
if title_rect.contains(pos):
self.editing_field = 'name'
self.edit_rect = title_rect
self.parent().edit(index)
return True
elif desc_rect.contains(pos):
# 移除对标题区域双击事件的处理
# if title_rect.contains(pos):
# self.editing_field = 'name'
# self.edit_rect = title_rect
# self.parent().edit(index)
# return True
if desc_rect.contains(pos):
self.editing_field = 'description'
self.edit_rect = desc_rect
self.parent().edit(index)
@ -444,14 +471,29 @@ class CardItemDelegate(QStyledItemDelegate):
return
data = index.data(Qt.ItemDataRole.UserRole)
old_value = ""
edit_type = ""
if self.editing_field == 'name':
old_value = data.name
data.name = editor.text()
edit_type = "project_name"
elif self.editing_field == 'description':
old_value = data.description
data.description = editor.text()
edit_type = "project_description"
elif self.editing_param_index >= 0:
old_value = data.params[self.editing_param_index].name
data.params[self.editing_param_index].name = editor.text()
edit_type = "parameter_name"
model.setData(index, data, Qt.ItemDataRole.UserRole)
# 发射编辑完成信号
if old_value != editor.text():
print(f"发射编辑完成信号: {edit_type}, {old_value}, {editor.text()}, {data.name}")
self.itemEdited.emit(edit_type, old_value, editor.text(), data.name)
self.editing_field = None
self.editing_param_index = -1

View File

@ -706,7 +706,7 @@ class AudioFilterWidget(QWidget):
self.current_filter_index = row
filter_name_item = self.ui.tableWidget.item(row, 1)
if filter_name_item:
self.ui.groupBox_4.setTitle(filter_name_item.text())
# self.ui.groupBox_4.setTitle(filter_name_item.text())
# 获取当前滤波器类型和slope值
filter_type_combo = self.ui.tableWidget.cellWidget(row, 2)

View File

@ -17,6 +17,7 @@ from component.widget_filter.audio_filter_model import AudioFilterModel
from component.widget_filter.audio_filter_componet import AudioFilterWidget
from component.widget_filter.audio_filter_model import FilterParams, FilterType, ChannelParams
from param_struct_test.params_service import Response, CMD
from persistence.data_store_manager import DataStoreManager
# from audio_filter_model import AudioFilterModel
# from audio_filter_componet import AudioFilterWidget
@ -90,7 +91,6 @@ class AudioFilterController(QObject):
try:
self.state = AudioControllerState.UPDATING
# 1. Update channel parameters
channel_params = ChannelParams(
delay=card_data.get('delay_data', 0.0),
volume=card_data.get('vol_data', 0.0),
@ -99,22 +99,47 @@ class AudioFilterController(QObject):
)
self.model.set_channel_params(channel_params)
# 2. Clear existing filters and add new ones
self.model.filters.clear()
# Convert and add new filters
for filter_data in card_data.get('filters', []):
filter_type = FilterType[filter_data['type']]
# 检查滤波器参数是否都为0
all_zeros = all([
filter_data.get('frequency', 0.0) == 0.0 and filter_data.get('fc', 0.0) == 0.0,
filter_data.get('q', 0.0) == 0.0,
filter_data.get('gain', 0.0) == 0.0,
filter_data.get('slope', 0.0) == 0.0
])
# 如果所有参数都为0跳过这个滤波器
if all_zeros:
continue
# 正确处理整数类型的 filterType
filter_type = None
if 'type' in filter_data and filter_data['type'] is not None:
# 如果是字符串名称
if isinstance(filter_data['type'], str):
filter_type = FilterType[filter_data['type']]
# 如果是整数值
elif isinstance(filter_data['type'], int):
filter_type = FilterType(filter_data['type'])
elif 'filterType' in filter_data and filter_data['filterType'] is not None:
# 如果是字符串名称
if isinstance(filter_data['filterType'], str):
filter_type = FilterType[filter_data['filterType']]
# 如果是整数值
elif isinstance(filter_data['filterType'], int):
filter_type = FilterType(filter_data['filterType'])
filter_params = FilterParams(
filter_type=filter_type,
frequency=filter_data['frequency'],
q_value=filter_data['q'],
gain=filter_data['gain'],
slope=filter_data['slope']
frequency=filter_data.get('frequency', 0.0) or filter_data.get('fc', 0.0),
q_value=filter_data.get('q', 0.0),
gain=filter_data.get('gain', 0.0),
slope=filter_data.get('slope', 0.0)
)
self.model.filters.append(filter_params)
# 3. Update UI
if self.widget:
self.widget.updateUI()
@ -442,9 +467,56 @@ class AudioFilterController(QObject):
self.model.update_filter(index, filter_params)
print(f"_on_widget_filter_changed model:{self.model.filters}")
# self.filter_changed.emit(index, param_name, value)
# 同步更新CSV文件中的数据
self._sync_to_csv()
except Exception as e:
self.error_occurred.emit(f"Error updating filter: {str(e)}")
def _sync_to_csv(self):
"""同步当前滤波器数据到CSV文件"""
try:
# 获取当前项目和参数名称
data_store_manager = DataStoreManager.get_instance()
current_project = data_store_manager.current_project
current_param = data_store_manager.current_param
# 如果仍然没有当前项目或参数,则不进行同步
if not current_project or not current_param:
return
# 准备通道数据
channel_data = {}
model_data = self.model.get_all_data()
channel_id = model_data['channel_id']
# 构建通道数据结构
channel_data[channel_id] = {
'mix_left_data': model_data['channel_params']['mix_left'],
'mix_right_data': model_data['channel_params']['mix_right'],
'delay_data': model_data['channel_params']['delay'],
'vol_data': model_data['channel_params']['volume'],
'filters': []
}
# 添加滤波器数据
for filter_param in model_data['filters']:
filter_data = {
'fc': filter_param['frequency'],
'q': filter_param['q_value'],
'gain': filter_param['gain'],
'slope': filter_param['slope'],
'filterType': filter_param['filter_type'].value
}
channel_data[channel_id]['filters'].append(filter_data)
# 保存到CSV文件
data_store_manager.save_param(current_project, current_param, channel_data)
except Exception as e:
self.error_occurred.emit(f"同步到CSV文件时发生错误: {str(e)}")
# def _on_widget_param_changed(self, param_name: str, value: float):
# """处理widget通道参数变化"""
# try:

View File

@ -1,118 +0,0 @@
{
"name": "test_default",
"created_at": "2025-02-25T10:30:00",
"last_modified": "2025-02-25T11:45:00",
"description": "test_xxxxx",
"params": {
"test_1": {
"name": "test_1-name",
"created_at": "2024-03-21T10:30:00",
"description": "test-description",
"channels": {
"1": {
"delay_data": 0.02,
"vol_data": -2.5,
"mix_left_data": 0.7,
"mix_right_data": 0.3,
"filters": [
{
"name": "Filters_1",
"type": "HIGHPASS",
"frequency": 20.0,
"q": 0.707,
"gain": 0.0,
"slope": 24,
"enabled": true
},
{
"name": "Filters_2",
"type": "PEAK",
"frequency": 250.0,
"q": 2.5,
"gain": -3.0,
"slope": 0,
"enabled": true
},
{
"name": "Filters_3",
"type": "LOWSHELF",
"frequency": 100.0,
"q": 1.0,
"gain": 3.0,
"slope": 12,
"enabled": true
}
]
},
"2": {
"delay_data": 0.02,
"vol_data": -2.5,
"mix_left_data": 0.3,
"mix_right_data": 0.7,
"filters": [
{
"name": "Filters_1",
"type": "HIGHPASS",
"frequency": 20.0,
"q": 0.707,
"gain": 0.0,
"slope": 24,
"enabled": true
},
{
"name": "Filters_2",
"type": "PEAK",
"frequency": 2000.0,
"q": 1.4,
"gain": -2.0,
"slope": 0,
"enabled": true
},
{
"name": "Filters_3",
"type": "HIGHSHELF",
"frequency": 8000.0,
"q": 1.0,
"gain": 1.5,
"slope": 12,
"enabled": true
}
]
}
}
},
"test_2": {
"name": "test_2-name",
"created_at": "2024-03-21T10:30:00",
"description": "test_2-description",
"channels": {
"1": {
"delay_data": 0.0,
"vol_data": 0.0,
"mix_left_data": 1.0,
"mix_right_data": 0.0,
"filters": [
{
"name": "Filters_1",
"type": "HIGHPASS",
"frequency": 45.0,
"q": 0.707,
"gain": 0.0,
"slope": 18,
"enabled": true
},
{
"name": "Filters_2",
"type": "PEAK",
"frequency": 400.0,
"q": 2.0,
"gain": -2.0,
"slope": 0,
"enabled": true
}
]
}
}
}
}
}

View File

@ -2,11 +2,11 @@ parameter,value
dataset.audio_mode,0
dataset.send_action,0
dataset.tuning_parameters.mix_parameters[0].ch_n,0
dataset.tuning_parameters.mix_parameters[0].mix_left_data,0.7
dataset.tuning_parameters.mix_parameters[0].mix_right_data,0.3
dataset.tuning_parameters.mix_parameters[0].mix_left_data,1.0
dataset.tuning_parameters.mix_parameters[0].mix_right_data,1.0
dataset.tuning_parameters.mix_parameters[1].ch_n,1
dataset.tuning_parameters.mix_parameters[1].mix_left_data,0.5
dataset.tuning_parameters.mix_parameters[1].mix_right_data,0.5
dataset.tuning_parameters.mix_parameters[1].mix_left_data,0.0
dataset.tuning_parameters.mix_parameters[1].mix_right_data,0.0
dataset.tuning_parameters.mix_parameters[2].ch_n,2
dataset.tuning_parameters.mix_parameters[2].mix_left_data,0.0
dataset.tuning_parameters.mix_parameters[2].mix_right_data,0.0
@ -19,16 +19,16 @@ dataset.tuning_parameters.mix_parameters[4].mix_right_data,0.0
dataset.tuning_parameters.mix_parameters[5].ch_n,5
dataset.tuning_parameters.mix_parameters[5].mix_left_data,0.0
dataset.tuning_parameters.mix_parameters[5].mix_right_data,0.0
dataset.tuning_parameters.eq_parameters[0].fc,100.0
dataset.tuning_parameters.eq_parameters[0].q,0.7
dataset.tuning_parameters.eq_parameters[0].gain,2.0
dataset.tuning_parameters.eq_parameters[0].slope,12
dataset.tuning_parameters.eq_parameters[0].filterType,1
dataset.tuning_parameters.eq_parameters[1].fc,200.0
dataset.tuning_parameters.eq_parameters[1].q,1.0
dataset.tuning_parameters.eq_parameters[1].gain,-3.0
dataset.tuning_parameters.eq_parameters[1].slope,6
dataset.tuning_parameters.eq_parameters[1].filterType,2
dataset.tuning_parameters.eq_parameters[0].fc,10.0
dataset.tuning_parameters.eq_parameters[0].q,10.0
dataset.tuning_parameters.eq_parameters[0].gain,10.0
dataset.tuning_parameters.eq_parameters[0].slope,10.0
dataset.tuning_parameters.eq_parameters[0].filterType,0
dataset.tuning_parameters.eq_parameters[1].fc,0.0
dataset.tuning_parameters.eq_parameters[1].q,0.0
dataset.tuning_parameters.eq_parameters[1].gain,0.0
dataset.tuning_parameters.eq_parameters[1].slope,0
dataset.tuning_parameters.eq_parameters[1].filterType,0
dataset.tuning_parameters.eq_parameters[2].fc,0.0
dataset.tuning_parameters.eq_parameters[2].q,0.0
dataset.tuning_parameters.eq_parameters[2].gain,0.0
@ -119,11 +119,11 @@ dataset.tuning_parameters.eq_parameters[19].q,0.0
dataset.tuning_parameters.eq_parameters[19].gain,0.0
dataset.tuning_parameters.eq_parameters[19].slope,0
dataset.tuning_parameters.eq_parameters[19].filterType,0
dataset.tuning_parameters.eq_parameters[20].fc,1000.0
dataset.tuning_parameters.eq_parameters[20].q,1.4
dataset.tuning_parameters.eq_parameters[20].gain,-3.0
dataset.tuning_parameters.eq_parameters[20].slope,6
dataset.tuning_parameters.eq_parameters[20].filterType,2
dataset.tuning_parameters.eq_parameters[20].fc,0.0
dataset.tuning_parameters.eq_parameters[20].q,0.0
dataset.tuning_parameters.eq_parameters[20].gain,0.0
dataset.tuning_parameters.eq_parameters[20].slope,0
dataset.tuning_parameters.eq_parameters[20].filterType,0
dataset.tuning_parameters.eq_parameters[21].fc,0.0
dataset.tuning_parameters.eq_parameters[21].q,0.0
dataset.tuning_parameters.eq_parameters[21].gain,0.0
@ -430,7 +430,6 @@ dataset.tuning_parameters.eq_parameters[81].gain,0.0
dataset.tuning_parameters.eq_parameters[81].slope,0
dataset.tuning_parameters.eq_parameters[81].filterType,0
dataset.tuning_parameters.eq_parameters[82].fc,0.0
dataset.tuning_parameters.eq_parameters[82].fc,0.0
dataset.tuning_parameters.eq_parameters[82].q,0.0
dataset.tuning_parameters.eq_parameters[82].gain,0.0
dataset.tuning_parameters.eq_parameters[82].slope,0
@ -621,9 +620,9 @@ dataset.tuning_parameters.eq_parameters[119].gain,0.0
dataset.tuning_parameters.eq_parameters[119].slope,0
dataset.tuning_parameters.eq_parameters[119].filterType,0
dataset.tuning_parameters.delay_parameters[0].ch_n,0
dataset.tuning_parameters.delay_parameters[0].delay_data,0.05
dataset.tuning_parameters.delay_parameters[0].delay_data,10.0
dataset.tuning_parameters.delay_parameters[1].ch_n,1
dataset.tuning_parameters.delay_parameters[1].delay_data,0.1
dataset.tuning_parameters.delay_parameters[1].delay_data,0.0
dataset.tuning_parameters.delay_parameters[2].ch_n,2
dataset.tuning_parameters.delay_parameters[2].delay_data,0.0
dataset.tuning_parameters.delay_parameters[3].ch_n,3
@ -633,9 +632,9 @@ dataset.tuning_parameters.delay_parameters[4].delay_data,0.0
dataset.tuning_parameters.delay_parameters[5].ch_n,5
dataset.tuning_parameters.delay_parameters[5].delay_data,0.0
dataset.tuning_parameters.volume_parameters[0].ch_n,0
dataset.tuning_parameters.volume_parameters[0].vol_data,-3.0
dataset.tuning_parameters.volume_parameters[0].vol_data,10.0
dataset.tuning_parameters.volume_parameters[1].ch_n,1
dataset.tuning_parameters.volume_parameters[1].vol_data,-6.0
dataset.tuning_parameters.volume_parameters[1].vol_data,0.0
dataset.tuning_parameters.volume_parameters[2].ch_n,2
dataset.tuning_parameters.volume_parameters[2].vol_data,0.0
dataset.tuning_parameters.volume_parameters[3].ch_n,3
@ -643,4 +642,4 @@ dataset.tuning_parameters.volume_parameters[3].vol_data,0.0
dataset.tuning_parameters.volume_parameters[4].ch_n,4
dataset.tuning_parameters.volume_parameters[4].vol_data,0.0
dataset.tuning_parameters.volume_parameters[5].ch_n,5
dataset.tuning_parameters.volume_parameters[5].vol_data,0.0
dataset.tuning_parameters.volume_parameters[5].vol_data,0.0
1 parameter value
2 dataset.audio_mode 0
3 dataset.send_action 0
4 dataset.tuning_parameters.mix_parameters[0].ch_n 0
5 dataset.tuning_parameters.mix_parameters[0].mix_left_data 0.7 1.0
6 dataset.tuning_parameters.mix_parameters[0].mix_right_data 0.3 1.0
7 dataset.tuning_parameters.mix_parameters[1].ch_n 1
8 dataset.tuning_parameters.mix_parameters[1].mix_left_data 0.5 0.0
9 dataset.tuning_parameters.mix_parameters[1].mix_right_data 0.5 0.0
10 dataset.tuning_parameters.mix_parameters[2].ch_n 2
11 dataset.tuning_parameters.mix_parameters[2].mix_left_data 0.0
12 dataset.tuning_parameters.mix_parameters[2].mix_right_data 0.0
19 dataset.tuning_parameters.mix_parameters[5].ch_n 5
20 dataset.tuning_parameters.mix_parameters[5].mix_left_data 0.0
21 dataset.tuning_parameters.mix_parameters[5].mix_right_data 0.0
22 dataset.tuning_parameters.eq_parameters[0].fc 100.0 10.0
23 dataset.tuning_parameters.eq_parameters[0].q 0.7 10.0
24 dataset.tuning_parameters.eq_parameters[0].gain 2.0 10.0
25 dataset.tuning_parameters.eq_parameters[0].slope 12 10.0
26 dataset.tuning_parameters.eq_parameters[0].filterType 1 0
27 dataset.tuning_parameters.eq_parameters[1].fc 200.0 0.0
28 dataset.tuning_parameters.eq_parameters[1].q 1.0 0.0
29 dataset.tuning_parameters.eq_parameters[1].gain -3.0 0.0
30 dataset.tuning_parameters.eq_parameters[1].slope 6 0
31 dataset.tuning_parameters.eq_parameters[1].filterType 2 0
32 dataset.tuning_parameters.eq_parameters[2].fc 0.0
33 dataset.tuning_parameters.eq_parameters[2].q 0.0
34 dataset.tuning_parameters.eq_parameters[2].gain 0.0
119 dataset.tuning_parameters.eq_parameters[19].gain 0.0
120 dataset.tuning_parameters.eq_parameters[19].slope 0
121 dataset.tuning_parameters.eq_parameters[19].filterType 0
122 dataset.tuning_parameters.eq_parameters[20].fc 1000.0 0.0
123 dataset.tuning_parameters.eq_parameters[20].q 1.4 0.0
124 dataset.tuning_parameters.eq_parameters[20].gain -3.0 0.0
125 dataset.tuning_parameters.eq_parameters[20].slope 6 0
126 dataset.tuning_parameters.eq_parameters[20].filterType 2 0
127 dataset.tuning_parameters.eq_parameters[21].fc 0.0
128 dataset.tuning_parameters.eq_parameters[21].q 0.0
129 dataset.tuning_parameters.eq_parameters[21].gain 0.0
430 dataset.tuning_parameters.eq_parameters[81].slope 0
431 dataset.tuning_parameters.eq_parameters[81].filterType 0
432 dataset.tuning_parameters.eq_parameters[82].fc 0.0
dataset.tuning_parameters.eq_parameters[82].fc 0.0
433 dataset.tuning_parameters.eq_parameters[82].q 0.0
434 dataset.tuning_parameters.eq_parameters[82].gain 0.0
435 dataset.tuning_parameters.eq_parameters[82].slope 0
620 dataset.tuning_parameters.eq_parameters[119].slope 0
621 dataset.tuning_parameters.eq_parameters[119].filterType 0
622 dataset.tuning_parameters.delay_parameters[0].ch_n 0
623 dataset.tuning_parameters.delay_parameters[0].delay_data 0.05 10.0
624 dataset.tuning_parameters.delay_parameters[1].ch_n 1
625 dataset.tuning_parameters.delay_parameters[1].delay_data 0.1 0.0
626 dataset.tuning_parameters.delay_parameters[2].ch_n 2
627 dataset.tuning_parameters.delay_parameters[2].delay_data 0.0
628 dataset.tuning_parameters.delay_parameters[3].ch_n 3
632 dataset.tuning_parameters.delay_parameters[5].ch_n 5
633 dataset.tuning_parameters.delay_parameters[5].delay_data 0.0
634 dataset.tuning_parameters.volume_parameters[0].ch_n 0
635 dataset.tuning_parameters.volume_parameters[0].vol_data -3.0 10.0
636 dataset.tuning_parameters.volume_parameters[1].ch_n 1
637 dataset.tuning_parameters.volume_parameters[1].vol_data -6.0 0.0
638 dataset.tuning_parameters.volume_parameters[2].ch_n 2
639 dataset.tuning_parameters.volume_parameters[2].vol_data 0.0
640 dataset.tuning_parameters.volume_parameters[3].ch_n 3
642 dataset.tuning_parameters.volume_parameters[4].ch_n 4
643 dataset.tuning_parameters.volume_parameters[4].vol_data 0.0
644 dataset.tuning_parameters.volume_parameters[5].ch_n 5
645 dataset.tuning_parameters.volume_parameters[5].vol_data 0.0

View File

@ -1,20 +1,20 @@
{
"name": "test_project",
"created_at": "2025-02-25T10:30:00",
"last_modified": "2025-02-25T14:45:00",
"description": "这是一个测试项目",
"params": {
"param1": {
"name": "param1",
"created_at": "2025-02-25T11:00:00",
"description": "这是第一个参数配置",
"channels": {}
},
"param2": {
"name": "param2",
"created_at": "2025-02-25T13:30:00",
"description": "这是第二个参数配置",
"channels": {}
}
"name": "aaa",
"created_at": "2025-02-25T10:30:00",
"last_modified": "2025-02-25T23:49:56.152782",
"description": "123",
"params": {
"param1": {
"name": "abc",
"created_at": "2025-02-25T11:00:00",
"description": "这是第一个参数配置",
"channels": {}
},
"param2": {
"name": "abcd",
"created_at": "2025-02-25T13:30:00",
"description": "这是第二个参数配置",
"channels": {}
}
}
}
}

View File

@ -223,7 +223,10 @@ class DataStore:
with open(file_path, 'r', encoding='utf-8') as f:
data = json.load(f)
return ProjectData(**data)
project_data = ProjectData(**data)
return project_data
except Exception as e:
logger.error(f"加载项目失败: {e}")
return None
@ -253,10 +256,12 @@ class DataStore:
channel_data = {}
# 处理混音参数
# to do:后续处理这个6
for i in range(6): # 假设最多6个通道
ch_key = f'dataset.tuning_parameters.mix_parameters[{i}].ch_n'
if ch_key in param_data:
channel_id = int(param_data[ch_key])
# 将字符串先转为浮点数,再转为整数,避免小数点导致的转换错误
channel_id = int(float(param_data[ch_key]))
if channel_id not in channel_data:
channel_data[channel_id] = {'filters': []}
@ -274,7 +279,8 @@ class DataStore:
for i in range(6):
ch_key = f'dataset.tuning_parameters.delay_parameters[{i}].ch_n'
if ch_key in param_data:
channel_id = int(param_data[ch_key])
# 同样先转为浮点数再转为整数
channel_id = int(float(param_data[ch_key]))
if channel_id not in channel_data:
channel_data[channel_id] = {'filters': []}
@ -286,7 +292,8 @@ class DataStore:
for i in range(6):
ch_key = f'dataset.tuning_parameters.volume_parameters[{i}].ch_n'
if ch_key in param_data:
channel_id = int(param_data[ch_key])
# 同样先转为浮点数再转为整数
channel_id = int(float(param_data[ch_key]))
if channel_id not in channel_data:
channel_data[channel_id] = {'filters': []}
@ -323,11 +330,13 @@ class DataStore:
slope_key = f'dataset.tuning_parameters.eq_parameters[{i}].slope'
if slope_key in param_data:
filter_data['slope'] = int(param_data[slope_key])
# 先转为浮点数再转为整数
filter_data['slope'] = int(float(param_data[slope_key]))
filter_type_key = f'dataset.tuning_parameters.eq_parameters[{i}].filterType'
if filter_type_key in param_data:
filter_data['filterType'] = int(param_data[filter_type_key])
# 先转为浮点数再转为整数
filter_data['filterType'] = int(float(param_data[filter_type_key]))
return channel_data

View File

@ -109,6 +109,39 @@ class DataStoreManager:
except Exception as e:
return False
def update_project(self, project_name: str, project_data: Dict) -> bool:
"""更新项目数据"""
try:
# 将字典转换为ProjectData对象
from persistence.models import ProjectData
from dataclasses import asdict
# 如果传入的是字典需要转换为ProjectData对象
if isinstance(project_data, dict):
# 确保params是字典而不是列表
if 'params' in project_data and not isinstance(project_data['params'], dict):
project_data['params'] = {}
# 创建ProjectData对象
from persistence.models import ProjectData
project_data_obj = ProjectData(**project_data)
else:
project_data_obj = project_data
# 更新最后修改时间
from datetime import datetime
project_data_obj.last_modified = datetime.now().isoformat()
# 保存项目元数据
self._store._save_project_metadata(project_name, project_data_obj)
return True
except Exception as e:
from component.widget_log.log_handler import logger
logger.error(f"更新项目失败: {e}")
import traceback
logger.error(traceback.format_exc())
return False
@classmethod
def get_instance(cls) -> 'DataStoreManager':
"""获取 DataStoreManager 实例"""