优化opus解码问题
authorhcj <1224667075@qq.com>
Fri, 30 Jan 2026 08:05:29 +0000 (16:05 +0800)
committerhcj <1224667075@qq.com>
Fri, 30 Jan 2026 08:05:29 +0000 (16:05 +0800)
code/sdk/zhihui/MQTT/uapi_mqtt_at.c
code/sdk/zhihui/leiniao/imsl_ln/LN_MQTT/ln_mqtt_api_at.c
code/sdk/zhihui/test_opus_frame_to_pcm/include/opus_frame_to_pcm.h
code/sdk/zhihui/test_opus_frame_to_pcm/src/opus_frame_to_pcm.c

index e7b3a3b..fbd4a77 100644 (file)
@@ -81,25 +81,6 @@ static void mqtt_at_message_cb(void *arg, const char *topic, const uint8_t *data
     }
 }
 
-/* OTA-发送设备信息到服务器:AT^LN_OTA_SEND_DEVICE_INFO */
-// static uint32_t ln_ota_send_device_info_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
-// {
-//     (void)para;
-//     (void)paraLen;
-//     (void)strCommonCmd;
-    
-//     printf("[LN][OTA_SEND_DEVICE_INFO]\n");
-    
-//     // 直接调用封装函数,使用默认URL(NULL表示使用默认URL)
-//     int ret = ln_ota_send_device_info_json(NULL, NULL);
-//     if (ret == 0) {
-//         printf("+LN_OTA_SEND_DEVICE_INFO: OK\n");
-//         return ERRCODE_SUCC;
-//     } else {
-//         printf("+LN_OTA_SEND_DEVICE_INFO: FAIL\n");
-//         return ERRCODE_FAIL;
-//     }
-// }
 
 /* MQTT-初始化:AT^LN_MQTT_INIT */
 static uint32_t uapi_mqtt_init_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
index 834e2eb..d7a8990 100644 (file)
@@ -172,11 +172,34 @@ static uint32_t ln_mqtt_stop_service_at(uint8_t *para, uint32_t paraLen, char *s
     return ERRCODE_SUCC;\r
 }\r
 \r
+\r
+/* OTA-发送设备信息到服务器:AT^LN_OTA_SEND_DEVICE_INFO */\r
+static uint32_t ln_ota_send_device_info_at(uint8_t *para, uint32_t paraLen, char *strCommonCmd)\r
+{\r
+    (void)para;\r
+    (void)paraLen;\r
+    (void)strCommonCmd;\r
+    \r
+    printf("[LN][OTA_SEND_DEVICE_INFO]\n");\r
+    \r
+    // 直接调用封装函数,使用默认URL(NULL表示使用默认URL)\r
+    int ret = ln_ota_send_device_info_json(NULL, NULL);\r
+    if (ret == 0) {\r
+        printf("+LN_OTA_SEND_DEVICE_INFO: OK\n");\r
+        return ERRCODE_SUCC;\r
+    } else {\r
+        printf("+LN_OTA_SEND_DEVICE_INFO: FAIL\n");\r
+        return ERRCODE_FAIL;\r
+    }\r
+}\r
+\r
+\r
 static const at_cmd_table_t g_ln_mqtt_at_cmds[] = {\r
     {(char *)"AT^LN_MQTT_LISTEN", ln_mqtt_listen_at, (char *)"LN MQTT listen start/stop: AT^LN_MQTT_LISTEN=1/0"},\r
     {(char *)"AT^LN_MQTT_HELLO",  ln_mqtt_hello_at,  (char *)"LN MQTT send hello: AT^LN_MQTT_HELLO"},\r
     {(char *)"AT^LN_MQTT_START_SERVICE", ln_mqtt_start_service_at, (char *)"LN MQTT start service: AT^LN_MQTT_START_SERVICE"},\r
     {(char *)"AT^LN_MQTT_STOP_SERVICE",  ln_mqtt_stop_service_at,  (char *)"LN MQTT stop service: AT^LN_MQTT_STOP_SERVICE"},\r
+     {(char *)"AT^LN_OTA_SEND_DEVICE_INFO",  ln_ota_send_device_info_at,  (char *)"ln_ota_send_device_info_at: AT^ln_ota_send_device_info_json"},\r
 };\r
 \r
 at_cmd_table_t *get_ln_mqtt_at_cmd_table(uint32_t *cmd_count)\r
index ea2c790..2ce2b7c 100644 (file)
@@ -5,6 +5,21 @@
 extern "C" {
 #endif
 
+/**
+ * @brief Initialize Opus decoder. Optional; decode_packet will auto-init if not initialized.
+ *
+ * @param sample_rate  Sample rate in Hz (e.g. 16000/48000).
+ * @param channels     Channel count (1=mono, 2=stereo).
+ *
+ * @return 0 on success, non-zero on failure.
+ */
+int opus_frame_to_pcm_decoder_init(int sample_rate, int channels);
+
+/**
+ * @brief Destroy Opus decoder. Call when decoder is no longer needed to free resources.
+ */
+void opus_frame_to_pcm_decoder_destroy(void);
+
 /**
  * @brief Decode a single Opus packet (in-memory) into 16-bit PCM samples.
  *
index bdcdf19..02580c9 100644 (file)
 #define MAX_PACKET_SIZE 15000\r
 #define MAX_PCM_SAMPLES 5760  /* 120ms at 48kHz */\r
 \r
+static OpusDecoder *s_decoder = NULL;\r
+static int s_decoder_sample_rate = 0;\r
+static int s_decoder_channels = 0;\r
+\r
+int opus_frame_to_pcm_decoder_init(int sample_rate, int channels)\r
+{\r
+    int error = OPUS_OK;\r
+\r
+    if (sample_rate <= 0 || channels <= 0) {\r
+        return 1;\r
+    }\r
+\r
+    /* If already initialized with same params, reuse */\r
+    if (s_decoder && s_decoder_sample_rate == sample_rate && s_decoder_channels == channels) {\r
+        return 0;\r
+    }\r
+\r
+    /* Destroy old decoder if params changed */\r
+    if (s_decoder) {\r
+        opus_decoder_destroy(s_decoder);\r
+        s_decoder = NULL;\r
+    }\r
+\r
+    s_decoder = opus_decoder_create(sample_rate, channels, &error);\r
+    if (error != OPUS_OK) {\r
+        return 1;\r
+    }\r
+\r
+    s_decoder_sample_rate = sample_rate;\r
+    s_decoder_channels = channels;\r
+    return 0;\r
+}\r
+\r
+void opus_frame_to_pcm_decoder_destroy(void)\r
+{\r
+    if (s_decoder) {\r
+        opus_decoder_destroy(s_decoder);\r
+        s_decoder = NULL;\r
+        s_decoder_sample_rate = 0;\r
+        s_decoder_channels = 0;\r
+    }\r
+}\r
+\r
 int opus_frame_to_pcm_decode_packet(const unsigned char *packet_data, int packet_len,\r
                                     int sample_rate, int channels,\r
                                     short *out_pcm, int out_pcm_capacity,\r
                                     int *out_pcm_samples)\r
 {\r
-    OpusDecoder *decoder = NULL;\r
-    int error = OPUS_OK;\r
     int decoded_samples = 0;\r
     int total_samples = 0;\r
 \r
@@ -76,28 +117,23 @@ int opus_frame_to_pcm_decode_packet(const unsigned char *packet_data, int packet
         }\r
     }\r
     \r
-    /* Create decoder */\r
-    decoder = opus_decoder_create(sample_rate, channels, &error);\r
-    if (error != OPUS_OK) {\r
+    /* Auto-init if not initialized, or re-init if params changed */\r
+    if (opus_frame_to_pcm_decoder_init(sample_rate, channels) != 0) {\r
         return 1;\r
     }\r
 \r
     /* Decode packet */\r
-    decoded_samples = opus_decode(decoder, packet_data, packet_len, (opus_int16 *)out_pcm, MAX_PCM_SAMPLES, 0);\r
+    decoded_samples = opus_decode(s_decoder, packet_data, packet_len, (opus_int16 *)out_pcm, MAX_PCM_SAMPLES, 0);\r
     if (decoded_samples <= 0) {\r
-        opus_decoder_destroy(decoder);\r
         return 1;\r
     }\r
 \r
     total_samples = decoded_samples * channels;\r
     if (total_samples > out_pcm_capacity) {\r
-        opus_decoder_destroy(decoder);\r
         return 1;\r
     }\r
     *out_pcm_samples = total_samples;\r
 \r
-    /* Cleanup */\r
-    opus_decoder_destroy(decoder);\r
     return 0;\r
 }\r
 \r