From 17ac2ce0ed52874616c79c910667e41e34604826 Mon Sep 17 00:00:00 2001
From: wangzhibo <wangzhibo@shsening.com>
Date: 星期一, 31 八月 2026 13:14:12 +0800
Subject: [PATCH] add translation app
---
xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/mp3_player.cc | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/mp3_player.cc b/xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/mp3_player.cc
index 0cf4cf0..cc87034 100644
--- a/xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/mp3_player.cc
+++ b/xiaozhi-esp32-2.2.6/main/boards/sening-xiaozhi-s3/mp3_player.cc
@@ -1,7 +1,9 @@
#include "system.h"
+#include "app_task.h"
#include "audio_codec.h"
#include "board.h"
+#include "application.h"
#include <esp_log.h>
#include <freertos/FreeRTOS.h>
@@ -27,11 +29,14 @@
typedef struct {
char path[SDCARD_PATH_MAX_LEN];
float speed;
+ int repeat;
+ bool power_off_after;
} mp3_player_task_arg_t;
static TaskHandle_t mp3_player_task_handle;
static volatile bool mp3_stop_requested;
static volatile bool mp3_pause_requested;
+static volatile int mp3_repeat_left;
static std::vector<int16_t> convert_channels(const int16_t *input, size_t frame_count, uint8_t src_channels, uint8_t dst_channels)
{
@@ -127,6 +132,8 @@
char path[SDCARD_PATH_MAX_LEN];
strlcpy(path, task_arg->path, sizeof(path));
float speed = task_arg->speed;
+ int repeat = task_arg->repeat < 1 ? 1 : task_arg->repeat;
+ bool power_off_after = task_arg->power_off_after;
free(task_arg);
FILE *fp = fopen(path, "rb");
@@ -134,6 +141,7 @@
ESP_LOGE(TAG, "open MP3 failed: %s", path);
mp3_player_task_handle = nullptr;
mp3_stop_requested = false;
+ mp3_repeat_left = 0;
vTaskDelete(nullptr);
return;
}
@@ -144,6 +152,7 @@
fclose(fp);
mp3_player_task_handle = nullptr;
mp3_stop_requested = false;
+ mp3_repeat_left = 0;
vTaskDelete(nullptr);
return;
}
@@ -167,6 +176,7 @@
fclose(fp);
mp3_player_task_handle = nullptr;
mp3_stop_requested = false;
+ mp3_repeat_left = 0;
vTaskDelete(nullptr);
return;
}
@@ -184,11 +194,27 @@
ESP_LOGE(TAG, "no memory for MP3 playback");
ret = ESP_AUDIO_ERR_MEM_LACK;
} else {
- ESP_LOGI(TAG, "play MP3: %s, speed: %.2fx", path, speed);
+ ESP_LOGI(TAG, "play MP3: %s, speed: %.2fx, repeat: %d, power_off_after: %d", path, speed, repeat, power_off_after ? 1 : 0);
if (wait_if_paused()) {
codec->EnableOutput(true);
}
+
+ for (int pass = 0; pass < repeat && ret == ESP_AUDIO_ERR_OK && !mp3_stop_requested; ++pass) {
+ mp3_repeat_left = repeat - pass;
+ if (pass > 0) {
+ if (fseek(fp, 0, SEEK_SET) != 0) {
+ ESP_LOGE(TAG, "rewind MP3 failed: %s", path);
+ break;
+ }
+ esp_audio_simple_dec_close(decoder);
+ decoder = nullptr;
+ ret = esp_audio_simple_dec_open(&dec_cfg, &decoder);
+ if (ret != ESP_AUDIO_ERR_OK || !decoder) {
+ ESP_LOGE(TAG, "reopen MP3 decoder failed: %d", ret);
+ break;
+ }
+ }
while (ret == ESP_AUDIO_ERR_OK && !mp3_stop_requested) {
if (!wait_if_paused()) {
@@ -287,6 +313,7 @@
break;
}
}
+ }
}
if (rate_cvt_handle) {
@@ -297,27 +324,44 @@
}
free(in_buf);
free(out_buf);
- esp_audio_simple_dec_close(decoder);
+ if (decoder) {
+ esp_audio_simple_dec_close(decoder);
+ }
esp_audio_simple_dec_unregister_default();
esp_audio_dec_unregister_default();
fclose(fp);
ESP_LOGI(TAG, "MP3 playback %s: %s", mp3_stop_requested ? "stopped" : "finished", path);
+ bool stopped = mp3_stop_requested;
+ bool should_power_off = power_off_after && !stopped;
mp3_player_task_handle = nullptr;
mp3_stop_requested = false;
mp3_pause_requested = false;
+ mp3_repeat_left = 0;
+ if (should_power_off) {
+ Application::GetInstance().RequestPowerOffStandby();
+ }
+ Board_OnSkillPlaybackFinished(stopped, power_off_after);
vTaskDelete(nullptr);
}
extern "C" esp_err_t SDCard_Play_MP3_File(const char *path)
{
- return SDCard_Play_MP3_File_With_Speed(path, 1.0f);
+ return SDCard_Play_MP3_File_With_Speed_Repeat(path, 1.0f, 1, false);
}
extern "C" esp_err_t SDCard_Play_MP3_File_With_Speed(const char *path, float speed)
{
+ return SDCard_Play_MP3_File_With_Speed_Repeat(path, speed, 1, false);
+}
+
+extern "C" esp_err_t SDCard_Play_MP3_File_With_Speed_Repeat(const char *path, float speed, int repeat, bool power_off_after)
+{
if (!path || path[0] == '\0' || !is_supported_speed(speed)) {
return ESP_ERR_INVALID_ARG;
+ }
+ if (repeat < 1) {
+ repeat = 1;
}
bool start_paused = mp3_pause_requested;
@@ -335,13 +379,17 @@
}
strlcpy(arg->path, path, sizeof(arg->path));
arg->speed = speed;
+ arg->repeat = repeat;
+ arg->power_off_after = power_off_after;
mp3_stop_requested = false;
mp3_pause_requested = start_paused;
+ mp3_repeat_left = repeat;
BaseType_t ret = xTaskCreate(mp3_player_task, "mp3_player", MP3_PLAYER_STACK_SIZE, arg, MP3_PLAYER_PRIORITY, &mp3_player_task_handle);
if (ret != pdPASS) {
free(arg);
mp3_player_task_handle = nullptr;
+ mp3_repeat_left = 0;
return ESP_FAIL;
}
@@ -378,3 +426,8 @@
{
return mp3_player_task_handle != nullptr && mp3_pause_requested;
}
+
+extern "C" int SDCard_Get_Repeat_Left(void)
+{
+ return mp3_repeat_left;
+}
--
Gitblit v1.9.1