解释以下代码:static void * sdcard_thread(void *param) { //read pps const char* fileName = "/pps/fileMgr/client?wait,delta"; int pps_washer = open(fileName,O_RDONLY); char temp[1024]; char* buf_addr_temp = temp; int bytes = 0; if(pps_washer == -1){ printf("CreatPPS open file %s faile \n ",fileName); return NULL; } while(g_bRunning) { buf_addr_temp = temp; memset(buf_addr_temp,0x00,1024); bytes = read(pps_washer, buf_addr_temp, 1024); if (bytes > 0) { parsebuf2(buf_addr_temp); } } }
时间: 2024-03-28 09:41:04 浏览: 110
这段代码定义了一个静态函数 sdcard_thread,该函数是一个线程函数,运行时会执行线程中的代码块。该函数首先定义了一个指向字符常量的指针 fileName,指向字符串 "/pps/fileMgr/client?wait,delta",然后调用 open 函数,打开该指向的文件,并将返回的文件描述符存储在整型变量 pps_washer 中。如果文件打开失败,该函数会输出错误信息并返回 NULL。
在 while 循环中,函数会不断读取文件中的数据,并将其存储在字符数组 temp 中。当读取到数据时,函数会调用 parsebuf2 函数对 temp 数组中的数据进行解析处理。函数会一直运行,直到全局变量 g_bRunning 被设置为 false。
需要注意的是,该函数中的代码并未进行错误处理,例如在读取文件时没有检查是否发生了错误。此外,该函数中的变量声明和一些函数调用的参数也没有给出具体的类型,因此需要根据上下文进行推断。
相关问题
优化这段代码uint8_t *audio_buffer = (uint8_t *)calloc(1, AUDIO_BUFFER_SIZE); assert(audio_buffer); size_t r_bytes = 0; size_t w_bytes = 0; uint8_t volume = 1; FILE *f_read_audio = fopen("/sdcard/wav/bell/CueTone.WAV", "rb"); if (f_read_audio == NULL) { ESP_LOGI(TAG, "Failed to open file"); } else { while (1) { r_bytes = fread(audio_buffer, 1, AUDIO_BUFFER_SIZE, f_read_audio); if (r_bytes == 0) { ESP_LOGI(TAG, "i2s_task will delete"); break; } ESP_LOGI(TAG, ":read %s bytes\n", audio_buffer); // 调整音量大小 int16_t *pcmdata = (int16_t *)audio_buffer; for (int i = 0; i < r_bytes / 2; i++) { int32_t temp = (int32_t)(*pcmdata); temp = temp * volume; temp = temp / 10; *pcmdata = (int16_t)temp; pcmdata++; } // for (int i = 0; i < r_bytes; i += 2) // { // audio_buffer[i] = audio_buffer[i + 1]; // audio_buffer[i + 1] = audio_buffer[i]; // } /* Write i2s data */ if (i2s_channel_write(tx_chan, audio_buffer, AUDIO_BUFFER_SIZE, &w_bytes, portMAX_DELAY) == ESP_OK) { ESP_LOGI(TAG, "Write Task: i2s write %d bytes\n", w_bytes); } else { ESP_LOGI(TAG, "Write Task: i2s write failed\n"); } } }
这段代码需要做以下优化:
1. 避免使用动态内存分配函数 calloc,因为它会频繁调用 malloc 和 free 函数,影响性能,可以使用静态分配的数组代替。
2. 避免在循环中频繁调用 fread 函数,可以将文件读取到缓存中,然后再从缓存中读取数据。
3. 避免在循环中频繁调用 i2s_channel_write 函数,可以将数据写入缓存中,然后再从缓存中写入 i2s 通道。
4. 调整音量大小时可以使用移位运算代替除法运算,提高性能。
下面是优化后的代码:
```c
#define AUDIO_BUFFER_SIZE 2048
uint8_t audio_buffer[AUDIO_BUFFER_SIZE];
size_t r_bytes = 0;
size_t w_bytes = 0;
uint8_t volume = 10;
FILE *f_read_audio = fopen("/sdcard/wav/bell/CueTone.WAV", "rb");
if (f_read_audio == NULL)
{
ESP_LOGI(TAG, "Failed to open file");
}
else
{
// 读取整个文件到缓存中
fseek(f_read_audio, 0, SEEK_END);
size_t file_size = ftell(f_read_audio);
fseek(f_read_audio, 0, SEEK_SET);
size_t read_size = fread(audio_buffer, 1, file_size, f_read_audio);
fclose(f_read_audio);
int16_t *pcmdata = (int16_t *)audio_buffer;
for (int i = 0; i < read_size / 2; i++)
{
int32_t temp = (int32_t)(*pcmdata);
temp = (temp * volume) >> 3; // 移位运算代替除法运算
*pcmdata = (int16_t)temp;
pcmdata++;
}
// 将数据写入 i2s 缓存中
int offset = 0;
while (offset < read_size)
{
size_t write_size = MIN(read_size - offset, AUDIO_BUFFER_SIZE);
memcpy(audio_buffer, audio_buffer + offset, write_size);
if (i2s_channel_write(tx_chan, audio_buffer, write_size, &w_bytes, portMAX_DELAY) == ESP_OK)
{
ESP_LOGI(TAG, "Write Task: i2s write %d bytes\n", w_bytes);
}
else
{
ESP_LOGI(TAG, "Write Task: i2s write failed\n");
}
offset += write_size;
}
}
```
#!/bin/bash # Assets TEST_IMG=demo.png SDK_ROOT=$PWD TEST_ROOT=$PWD BIN_NAME=test_demo DEVICE_TEST_PATH=/data/local/tmp/ts_ai_sdk_test MODEL_PATH=/sdcard/models RUSULT=/data/local/tmp/ts_ai_sdk_test/results/ RUNTIME=DSP adb root # Push test assets adb shell rm -rf $DEVICE_TEST_PATH # adb shell rm -rf $MODEL_PATH adb shell mkdir -p $DEVICE_TEST_PATH/jpgs adb shell mkdir -p $DEVICE_TEST_PATH/results/post_result adb shell mkdir -p $DEVICE_TEST_PATH/results/img_result #adb shell mkdir -p $MODEL_PATH adb push images/* $DEVICE_TEST_PATH/jpgs # Push SNPE libraries adb push ${SDK_ROOT}/libs/ $DEVICE_TEST_PATH adb push ${SDK_ROOT}/models/model.exf $DEVICE_TEST_PATH/ # Push executable adb push build/$BIN_NAME $DEVICE_TEST_PATH # Test adb shell "chmod +x $DEVICE_TEST_PATH/$BIN_NAME" echo "Running on Android device ..." echo "LD_LIBRARY_PATH='$DEVICE_TEST_PATH/libs' $DEVICE_TEST_PATH/$BIN_NAME $DEVICE_TEST_PATH/jpgs $RUSULT $DEVICE_TEST_PATH/model.exf" echo "Done." adb shell "LD_LIBRARY_PATH='$DEVICE_TEST_PATH/libs' $DEVICE_TEST_PATH/$BIN_NAME $DEVICE_TEST_PATH/jpgs $RUSULT $DEVICE_TEST_PATH/model.exf" # Pull result adb pull $DEVICE_TEST_PATH/results/ . sleep 1改为bat脚本
将该脚本转换为 Windows 的 batch 脚本,需要进行以下修改:
1. 更改第一行为 `@echo off`,表示关闭命令回显。
2. 将变量的赋值方式从 `$变量名=值` 改为 `set 变量名=值`。
3. 将 `adb` 命令行中的路径分隔符 `/` 改为 Windows 下的路径分隔符 `\`。
4. 在执行命令行时需要使用 `call` 命令。
修改后的 batch 脚本如下:
```
@echo off
REM Assets
set TEST_IMG=demo.png
set SDK_ROOT=%cd%
set TEST_ROOT=%cd%
set BIN_NAME=test_demo
set DEVICE_TEST_PATH=/data/local/tmp/ts_ai_sdk_test
set MODEL_PATH=/sdcard/models
set RESULT=/data/local/tmp/ts_ai_sdk_test/results/
set RUNTIME=DSP
REM Push test assets
adb root
adb shell rm -rf %DEVICE_TEST_PATH%
adb shell mkdir -p %DEVICE_TEST_PATH%/jpgs
adb shell mkdir -p %DEVICE_TEST_PATH%/results/post_result
adb shell mkdir -p %DEVICE_TEST_PATH%/results/img_result
adb push images\* %DEVICE_TEST_PATH%/jpgs
REM Push SNPE libraries
adb push %SDK_ROOT%\libs\ %DEVICE_TEST_PATH%
adb push %SDK_ROOT%\models\model.exf %DEVICE_TEST_PATH%\
REM Push executable
adb push build\%BIN_NAME% %DEVICE_TEST_PATH%\
REM Test
adb shell "chmod +x %DEVICE_TEST_PATH%\%BIN_NAME%"
echo Running on Android device ...
echo "LD_LIBRARY_PATH='%DEVICE_TEST_PATH%\libs' %DEVICE_TEST_PATH%\%BIN_NAME% %DEVICE_TEST_PATH%/jpgs %RESULT% %DEVICE_TEST_PATH%/model.exf"
echo Done.
call adb shell "LD_LIBRARY_PATH='%DEVICE_TEST_PATH%\libs' %DEVICE_TEST_PATH%\%BIN_NAME% %DEVICE_TEST_PATH%/jpgs %RESULT% %DEVICE_TEST_PATH%\model.exf"
REM Pull result
adb pull %DEVICE_TEST_PATH%/results/ .
timeout /t 1
```
阅读全文