From eae7e2178bb3a87bb4c82536c77e39d5be895674 Mon Sep 17 00:00:00 2001 From: Steven Dan Date: Tue, 31 Mar 2026 10:58:58 +0800 Subject: [PATCH] update eq_flash_storage --- .../src/extensions/eq_flash_storage.c | 429 +++++++++--------- 1 file changed, 214 insertions(+), 215 deletions(-) diff --git a/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq_flash_storage.c b/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq_flash_storage.c index 4fcf7ff..5501452 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq_flash_storage.c +++ b/sw_usb_audio/app_usb_aud_phaten_golden_6ch/src/extensions/eq_flash_storage.c @@ -101,7 +101,7 @@ static eq_mode_data_t (*get_eq_array_ptr(uint32_t sample_rate))[NUM_EQ_MODES][NU */ static int verify_file_header(const eq_file_header_t *header, uint8_t mode, uint8_t channel) { if (!header) return 0; - + return (header->magic == EQ_FLASH_MAGIC && header->version == EQ_FLASH_VERSION && header->mode == mode && @@ -115,9 +115,9 @@ static int verify_file_header(const eq_file_header_t *header, uint8_t mode, uint */ static int create_eq_directory_structure(void) { char dir_path[64]; - + DPRINTF("Creating EQ directory structure (on-demand)\n"); - + // 检查主目录是否存在,不存在才创建 // 改动原因:使用全局变量代替硬编码目录名,支持不同产品 if (!lfs_file_exists(g_eq_flash_base_dir)) { @@ -126,10 +126,10 @@ static int create_eq_directory_structure(void) { } else { DPRINTF("%s directory already exists\n", g_eq_flash_base_dir); } - + // 不再为每个采样率创建子目录,因为同一模式的参数是相同的 DPRINTF("EQ parameters will be stored without sample rate grouping\n"); - + DPRINTF("EQ directory structure creation completed\n"); return 0; } @@ -146,18 +146,18 @@ static int create_eq_directory_structure(void) { */ int eq_flash_init(void) { DPRINTF("Initializing EQ Flash storage system\n"); - + // 初始化存储状态 memset(&storage_status, 0, sizeof(storage_status)); memset(dirty_flags, 0, sizeof(dirty_flags)); - + // 延迟一段时间,确保QSPI Flash已经初始化完成 delay_milliseconds(100); - + // 尝试初始化LFS,最多重试3次 int retry_count = 0; int lfs_init_result = -1; - + while (retry_count < 3 && lfs_init_result != 0) { lfs_init_result = lfs_init(); if (lfs_init_result != 0) { @@ -168,7 +168,7 @@ int eq_flash_init(void) { } } } - + if (lfs_init_result != 0) { DPRINTF("Failed to initialize LFS after %d retries, continuing without Flash storage\n", retry_count); // 即使LFS初始化失败,也标记为已初始化,系统继续运行 @@ -176,19 +176,19 @@ int eq_flash_init(void) { storage_status.has_flash_data = 0; return 0; } - + DPRINTF("LFS initialized successfully\n"); - + // 创建目录结构(按需创建) create_eq_directory_structure(); - + // 检查是否有现有数据(通过检查目录是否存在) // 改动原因:使用全局变量代替硬编码目录名 storage_status.has_flash_data = lfs_file_exists(g_eq_flash_base_dir) ? 1 : 0; storage_status.is_initialized = 1; - + DPRINTF("EQ Flash storage initialized, has_data: %d\n", storage_status.has_flash_data); - + lfs_deinit(); return 0; } @@ -241,24 +241,24 @@ static void init_eq_data_defaults(eq_mode_data_t *eq_data, uint32_t sample_rate) int eq_flash_load_mode(uint8_t mode) { //DPRINTF("Loading EQ mode %d from Flash\n", mode); - + if (!storage_status.is_initialized) { DPRINTF(" Error: EQ Flash storage not initialized\n"); return -1; } - + if (mode >= NUM_EQ_MODES) { DPRINTF(" Error: Invalid mode %d (max: %d)\n", mode, NUM_EQ_MODES - 1); return -1; } - + // 获取当前采样率的EQ数组指针 eq_mode_data_t (*eq_array)[NUM_EQ_MODES][NUM_EQ_CHANS] = get_eq_array_ptr(g_eq_sample_rate); if (!eq_array) { DPRINTF(" Error: Failed to get EQ array for current sample rate %lu\n", (unsigned long)g_eq_sample_rate); return -1; } - + // 加载左右两个声道的数据 for (int ch = 0; ch < NUM_EQ_CHANS; ch++) { // 构建文件路径 @@ -266,7 +266,7 @@ int eq_flash_load_mode(uint8_t mode) { char file_path[FILE_PATH_MAX_LENGTH]; snprintf(file_path, sizeof(file_path), "%s/mode%d_ch%d.bin", g_eq_flash_base_dir, mode, ch); DPRINTF(" File path (channel %d): %s\n", ch, file_path); - + // 检查文件是否存在 if (!lfs_file_exists(file_path)) { DPRINTF(" ****************** file is not exist (ch %d), initializing with default values\n", ch); @@ -274,12 +274,12 @@ int eq_flash_load_mode(uint8_t mode) { DPRINTF(" Initialized with default values for mode %d, channel %d\n", mode, ch); continue; // 继续处理下一个通道 } - + // 准备读取缓冲区 eq_file_header_t header; eq_flash_data_t flash_data; uint8_t file_data[sizeof(header) + sizeof(flash_data)]; - + // 使用lfs_read_config读取文件 DPRINTF(" Read file data, size: %zu bytes\n", sizeof(file_data)); lfs_read_config(file_path, file_data, sizeof(file_data)); @@ -287,25 +287,25 @@ int eq_flash_load_mode(uint8_t mode) { // 解析文件数据 memcpy(&header, file_data, sizeof(header)); memcpy(&flash_data, file_data + sizeof(header), sizeof(flash_data)); - + // 检查文件头基本信息 - DPRINTF(" File header: magic=0x%08X, version=%u, mode=%u\n", + DPRINTF(" File header: magic=0x%08X, version=%u, mode=%u\n", header.magic, header.version, header.mode); - + // 验证文件头 DPRINTF(" Verifying file header:\n"); - DPRINTF(" Expected: magic=0x%08X, version=%u, mode=%u, channel=%d, data_size=%zu\n", + DPRINTF(" Expected: magic=0x%08X, version=%u, mode=%u, channel=%d, data_size=%zu\n", EQ_FLASH_MAGIC, EQ_FLASH_VERSION, mode, ch, sizeof(eq_flash_data_t)); - DPRINTF(" Actual: magic=0x%08X, version=%u, mode=%u, channel=%u, data_size=%u\n", + DPRINTF(" Actual: magic=0x%08X, version=%u, mode=%u, channel=%u, data_size=%u\n", header.magic, header.version, header.mode, header.channel, header.data_size); - + if (!verify_file_header(&header, mode, ch)) { DPRINTF(" Invalid file header for mode %d, channel %d\n", mode, ch); init_eq_data_defaults(&(*eq_array)[mode][ch], g_eq_sample_rate); DPRINTF(" Initialized with default values for mode %d, channel %d\n", mode, ch); continue; // 继续处理下一个通道 } - + // 验证CRC32 uint32_t calculated_crc = eq_flash_calculate_crc32((uint8_t*)&flash_data, sizeof(flash_data)); if (calculated_crc != header.crc32) { @@ -314,70 +314,70 @@ int eq_flash_load_mode(uint8_t mode) { DPRINTF(" Initialized with default values due to CRC32 mismatch for channel %d\n", ch); continue; // 继续处理下一个通道 } - + // 将Flash数据加载到EQ数组 eq_mode_data_t *eq_data = &(*eq_array)[mode][ch]; - + // 检查Flash数据的完整性 - DPRINTF(" Flash data before restore (ch %d): active_bands_count=%d\n", + DPRINTF(" Flash data before restore (ch %d): active_bands_count=%d\n", ch, flash_data.active_bands_count); - - DPRINTF(" EQ array after copy (ch %d): sample_rate=%u, post_gain_db=%ld\n", + + DPRINTF(" EQ array after copy (ch %d): sample_rate=%u, post_gain_db=%ld\n", ch, eq_data->sample_rate, (long)eq_data->post_gain_db); - DPRINTF(" EQ array total_bshift=%ld\n", + DPRINTF(" EQ array total_bshift=%ld\n", (long)eq_data->total_bshift); - - + + // 检查内存地址是否有效 if (eq_data == NULL) { DPRINTF(" ERROR: eq_data is NULL\n"); continue; // 继续处理下一个通道 } - + DPRINTF(" eq_data address: %p\n", (void*)eq_data); DPRINTF(" eq_data size: %zu bytes\n", sizeof(eq_mode_data_t)); - + // 检查bands数组地址是否有效 DPRINTF(" bands array address: %p\n", (void*)&eq_data->bands); DPRINTF(" bands array size: %zu bytes\n", sizeof(eq_data->bands)); - + // 检查bands数组偏移量 DPRINTF(" bands offset in struct: %zu bytes\n", (size_t)&eq_data->bands - (size_t)eq_data); - + // 检查第一个band的地址 DPRINTF(" bands[0] address: %p\n", (void*)&eq_data->bands[0]); DPRINTF(" bands[0] size: %zu bytes\n", sizeof(eq_data->bands[0])); - + // 检查内存对齐 DPRINTF(" eq_data alignment: %zu\n", (size_t)eq_data % 4); DPRINTF(" bands alignment: %zu\n", (size_t)&eq_data->bands % 4); - + // 尝试安全地访问第一个band DPRINTF(" Attempting to access bands[0]...\n"); - + // 先检查bands[0]的地址是否在合理范围内 - if ((size_t)&eq_data->bands[0] < (size_t)eq_data || + if ((size_t)&eq_data->bands[0] < (size_t)eq_data || (size_t)&eq_data->bands[0] > (size_t)eq_data + sizeof(eq_mode_data_t)) { DPRINTF(" ERROR: bands[0] address out of range\n"); continue; // 继续处理下一个通道 } - + // 暂时注释掉有问题的调试代码 DPRINTF(" Accessing bands[0].index...\n"); DPRINTF(" bands[0].index = %d\n", eq_data->bands[0].index); - + DPRINTF(" Accessing bands[0].type...\n"); DPRINTF(" bands[0].type = %d\n", eq_data->bands[0].type); - + DPRINTF(" Accessing bands[0].fc...\n"); DPRINTF(" bands[0].fc = %d.%02d Hz\n", (int)eq_data->bands[0].fc, (int)((eq_data->bands[0].fc - (int)eq_data->bands[0].fc) * 100)); - + DPRINTF(" Accessing bands[0].q...\n"); DPRINTF(" bands[0].q = %d.%04d\n", (int)eq_data->bands[0].q, (int)((eq_data->bands[0].q - (int)eq_data->bands[0].q) * 10000)); - + DPRINTF(" Successfully loaded EQ parameters for mode %d, channel %d\n", mode, ch); } - + return 0; } @@ -388,16 +388,16 @@ int eq_flash_load_mode(uint8_t mode) { */ int is_filter_bypass(const filter_params_t *band) { if (band == NULL) return 1; - + // 检查是否为bypass类型 if (band->type != FILTER_TYPE_BYPASS) return 0; - + // 检查其他参数是否为默认值 if (band->fc != 1000.0f) return 0; if (band->q != 0.707f) return 0; if (band->bw != 1.0f) return 0; if (band->gain != 0.0f) return 0; - + return 1; } @@ -409,9 +409,9 @@ int is_filter_bypass(const filter_params_t *band) { */ int extract_active_filters(const eq_mode_data_t *eq_data, eq_flash_data_t *flash_data) { if (eq_data == NULL || flash_data == NULL) return -1; - + flash_data->active_bands_count = 0; - + // 遍历所有滤波器,只保存非bypass的 for (int i = 0; i < MAX_EQ_BANDS; i++) { if (!is_filter_bypass(&eq_data->bands[i])) { @@ -419,17 +419,17 @@ int extract_active_filters(const eq_mode_data_t *eq_data, eq_flash_data_t *flash DPRINTF(" Warning: Too many active filters, truncating\n"); break; } - + // 复制非默认滤波器 flash_data->active_bands[flash_data->active_bands_count] = eq_data->bands[i]; flash_data->active_bands[flash_data->active_bands_count].index = flash_data->active_bands_count; flash_data->active_bands_count++; } } - - DPRINTF(" Extracted %d active filters from %d total filters\n", + + DPRINTF(" Extracted %d active filters from %d total filters\n", flash_data->active_bands_count, MAX_EQ_BANDS); - + return 0; } @@ -441,7 +441,7 @@ int extract_active_filters(const eq_mode_data_t *eq_data, eq_flash_data_t *flash */ int restore_eq_from_flash(const eq_flash_data_t *flash_data, eq_mode_data_t *eq_data) { if (flash_data == NULL || eq_data == NULL) return -1; - + // 初始化所有滤波器为bypass for (int i = 0; i < MAX_EQ_BANDS; i++) { eq_data->bands[i].index = i; @@ -451,7 +451,7 @@ int restore_eq_from_flash(const eq_flash_data_t *flash_data, eq_mode_data_t *eq_ eq_data->bands[i].bw = 1.0f; eq_data->bands[i].gain = 0.0f; } - + // 恢复非默认滤波器 for (int i = 0; i < flash_data->active_bands_count && i < MAX_EQ_BANDS; i++) { int target_index = flash_data->active_bands[i].index; @@ -459,9 +459,9 @@ int restore_eq_from_flash(const eq_flash_data_t *flash_data, eq_mode_data_t *eq_ eq_data->bands[target_index] = flash_data->active_bands[i]; } } - + DPRINTF(" Restored %d active filters to EQ data\n", flash_data->active_bands_count); - + return 0; } @@ -473,12 +473,12 @@ int restore_eq_from_flash(const eq_flash_data_t *flash_data, eq_mode_data_t *eq_ */ int eq_single_param_database_init(void) { DPRINTF("Initializing single parameter storage database\n"); - + memset(&single_param_database, 0, sizeof(single_param_database)); single_param_database.max_params = MAX_EQ_BANDS * 8 * 2; // 最多8个模式×2通道的所有参数 single_param_database.param_count = 0; single_param_database.last_save_time = 0; - + DPRINTF(" Single parameter database initialized: max_params=%d\n", single_param_database.max_params); return 0; } @@ -494,7 +494,7 @@ int eq_process_single_param_change(uint32_t sample_rate, uint8_t mode, uint8_t c if (eq_add_single_param(sample_rate, mode, channel, band_index, band) == 0) { // 标记为脏数据 dirty_flags[mode] = 1; - + return 0; } else { return -1; @@ -509,14 +509,14 @@ int eq_process_single_param_change(uint32_t sample_rate, uint8_t mode, uint8_t c */ int eq_single_params_different(const filter_params_t *old_params, const filter_params_t *new_params) { if (old_params == NULL || new_params == NULL) return 1; - + // 比较各个字段 if (old_params->type != new_params->type) return 1; if (fabsf(old_params->fc - new_params->fc) > 0.01f) return 1; if (fabsf(old_params->q - new_params->q) > 0.0001f) return 1; if (fabsf(old_params->bw - new_params->bw) > 0.01f) return 1; if (fabsf(old_params->gain - new_params->gain) > 0.01f) return 1; - + return 0; } @@ -529,16 +529,16 @@ int eq_single_params_different(const filter_params_t *old_params, const filter_p * @param new_params 新参数 * @return 0: 成功, -1: 失败 */ -int eq_add_single_param(uint32_t sample_rate, uint8_t mode, uint8_t channel, +int eq_add_single_param(uint32_t sample_rate, uint8_t mode, uint8_t channel, uint8_t band_index, const filter_params_t *new_params) { if (new_params == NULL) return -1; - + // 检查是否已存在相同的参数记录 for (int i = 0; i < single_param_database.param_count; i++) { eq_single_param_t *param = &single_param_database.params[i]; - if (param->sample_rate == sample_rate && - param->mode == mode && - param->channel == channel && + if (param->sample_rate == sample_rate && + param->mode == mode && + param->channel == channel && param->band_index == band_index) { // 更新现有记录 param->params = *new_params; @@ -549,16 +549,16 @@ int eq_add_single_param(uint32_t sample_rate, uint8_t mode, uint8_t channel, return 0; } } - + // 检查数据库是否已满 if (single_param_database.param_count >= single_param_database.max_params) { DPRINTF(" Warning: Single parameter database full, overwriting oldest entry\n"); // 移动所有条目向前一位,覆盖最旧的 - memmove(&single_param_database.params[0], &single_param_database.params[1], + memmove(&single_param_database.params[0], &single_param_database.params[1], (single_param_database.max_params - 1) * sizeof(eq_single_param_t)); single_param_database.param_count--; } - + // 添加新参数 eq_single_param_t *param = &single_param_database.params[single_param_database.param_count]; param->sample_rate = sample_rate; @@ -568,12 +568,12 @@ int eq_add_single_param(uint32_t sample_rate, uint8_t mode, uint8_t channel, param->params = *new_params; param->timestamp = get_reference_time(); param->is_dirty = 1; - + single_param_database.param_count++; - + DPRINTF(" Added single parameter: rate=%u, mode=%d, ch=%d, band=%d, count=%d\n", sample_rate, mode, channel, band_index, single_param_database.param_count); - + return 0; } @@ -591,18 +591,18 @@ int eq_save_single_param(uint32_t sample_rate, uint8_t mode, uint8_t channel, ui } DPRINTF("Saving single parameter to Flash: mode=%d, ch=%d, band=%d (applying to all sample rates)\n", mode, channel, band_index); - + if (!storage_status.is_initialized) { DPRINTF(" Error: Flash storage not initialized\n"); return -1; } - + // 构建单个参数文件路径 - 简化格式:只存储mode和band信息 // 改动原因:使用全局变量代替硬编码目录名,统一文件路径管理 char file_path[FILE_PATH_MAX_LENGTH]; - snprintf(file_path, sizeof(file_path), "%s/mode%d_band%d.bin", + snprintf(file_path, sizeof(file_path), "%s/mode%d_band%d.bin", g_eq_flash_base_dir, mode, band_index); - + // 改动原因:优化EQ参数存储策略,统一参数源为44100Hz // 保存参数时,总是从44100Hz读取参数,确保参数一致性 eq_mode_data_t (*eq_array)[NUM_EQ_MODES][NUM_EQ_CHANS] = get_eq_array_ptr(44100); @@ -610,10 +610,10 @@ int eq_save_single_param(uint32_t sample_rate, uint8_t mode, uint8_t channel, ui DPRINTF(" Error: Failed to get EQ array for sample rate 44100 (unified source)\n"); return -1; } - + // 从44100Hz统一参数源读取参数 filter_params_t *param = &(*eq_array)[mode][channel].bands[band_index]; - + // 创建文件头 eq_file_header_t header; header.magic = EQ_FLASH_MAGIC; @@ -623,22 +623,22 @@ int eq_save_single_param(uint32_t sample_rate, uint8_t mode, uint8_t channel, ui header.reserved = band_index; // 使用reserved字段存储band_index header.data_size = sizeof(filter_params_t); header.crc32 = eq_flash_calculate_crc32((uint8_t*)param, sizeof(filter_params_t)); - + // 创建文件数据 uint8_t file_data[sizeof(header) + sizeof(filter_params_t)]; memcpy(file_data, &header, sizeof(header)); memcpy(file_data + sizeof(header), param, sizeof(filter_params_t)); - + // 写入文件 lfs_write_config(file_path, file_data, sizeof(file_data)); - + DPRINTF(" Successfully saved single parameter to %s\n", file_path); - + // 改动原因:优化EQ参数存储策略,参数保存后需要同步到44100Hz并更新所有采样率 // 确保44100Hz作为统一参数源,然后通过copy_params_from_44100函数同步到其他采样率 // 注意:这里只保存参数,系数会在切换采样率时动态计算 // 参数已经保存到Flash,加载时会自动应用到所有采样率 - + return 0; } @@ -656,38 +656,38 @@ int eq_load_single_param(uint32_t sample_rate, uint8_t mode, uint8_t channel, ui } DPRINTF("Loading single parameter from Flash: mode=%d, ch=%d, band=%d (applying to all sample rates)\n", mode, channel, band_index); - + if (!storage_status.is_initialized) { DPRINTF(" Error: Flash storage not initialized\n"); return -1; } - + // 构建单个参数文件路径 - 简化格式:只存储mode和band信息 // 改动原因:使用全局变量代替硬编码目录名,统一文件路径管理 char file_path[FILE_PATH_MAX_LENGTH]; - snprintf(file_path, sizeof(file_path), "%s/mode%d_band%d.bin", + snprintf(file_path, sizeof(file_path), "%s/mode%d_band%d.bin", g_eq_flash_base_dir, mode, band_index); - + // 检查文件是否存在 if (!lfs_file_exists(file_path)) { DPRINTF(" Single parameter file does not exist: %s\n", file_path); return -1; } - + // 准备读取缓冲区 eq_file_header_t header; filter_params_t param; uint8_t file_data[sizeof(header) + sizeof(filter_params_t)]; - + // 读取文件 lfs_read_config(file_path, file_data, sizeof(file_data)); - + // 解析文件数据 memcpy(&header, file_data, sizeof(header)); memcpy(¶m, file_data + sizeof(header), sizeof(filter_params_t)); - + // 验证文件头 - if (header.magic != EQ_FLASH_MAGIC || + if (header.magic != EQ_FLASH_MAGIC || header.version != EQ_FLASH_VERSION || header.mode != mode || header.channel != 0 || // 固定验证channel为0 @@ -695,14 +695,14 @@ int eq_load_single_param(uint32_t sample_rate, uint8_t mode, uint8_t channel, ui DPRINTF(" Error: Invalid single parameter file header\n"); return -1; } - + // 验证CRC32 uint32_t calculated_crc = eq_flash_calculate_crc32((uint8_t*)¶m, sizeof(filter_params_t)); if (calculated_crc != header.crc32) { DPRINTF(" Error: CRC32 mismatch for single parameter\n"); return -1; } - + // 为所有采样率应用参数到两个通道并计算系数 for (int i = 0; i < EQ_FLASH_MAX_SAMPLE_RATES; i++) { uint32_t fs = supported_sample_rates[i]; @@ -713,7 +713,7 @@ int eq_load_single_param(uint32_t sample_rate, uint8_t mode, uint8_t channel, ui (*eq_array)[mode][1].bands[band_index] = param; } } - + return 0; } @@ -723,30 +723,30 @@ int eq_load_single_param(uint32_t sample_rate, uint8_t mode, uint8_t channel, ui */ int eq_save_dirty_params(void) { //DPRINTF("Saving dirty single parameters to Flash\n"); - + if (!storage_status.is_initialized) { DPRINTF(" Error: Flash storage not initialized\n"); return -1; } - + //DPRINTF(" Single param database count: %d\n", single_param_database.param_count); - + int saved_count = 0; - + // 遍历所有脏参数,但只保存一次(不按采样率分组) bool saved_params[EQ_FLASH_MAX_MODES][NUM_EQ_CHANS][MAX_EQ_BANDS] = {0}; // 记录已保存的参数 - + for (int i = 0; i < single_param_database.param_count; i++) { eq_single_param_t *param = &single_param_database.params[i]; - + DPRINTF(" Checking param %d: mode=%d, ch=%d, band=%d, dirty=%d\n", i, param->mode, param->channel, param->band_index, param->is_dirty); - + if (param->is_dirty && !saved_params[param->mode][param->channel][param->band_index]) { DPRINTF(" Saving dirty single parameter: mode=%d, ch=%d, band=%d (applying to all sample rates)\n", param->mode, param->channel, param->band_index); if (param->mode < EQ_USER_MODE_MIN || param->mode > EQ_USER_MODE_MAX ) { - printf(" Invalid mode %d, only user modes (%d-%d) can be saved\n", param->mode, EQ_USER_MODE_MIN, EQ_USER_MODE_MAX); + DPRINTF(" Invalid mode %d, only user modes (%d-%d) can be saved\n", param->mode, EQ_USER_MODE_MIN, EQ_USER_MODE_MAX); continue; } if (eq_save_single_param(param->sample_rate, param->mode, param->channel, param->band_index) == 0) { @@ -1193,7 +1193,7 @@ int eq_load_gain_and_names(void) { * @return 0: 成功, -1: 失败 */ int eq_load_all_params_and_calculate_coefficients(uint32_t sample_rate, uint8_t mode) { - //DPRINTF("Loading all parameters and calculating coefficients for rate=%u, mode=%d\n", + //DPRINTF("Loading all parameters and calculating coefficients for rate=%u, mode=%d\n", // sample_rate, mode); if (mode < EQ_USER_MODE_MIN || mode > EQ_USER_MODE_MAX ) { @@ -1203,16 +1203,16 @@ int eq_load_all_params_and_calculate_coefficients(uint32_t sample_rate, uint8_t DPRINTF(" Error: Flash storage not initialized\n"); return -1; } - + // 获取EQ数组指针 eq_mode_data_t (*eq_array)[NUM_EQ_MODES][NUM_EQ_CHANS] = get_eq_array_ptr(sample_rate); if (!eq_array) { DPRINTF(" Error: Failed to get EQ array for sample rate %u\n", sample_rate); return -1; } - + int loaded_count = 0; - + // 简化加载逻辑:只从44100Hz channel 0加载参数,然后应用到所有采样率和通道 for (int band = 0; band < MAX_EQ_BANDS; band++) { if (eq_load_single_param(44100, mode, 0, band) == 0) { @@ -1220,10 +1220,10 @@ int eq_load_all_params_and_calculate_coefficients(uint32_t sample_rate, uint8_t DPRINTF(" Loaded parameter for band %d from 44100Hz channel 0\n", band); } } - - //DPRINTF(" Loaded %d single parameters and calculated coefficients for mode %d\n", + + //DPRINTF(" Loaded %d single parameters and calculated coefficients for mode %d\n", // loaded_count, mode); - + return 0; } @@ -1234,7 +1234,7 @@ int eq_load_all_params_and_calculate_coefficients(uint32_t sample_rate, uint8_t */ int eq_get_single_param_stats(eq_single_param_database_t *stats) { if (stats == NULL) return -1; - + *stats = single_param_database; return 0; } @@ -1245,10 +1245,10 @@ int eq_get_single_param_stats(eq_single_param_database_t *stats) { */ int eq_clear_single_param_database(void) { DPRINTF("Clearing single parameter database\n"); - + memset(&single_param_database, 0, sizeof(single_param_database)); single_param_database.max_params = MAX_EQ_BANDS * 8 * 2; - + DPRINTF(" Single parameter database cleared\n"); return 0; } @@ -1260,24 +1260,24 @@ int eq_clear_single_param_database(void) { */ int eq_flash_save_mode(uint8_t mode) { DPRINTF("Saving EQ mode %d to Flash\n", mode); - + if (!storage_status.is_initialized) { DPRINTF(" Error: EQ Flash storage not initialized\n"); return -1; } - + if (mode >= NUM_EQ_MODES) { DPRINTF(" Error: Invalid mode %d (max: %d)\n", mode, NUM_EQ_MODES - 1); return -1; } - + // 获取当前采样率的EQ数组指针 eq_mode_data_t (*eq_array)[NUM_EQ_MODES][NUM_EQ_CHANS] = get_eq_array_ptr(g_eq_sample_rate); if (!eq_array) { DPRINTF(" Error: Failed to get EQ array for current sample rate %lu\n", (unsigned long)g_eq_sample_rate); return -1; } - + // 保存左右两个声道的数据 for (int ch = 0; ch < NUM_EQ_CHANS; ch++) { // 构建文件路径 @@ -1285,19 +1285,19 @@ int eq_flash_save_mode(uint8_t mode) { char file_path[FILE_PATH_MAX_LENGTH]; snprintf(file_path, sizeof(file_path), "%s/mode%d_ch%d.bin", g_eq_flash_base_dir, mode, ch); DPRINTF(" File path (channel %d): %s\n", ch, file_path); - + // 从EQ数组读取数据 eq_mode_data_t *eq_data = &(*eq_array)[mode][ch]; - DPRINTF(" Reading EQ data from array (ch %d): sample_rate=%u, post_gain_db=%ld\n", + DPRINTF(" Reading EQ data from array (ch %d): sample_rate=%u, post_gain_db=%ld\n", ch, eq_data->sample_rate, (long)eq_data->post_gain_db); - + // 提取非默认滤波器到优化存储格式 eq_flash_data_t flash_data; if (extract_active_filters(eq_data, &flash_data) != 0) { DPRINTF(" Error: Failed to extract active filters\n"); continue; } - + // 准备文件头 eq_file_header_t header; header.magic = EQ_FLASH_MAGIC; @@ -1307,13 +1307,13 @@ int eq_flash_save_mode(uint8_t mode) { header.reserved = 0; header.data_size = sizeof(eq_flash_data_t); header.crc32 = eq_flash_calculate_crc32((uint8_t*)&flash_data, sizeof(eq_flash_data_t)); - + // 创建完整的数据包(文件头 + 优化EQ数据) uint8_t file_data[sizeof(header) + sizeof(eq_flash_data_t)]; uint8_t file_data2[sizeof(header) + sizeof(eq_flash_data_t)]; memcpy(file_data, &header, sizeof(header)); memcpy(file_data + sizeof(header), &flash_data, sizeof(eq_flash_data_t)); - + DPRINTF(" +++++++++++++++ data before save (ch %d) ++++++++++++++ \n", ch); // debug_print_eq_mode(eq_data); DPRINTF(" +++++++++++++++ data before save (ch %d) ++++++++++++++ \n", ch); @@ -1331,7 +1331,7 @@ int eq_flash_save_mode(uint8_t mode) { #endif DPRINTF(" Successfully saved EQ parameters for mode %d, channel %d\n", mode, ch); } - + return 0; } @@ -1353,23 +1353,23 @@ void eq_flash_mark_dirty(uint8_t mode) { */ int eq_flash_sync_mode(uint8_t mode) { DPRINTF("Syncing EQ mode %d to Flash\n", mode); - + if (!storage_status.is_initialized) { DPRINTF("EQ Flash storage not initialized\n"); return -1; } - + if (mode >= NUM_EQ_MODES) { DPRINTF("Invalid mode %d\n", mode); return -1; } - + // 保存指定模式到Flash if (eq_flash_save_mode(mode) != 0) { DPRINTF("Failed to save mode %d to Flash\n", mode); return -1; } - + // 清除脏标志 dirty_flags[mode] = 0; DPRINTF("EQ mode %d synced to Flash\n", mode); @@ -1382,12 +1382,12 @@ int eq_flash_sync_mode(uint8_t mode) { */ int eq_flash_sync_all(void) { DPRINTF("Syncing dirty EQ parameters to Flash\n"); - + if (!storage_status.is_initialized) { DPRINTF("EQ Flash storage not initialized\n"); return -1; } - + // 简化实现 memset(dirty_flags, 0, sizeof(dirty_flags)); DPRINTF("EQ parameters synced to Flash (simplified)\n"); @@ -1421,12 +1421,12 @@ int eq_flash_get_status(eq_storage_status_t *status) { */ int eq_flash_clear_all(void) { DPRINTF("Clearing all EQ Flash data\n"); - + if (!storage_status.is_initialized) { DPRINTF("EQ Flash storage not initialized\n"); return -1; } - + // 简化实现 storage_status.has_flash_data = 0; memset(dirty_flags, 0, sizeof(dirty_flags)); @@ -1441,11 +1441,11 @@ int eq_flash_clear_all(void) { */ int eq_flash_verify_mode(uint8_t mode) { DPRINTF("Verifying EQ mode %d\n", mode); - + if (!storage_status.is_initialized) { return 0; } - + // 简化实现 return 1; } @@ -1509,14 +1509,14 @@ int eq_flash_needs_sync(void) { */ int delete_flash_eq_params(uint8_t mode) { DPRINTF("Deleting Flash EQ params for mode %d\n", mode); - + if (!storage_status.is_initialized) { DPRINTF(" Error: Flash storage not initialized\n"); return -1; } - + int deleted_count = 0; - + if (mode == 0xFF) { // 删除所有模式的参数文件 DPRINTF(" Deleting all mode parameters\n"); @@ -1525,7 +1525,7 @@ int delete_flash_eq_params(uint8_t mode) { // 改动原因:使用全局变量代替硬编码目录名,统一文件路径管理 char file_path[FILE_PATH_MAX_LENGTH]; snprintf(file_path, sizeof(file_path), "%s/mode%d_band%d.bin", g_eq_flash_base_dir, m, band); - + if (lfs_file_exists(file_path)) { if (lfs_remove_file(file_path) == 0) { deleted_count++; @@ -1543,7 +1543,7 @@ int delete_flash_eq_params(uint8_t mode) { // 改动原因:使用全局变量代替硬编码目录名,统一文件路径管理 char file_path[FILE_PATH_MAX_LENGTH]; snprintf(file_path, sizeof(file_path), "%s/mode%d_band%d.bin", g_eq_flash_base_dir, mode, band); - + if (lfs_file_exists(file_path)) { if (lfs_remove_file(file_path) == 0) { deleted_count++; @@ -1554,7 +1554,7 @@ int delete_flash_eq_params(uint8_t mode) { } } } - + DPRINTF(" Deleted %d parameter files\n", deleted_count); return 0; } @@ -1563,7 +1563,7 @@ int delete_flash_eq_params(uint8_t mode) { * @brief 删除Flash中的增益和模式名称文件 * @param mode 模式号 (0-9, 0xFF表示所有模式) * @return 0: 成功, -1: 失败 - * + * * 改动原因:修改为按模式删除,只删除指定模式的增益和名称,而不是删除所有文件 * - 如果mode == 0xFF,删除所有用户模式的增益和名称文件 * - 如果mode是用户模式(6-8),只删除该模式的名称文件,并将该模式的增益恢复为默认值(0) @@ -1571,16 +1571,16 @@ int delete_flash_eq_params(uint8_t mode) { */ int delete_flash_gain_and_names(uint8_t mode) { DPRINTF("Deleting Flash gain and names for mode %d\n", mode); - + if (!storage_status.is_initialized) { DPRINTF(" Error: Flash storage not initialized\n"); return -1; } - + // 处理删除所有模式的情况 if (mode == 0xFF) { DPRINTF(" Deleting all user mode gains and names\n"); - + // 删除gains文件 char file_path[FILE_PATH_MAX_LENGTH]; snprintf(file_path, sizeof(file_path), "%s/%s", g_eq_flash_base_dir, g_eq_flash_gains_file); @@ -1591,7 +1591,7 @@ int delete_flash_gain_and_names(uint8_t mode) { DPRINTF(" Failed to delete gains file: %s\n", file_path); } } - + // 删除所有用户模式的名称文件 for (int i = EQ_USER_MODE_MIN; i <= EQ_USER_MODE_MAX; i++) { snprintf(file_path, sizeof(file_path), "%s/%s%d", g_eq_flash_base_dir, g_eq_flash_name_prefix, i); @@ -1603,22 +1603,22 @@ int delete_flash_gain_and_names(uint8_t mode) { } } } - + return 0; } - + // 检查模式有效性 if (mode >= NUM_EQ_MODES) { DPRINTF(" Error: Invalid mode %d\n", mode); return -1; } - + // 预设模式(0-5)的增益和名称不存储在Flash中,不需要删除 if (mode < EQ_USER_MODE_MIN) { DPRINTF(" Mode %d is a preset mode, no Flash data to delete\n", mode); return 0; } - + // 只处理用户模式(6-8) if (mode >= EQ_USER_MODE_MIN && mode <= EQ_USER_MODE_MAX) { // 删除该模式的名称文件 @@ -1633,7 +1633,7 @@ int delete_flash_gain_and_names(uint8_t mode) { } else { DPRINTF(" Name file for mode %d does not exist: %s\n", mode, file_path); } - + // 从gains文件中移除该模式的增益(恢复为默认值0) // 改动原因:gains文件存储了所有用户模式的增益,需要读取、修改、写回 snprintf(file_path, sizeof(file_path), "%s/%s", g_eq_flash_base_dir, g_eq_flash_gains_file); @@ -1643,29 +1643,29 @@ int delete_flash_gain_and_names(uint8_t mode) { eq_gain_header_t header; eq_gain_data_t data; uint8_t file_data[sizeof(header) + sizeof(eq_gain_data_t)]; - + // 直接调用lfs_read_config(返回void,不能检查返回值) lfs_read_config(file_path, file_data, sizeof(file_data)); - + // 解析文件数据 memcpy(&header, file_data, sizeof(header)); memcpy(&data, file_data + sizeof(header), sizeof(eq_gain_data_t)); - + // 验证文件头来判断读取是否成功 if (header.magic == 0x4551474E && header.version == EQ_FLASH_VERSION) { // 将对应模式的增益恢复为默认值(0) int idx = mode - EQ_USER_MODE_MIN; // 转换为数组索引 0, 1, 2 data.mode_gains[idx] = 0; DPRINTF(" Reset gain for mode %d to default (0)\n", mode); - + // 重新计算CRC32 header.crc32 = eq_flash_calculate_crc32((uint8_t*)&data, sizeof(eq_gain_data_t)); - + // 写回文件 memcpy(file_data, &header, sizeof(header)); memcpy(file_data + sizeof(header), &data, sizeof(eq_gain_data_t)); lfs_write_config(file_path, file_data, sizeof(file_data)); - + DPRINTF(" Successfully updated gains file for mode %d\n", mode); } else { DPRINTF(" Error: Invalid gains file format or read failed\n"); @@ -1673,10 +1673,10 @@ int delete_flash_gain_and_names(uint8_t mode) { } else { DPRINTF(" Gains file does not exist: %s\n", file_path); } - + return 0; } - + // 其他模式(如模式9)不需要处理 DPRINTF(" Mode %d does not require Flash data deletion\n", mode); return 0; @@ -1689,21 +1689,21 @@ int delete_flash_gain_and_names(uint8_t mode) { */ void restore_mode_default_params(uint8_t mode, uint32_t sample_rate) { if (mode >= NUM_EQ_MODES) return; - + // 改动原因:所有采样率共用44100Hz数组 eq_mode_data_t (*eq_array)[NUM_EQ_MODES][NUM_EQ_CHANS] = &sEQ_data_44100HZ; - + if (eq_array == NULL) return; - + // 恢复左右通道的默认参数 for (int ch = 0; ch < NUM_EQ_CHANS; ch++) { eq_mode_data_t *eq_data = &(*eq_array)[mode][ch]; - + // 恢复基本参数 eq_data->sample_rate = sample_rate; eq_data->total_bshift = 0; eq_data->post_gain_db = 0; - + // 恢复所有滤波器的默认参数 for (int i = 0; i < MAX_EQ_BANDS; i++) { filter_params_t *band = &eq_data->bands[i]; @@ -1713,7 +1713,7 @@ void restore_mode_default_params(uint8_t mode, uint32_t sample_rate) { band->q = 0.707f; band->bw = 1.0f; band->gain = 0.0f; - + // 恢复默认系数 (bypass滤波器) eq_data->filter.coef[0][i] = 1 << 30; // b0 = 1.0 in Q30 eq_data->filter.coef[1][i] = 0; // b1 = 0 @@ -1721,11 +1721,11 @@ void restore_mode_default_params(uint8_t mode, uint32_t sample_rate) { eq_data->filter.coef[3][i] = 0; // a1 = 0 eq_data->filter.coef[4][i] = 0; // a2 = 0 } - + eq_data->filter.biquad_count = MAX_EQ_BANDS; memset(eq_data->filter.state, 0, sizeof(eq_data->filter.state)); } - + DPRINTF(" Restored mode %d for sample rate %u Hz\n", mode, sample_rate); } /** @@ -1735,7 +1735,7 @@ void restore_mode_default_params(uint8_t mode, uint32_t sample_rate) { */ int restore_default_eq_params(uint8_t mode) { DPRINTF("Restoring default EQ params for mode %d\n", mode); - + // 改动原因:所有采样率共用44100Hz数组,只需要恢复44100Hz数组 if (mode == 0xFF) { // 恢复所有模式的默认参数 @@ -1748,7 +1748,7 @@ int restore_default_eq_params(uint8_t mode) { DPRINTF(" Restoring mode %d to default parameters\n", mode); restore_mode_default_params(mode, 44100); // 恢复44100Hz数组 } - + DPRINTF(" Default parameters restored successfully\n"); return 0; } @@ -1757,29 +1757,29 @@ int restore_default_eq_params(uint8_t mode) { * @brief 保存EQ使能状态到Flash(独立文件存储,与模式存储完全分离) * @param enable EQ使能状态 (0=禁用, 1=启用) * @return 0: 成功, -1: 失败 - * + * * 改动原因:将eq_enable存储独立为单独文件,与模式存储完全分离,互不影响 */ int eq_flash_save_eq_enable(uint8_t enable) { DPRINTF("Saving EQ enable state %d to Flash (independent file)\n", enable); - + if (!storage_status.is_initialized) { DPRINTF(" Error: Flash storage not initialized\n"); return -1; } - + // 验证使能值范围 if (enable > 1) { DPRINTF(" Error: Invalid EQ enable value %d (valid range: 0-1)\n", enable); return -1; } - + // 构建独立文件路径 // 改动原因:使用独立的文件名存储eq_enable,与模式存储完全分离 char file_path[FILE_PATH_MAX_LENGTH]; snprintf(file_path, sizeof(file_path), "%s", g_eq_flash_enable_file); - + // 创建文件头 eq_file_header_t header = {0}; header.magic = EQ_FLASH_MAGIC; @@ -1787,17 +1787,17 @@ int eq_flash_save_eq_enable(uint8_t enable) header.mode = 0; // 不使用模式字段 header.channel = 0; // 不使用通道字段 header.data_size = 1; // 数据大小:只有使能状态(1字节) - + // 准备数据(只有使能状态) uint8_t enable_data = enable; - + header.crc32 = eq_flash_calculate_crc32(&enable_data, 1); - + // 准备文件数据 uint8_t file_data[sizeof(header) + 1]; memcpy(file_data, &header, sizeof(header)); file_data[sizeof(header)] = enable; - + // 写入文件 lfs_write_config(file_path, file_data, sizeof(file_data)); DPRINTF(" Successfully saved EQ enable %d to Flash (independent file: %s)\n", enable, file_path); @@ -1808,29 +1808,29 @@ int eq_flash_save_eq_enable(uint8_t enable) * @brief 保存当前EQ模式到Flash(独立文件存储,与使能状态存储完全分离) * @param mode 模式值 (0-9) * @return 0: 成功, -1: 失败 - * + * * 改动原因:将模式存储独立为单独文件,与eq_enable存储完全分离,互不影响 */ int eq_flash_save_current_mode(uint8_t mode) { DPRINTF("Saving current EQ mode %d to Flash (independent file)\n", mode); - + if (!storage_status.is_initialized) { DPRINTF(" Error: Flash storage not initialized\n"); return -1; } - + // 验证模式值范围 if (mode > 9) { DPRINTF(" Error: Invalid mode %d (valid range: 0-9)\n", mode); return -1; } - + // 构建独立文件路径 // 改动原因:使用独立的文件名存储模式,与eq_enable存储完全分离 char file_path[FILE_PATH_MAX_LENGTH]; snprintf(file_path, sizeof(file_path), "%s", g_eq_flash_mode_file); - + // 创建文件头 eq_file_header_t header = {0}; header.magic = EQ_FLASH_MAGIC; @@ -1838,17 +1838,17 @@ int eq_flash_save_current_mode(uint8_t mode) header.mode = mode; // 模式值 header.channel = 0; // 不使用通道字段 header.data_size = 1; // 数据大小:只有模式值(1字节) - + // 准备数据(只有模式值) uint8_t mode_data = mode; - + header.crc32 = eq_flash_calculate_crc32(&mode_data, 1); - + // 准备文件数据 uint8_t file_data[sizeof(header) + 1]; memcpy(file_data, &header, sizeof(header)); file_data[sizeof(header)] = mode; - + // 写入文件 lfs_write_config(file_path, file_data, sizeof(file_data)); DPRINTF(" Successfully saved EQ mode %d to Flash (independent file: %s)\n", mode, file_path); @@ -1858,7 +1858,7 @@ int eq_flash_save_current_mode(uint8_t mode) /** * @brief 从Flash加载当前EQ模式和使能状态(从两个独立文件分别加载) * @return 模式值: 成功, -1: 失败 - * + * * 改动原因:从两个独立文件分别加载模式和使能状态,完全独立,互不影响 */ int eq_flash_load_current_mode(void) @@ -1866,25 +1866,25 @@ int eq_flash_load_current_mode(void) uint8_t mode = 0; uint8_t eq_enable = 0; DPRINTF("Loading current EQ mode and enable state from Flash (independent files)\n"); - + if (!storage_status.is_initialized) { DPRINTF(" Error: Flash storage not initialized\n"); return -1; } - + // 加载模式(从独立文件) char mode_file_path[FILE_PATH_MAX_LENGTH]; snprintf(mode_file_path, sizeof(mode_file_path), "%s", g_eq_flash_mode_file); - + if (lfs_file_exists(mode_file_path)) { eq_file_header_t header; uint8_t file_header_data[sizeof(header) + 1]; lfs_read_config(mode_file_path, file_header_data, sizeof(file_header_data)); memcpy(&header, file_header_data, sizeof(header)); - + if (header.magic == EQ_FLASH_MAGIC && header.version == EQ_FLASH_VERSION) { mode = file_header_data[sizeof(header)]; - + // 验证模式值范围 if (mode > 9) { DPRINTF(" Error: Invalid mode value %d in file\n", mode); @@ -1908,20 +1908,20 @@ int eq_flash_load_current_mode(void) DPRINTF(" Mode file does not exist, using default mode 0\n"); mode = 0; } - + // 加载使能状态(从独立文件) char enable_file_path[FILE_PATH_MAX_LENGTH]; snprintf(enable_file_path, sizeof(enable_file_path), "%s", g_eq_flash_enable_file); - + if (lfs_file_exists(enable_file_path)) { eq_file_header_t header; uint8_t file_header_data[sizeof(header) + 1]; lfs_read_config(enable_file_path, file_header_data, sizeof(file_header_data)); memcpy(&header, file_header_data, sizeof(header)); - + if (header.magic == EQ_FLASH_MAGIC && header.version == EQ_FLASH_VERSION) { eq_enable = file_header_data[sizeof(header)]; - + // 验证使能值范围 if (eq_enable > 1) { DPRINTF(" Warning: Invalid EQ enable value %d in file, defaulting to 0\n", eq_enable); @@ -1945,11 +1945,11 @@ int eq_flash_load_current_mode(void) DPRINTF(" Enable file does not exist, using default enable 0\n"); eq_enable = 0; } - + // 设置全局变量g_eq_enable extern unsigned int g_eq_enable; g_eq_enable = eq_enable; - + DPRINTF(" Successfully loaded mode %d and EQ enable %d from Flash (independent files)\n", mode, eq_enable); return mode; } @@ -1957,32 +1957,32 @@ int eq_flash_load_current_mode(void) /** * @brief 从Flash加载EQ使能状态(独立文件加载,与模式加载完全分离) * @return 使能状态值: 成功(0或1), -1: 失败 - * + * * 改动原因:从独立文件(eq_enable)加载eq_enable,与模式加载完全分离,互不影响 */ int eq_flash_load_eq_enable(void) { uint8_t eq_enable = 0; DPRINTF("Loading EQ enable state from Flash (independent file)\n"); - + if (!storage_status.is_initialized) { DPRINTF(" Error: Flash storage not initialized\n"); return -1; } - + // 加载使能状态(从独立文件) char enable_file_path[FILE_PATH_MAX_LENGTH]; snprintf(enable_file_path, sizeof(enable_file_path), "%s", g_eq_flash_enable_file); - + if (lfs_file_exists(enable_file_path)) { eq_file_header_t header; uint8_t file_header_data[sizeof(header) + 1]; lfs_read_config(enable_file_path, file_header_data, sizeof(file_header_data)); memcpy(&header, file_header_data, sizeof(header)); - + if (header.magic == EQ_FLASH_MAGIC && header.version == EQ_FLASH_VERSION) { eq_enable = file_header_data[sizeof(header)]; - + // 验证使能值范围 if (eq_enable > 1) { DPRINTF(" Warning: Invalid EQ enable value %d in file, defaulting to 0\n", eq_enable); @@ -2006,12 +2006,11 @@ int eq_flash_load_eq_enable(void) DPRINTF(" Enable file does not exist, using default enable 0\n"); eq_enable = 0; } - + // 设置全局变量g_eq_enable extern unsigned int g_eq_enable; g_eq_enable = eq_enable; - + DPRINTF(" Successfully loaded EQ enable %d from Flash (independent file)\n", eq_enable); return eq_enable; } -