Роберт_Rob 0 December 30, 2025 Posted December 30, 2025 · Report post Всех с наступающим новым годом!!! Вопрос: Как встроить ауди файл в прошивку, чтобы програмно воспроизводить его? Пробовал в главном CMakeLists.txt добавлять строки: file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/sounds/Vol1.wav DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/sounds) в папке out появляется моя папка с файлом. Но в файле burn, который заливается в модуль, видимо его нет, тк функция воспроизведения result = sAPI_AudioPlay(filename, 1,1); выдает ошибку. Пробовал функциями проверять папку и файл, тоже получаю ошибку. ret = sAPI_stat(file_name,&info_file); ret = sAPI_stat(dir_name,&info_file); Файл CMakeLists.txt запускаю 2 раза. Первый раз создаю библиотеку, второй раз встраиваю ее в проект (если я правильно перевел все с китайского :)) Когда надо правильно добавлять в CMakeLists.txt команду file(COPY ??? в первую или вторую компиляцию? И как добавить файл в прошивку? Quote Share this post Link to post Share on other sites More sharing options...
Роберт_Rob 0 January 7 Posted January 7 · Report post Никто не ответил, пришлось читать литературу cmake. Коротко так: Что бы фай передать в модуль вместе с программой, надо сначала преобразовать его в заголовочный файл H. После это присоединить к проекту. Далее при первом запуске, я проверяю существует ли файл wav, и если нет, то запускаю подпрограмму (на си ), которая создает на диске С: в модуле файл wav из массива, полученного из H файла. Далее запускаю команду result = sAPI_AudioWavFilePlay(filename, 1); и модуль выдает мне что все ок: +AUDIOSTATE: audio play НО!!!! В линию я ничего не слышу! (я звоню на модуль, и после снятия трубки вызываю проигрывание файла) Динамик к модулю не подключен. Возможно на динамик сигнал подается. Но как модулю сказать, что бы он посылал сигнал в линию? Команда sAPI_AudioSetPlayPath(1); не помогает. Пробовал и 0 (локальный путь) и 1 (удаленный) Все одинаково. Кстати, кто знает различие напишите. Так что продолжаю ломать голову:))) Кто подскажет - заранее спасибо!!!! Кому интересно - вот функция cmake для создания из любого файла - файла H function(embed_resource resource_file_name source_file_name variable_name) if(EXISTS "${source_file_name}") if("${source_file_name}" IS_NEWER_THAN "${resource_file_name}") return() endif() endif() file(READ "${resource_file_name}" hex_content HEX) foreach(a RANGE 31) string(CONCAT pattern "[0-9a-f]" pattern) endforeach(a RANGE 31) string(REGEX REPLACE "(${pattern})" "\\1\n" content "${hex_content}") string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1, " content "${content}") string(REGEX REPLACE ", $" "" content "${content}") set(array_definition "static const unsigned char ${variable_name}[] =\n{\n${content}\n};") set(source "// Auto generated file.\n${array_definition}\n") file(WRITE "${source_file_name}" "${source}") endfunction() # вызов функции входной файл, выходной, массив который используется в программе си embed_resource("sounds/Vol1.wav" "Vol1.h" "VOL1") в программе си использование: подключите заголовочный файл и определите: static const unsigned char VOL1[]; const size_t Vol1_len = sizeof(VOL1); Далее я использовал подпрограмму для создания файла wav (ее кстати написал мне https://chatgpt.org/ru/chat искусственный интеллект!!! Быстро и почти без ошибок:) #include "simcom_debug.h" #include "Vol1.h" #include "wav_utils.h" #include "simcom_file_system.h" #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <stdint.h> #include <string.h> static void write_le32(unsigned char *p, uint32_t v) { p[0] = v & 0xFF; p[1] = (v >> 8) & 0xFF; p[2] = (v >> 16) & 0xFF; p[3] = (v >> 24) & 0xFF; } static void write_le16(unsigned char *p, uint16_t v) { p[0] = v & 0xFF; p[1] = (v >> 8) & 0xFF; } typedef struct { char riff[4]; uint32_t overall_size; char wave[4]; char fmt_chunk[4]; uint32_t fmt_size; uint16_t audio_format; uint16_t num_channels; uint32_t sample_rate; uint32_t byte_rate; uint16_t block_align; uint16_t bits_per_sample; char data_chunk[4]; uint32_t data_size; } WAVHeader; static const unsigned char VOL1[sizeof(VOL1)]; //const size_t Vol1_len = sizeof(VOL1); SCFILE *out = NULL; uint32_t actul_write_len ; /* FILE* in = fopen(header_path, "r"); if (!in) return NULL; fseek(in, 0, SEEK_END); long size = ftell(in); fseek(in, 0, SEEK_SET); char* buf = (char*)malloc(size + 1); if (!buf) { fclose(in); return NULL; } size_t read = fread(buf, 1, size, in); fclose(in); buf[read] = '\0'; unsigned char* data = NULL; size_t capacity = 0; size_t len = 0; for (size_t i = 0; i < read; ++i) { if (buf == '0' && (i + 1 < read) && (buf[i+1] == 'x' || buf[i+1] == 'X')) { i += 2; unsigned int val = 0; int had = 0; while (i < read && isxdigit((unsigned char)buf)) { char c = buf; val <<= 4; if (c >= '0' && c <= '9') val |= (c - '0'); else if (c >= 'a' && c <= 'f') val |= (10 + (c - 'a')); else if (c >= 'A' && c <= 'F') val |= (10 + (c - 'A')); ++i; ++had; } if (had > 0) { if (len == capacity) { capacity = capacity ? capacity * 2 : 256; unsigned char* nd = (unsigned char*)realloc(data, capacity); if (!nd) { free(buf); free(data); return NULL; } data = nd; } data[len++] = (unsigned char)val; --i; } } } free(buf); if (len == 0) { free(data); return NULL; } *out_len = len; return data; } */ // Основная реализация int wav_from_header_array(const char* header_path, const char* wav_path, int sample_rate, int bits_per_sample, int channels) { sAPI_Debug("wav_from_header_array"); size_t data_len = sizeof(VOL1); WAVHeader header; memcpy(header.riff, "RIFF", 4); memcpy(header.wave, "WAVE", 4); memcpy(header.fmt_chunk, "fmt ", 4); memcpy(header.data_chunk, "data", 4); header.fmt_size = 16; header.audio_format = 1; // PCM header.num_channels = (uint16_t)channels; header.sample_rate = (uint32_t)sample_rate; header.bits_per_sample = (uint16_t)bits_per_sample; header.block_align = (header.num_channels * header.bits_per_sample) / 8; header.byte_rate = header.sample_rate * header.block_align; header.data_size = (uint32_t)data_len; header.overall_size = 4 + (8 + header.fmt_size) + (8 + header.data_size); out = sAPI_fopen(wav_path, "wb"); if (!out) { sAPI_Debug("Error sAPI_fopen"); return -1; } unsigned char tmp4[4]; // RIFF actul_write_len = sAPI_fwrite(header.riff, 1, 4, out); if (actul_write_len != (4)) { sAPI_Debug("FILE SYSTEM write file fail!! actual write len: %ld", actul_write_len); } sAPI_Debug("FILE SYSTEM write after"); write_le32(tmp4, header.overall_size); sAPI_fwrite(tmp4, 1, 4, out); sAPI_fwrite(header.wave, 1, 4, out); // fmt sAPI_Debug("ftm_start"); sAPI_fwrite(header.fmt_chunk, 1, 4, out); write_le32(tmp4, header.fmt_size); sAPI_fwrite(tmp4, 1, 4, out); unsigned char tmp2[2]; write_le16(tmp2, header.audio_format); sAPI_fwrite(tmp2, 1, 2, out); write_le16(tmp2, header.num_channels); sAPI_fwrite(tmp2, 1, 2, out); write_le32(tmp4, header.sample_rate); sAPI_fwrite(tmp4, 1, 4, out); write_le32(tmp4, header.byte_rate); sAPI_fwrite(tmp4, 1, 4, out); write_le16(tmp2, header.block_align); sAPI_fwrite(tmp2, 1, 2, out); write_le16(tmp2, header.bits_per_sample); sAPI_fwrite(tmp2, 1, 2, out); sAPI_Debug("ftm_finish"); // data sAPI_fwrite(header.data_chunk, 1, 4, out); write_le32(tmp4, header.data_size); sAPI_fwrite(tmp4, 1, 4, out); sAPI_Debug("data_finish"); // данные if (sAPI_fwrite(VOL1, 1, data_len, out) != data_len) { sAPI_Debug("data!!!"); sAPI_fclose(out); return -1; } sAPI_Debug("data_finish"); sAPI_fclose(out); return 0; } То что в взято в коменты - я убрал, тк там сначала считывали в буфер ( переполняли память), а затем выводили. Я сразу вывел массив. Так что новогодние каникулы проходят напряженно:) Кто знает как переключить звук напишите! Quote Share this post Link to post Share on other sites More sharing options...
kolobok0 4 January 8 Posted January 8 (edited) · Report post 17 hours ago, Роберт_Rob said: ...Но как модулю сказать, что бы он посылал сигнал в линию? Команда У Вас задача распадается на несколько этапов: - на компиляции подтащить в нужное место динамически меняющийся (насколько я понял) звуковой файл - вставить в прошивку звуковой файл - убедиться в успехе проигрывания файла - направить звуковой поток в линию, по вашей логике первые две задачи Вы сделали. Осталось ещё две. 1) Вам надо убедиться что нигде не ошиблись - т.е. Вам нужно теперь в заведомо рабочий канал направить Ваш звуковой файл 2) Направить звуковой поток в аудио канал при вызове как то так (круглый) Edited January 8 by kolobok0 Quote Share this post Link to post Share on other sites More sharing options...