NEW: release DJI Payload-SDK version 3.1

Signed-off-by: DJI-Martin <DJI-Martin@dji.com>
This commit is contained in:
DJI-Martin
2022-03-21 22:25:37 +08:00
parent 7b5f853e87
commit 0e06bc3fd3
62 changed files with 9042 additions and 348 deletions

View File

@ -0,0 +1,708 @@
/**
********************************************************************
* @file test_widget_speaker.c
* @brief
*
* @copyright (c) 2018 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJIs authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#ifdef SYSTEM_ARCH_LINUX
#include "test_widget_speaker.h"
#include "dji_logger.h"
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include "utils/util_misc.h"
#include "utils/util_md5.h"
#ifdef OPUS_INSTALLED
#include <opus.h>
#endif
/* Private constants ---------------------------------------------------------*/
#define WIDGET_SPEAKER_TASK_STACK_SIZE (2048)
#define WIDGET_SPEAKER_USB_AUDIO_DEVICE_NAME "alsa_output.usb-C-Media_Electronics_Inc._USB_Audio_Device-00.analog-stereo"
#define WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME "test_audio.opus"
#define WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME "test_audio.pcm"
#define WIDGET_SPEAKER_TTS_FILE_NAME "test_tts.txt"
#define WIDGET_SPEAKER_TTS_OUTPUT_FILE_NAME "tts_sample.wav"
#define WIDGET_SPEAKER_TTS_FILE_MAX_SIZE (3000)
/*The frame size is hardcoded for this sample code but it doesn't have to be*/
#define WIDGET_SPEAKER_AUDIO_OPUS_MAX_PACKET_SIZE (3 * 1276)
#define WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE (6 * 960)
#define WIDGET_SPEAKER_AUDIO_OPUS_SAMPLE_RATE (16000)
#define WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS (1)
#define WIDGET_SPEAKER_AUDIO_OPUS_DECODE_FRAME_SIZE (160)
/* Private types -------------------------------------------------------------*/
/* Private values -------------------------------------------------------------*/
static T_DjiWidgetSpeakerHandler s_speakerHandler = {0};
static T_DjiMutexHandle s_speakerMutex = {0};
static T_DjiWidgetSpeakerState s_speakerState = {0};
static T_DjiTaskHandle s_widgetSpeakerTestThread;
static FILE *audioFile = NULL;
static FILE *ttsFile = NULL;
/* Private functions declaration ---------------------------------------------*/
static T_DjiReturnCode GetSpeakerState(T_DjiWidgetSpeakerState *speakerState);
static T_DjiReturnCode SetWorkMode(E_DjiWidgetSpeakerWorkMode workMode);
static T_DjiReturnCode GetWorkMode(E_DjiWidgetSpeakerWorkMode *workMode);
static T_DjiReturnCode SetPlayMode(E_DjiWidgetSpeakerPlayMode playMode);
static T_DjiReturnCode GetPlayMode(E_DjiWidgetSpeakerPlayMode *playMode);
static T_DjiReturnCode StartPlay(void);
static T_DjiReturnCode StopPlay(void);
static T_DjiReturnCode SetVolume(uint8_t volume);
static T_DjiReturnCode GetVolume(uint8_t *volume);
static T_DjiReturnCode ReceiveTtsData(E_DjiWidgetTransmitDataEvent event,
uint32_t offset, uint8_t *buf, uint16_t size);
static T_DjiReturnCode ReceiveAudioData(E_DjiWidgetTransmitDataEvent event,
uint32_t offset, uint8_t *buf, uint16_t size);
static void *DjiTest_WidgetSpeakerTask(void *arg);
static uint32_t DjiTest_GetVoicePlayProcessId(void);
static uint32_t DjiTest_KillVoicePlayProcess(uint32_t pid);
static T_DjiReturnCode DjiTest_DecodeAudioData(void);
static T_DjiReturnCode DjiTest_PlayAudioData(void);
static T_DjiReturnCode DjiTest_PlayTtsData(void);
static T_DjiReturnCode DjiTest_CheckFileMd5Sum(const char *path, uint8_t *buf, uint16_t size);
/* Exported functions definition ---------------------------------------------*/
T_DjiReturnCode DjiTest_WidgetSpeakerStartService(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
s_speakerHandler.GetSpeakerState = GetSpeakerState;
s_speakerHandler.SetWorkMode = SetWorkMode;
s_speakerHandler.GetWorkMode = GetWorkMode;
s_speakerHandler.StartPlay = StartPlay;
s_speakerHandler.StopPlay = StopPlay;
s_speakerHandler.SetPlayMode = SetPlayMode;
s_speakerHandler.GetPlayMode = GetPlayMode;
s_speakerHandler.SetVolume = SetVolume;
s_speakerHandler.GetVolume = GetVolume;
s_speakerHandler.ReceiveTtsData = ReceiveTtsData;
s_speakerHandler.ReceiveVoiceData = ReceiveAudioData;
returnCode = osalHandler->MutexCreate(&s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Create speaker mutex error: 0x%08llX", returnCode);
return returnCode;
}
returnCode = DjiWidget_RegSpeakerHandler(&s_speakerHandler);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Register speaker handler error: 0x%08llX", returnCode);
return returnCode;
}
if (osalHandler->TaskCreate("user_widget_speaker_task", DjiTest_WidgetSpeakerTask, WIDGET_SPEAKER_TASK_STACK_SIZE,
NULL,
&s_widgetSpeakerTestThread) != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Dji widget speaker test task create error.");
return DJI_ERROR_SYSTEM_MODULE_CODE_UNKNOWN;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
/* Private functions definition-----------------------------------------------*/
static uint32_t DjiTest_GetVoicePlayProcessId(void)
{
FILE *fp;
char cmdStr[128];
uint32_t pid;
int ret;
snprintf(cmdStr, 128, "pgrep ffplay");
fp = popen(cmdStr, "r");
if (fp == NULL) {
USER_LOG_ERROR("fp is null.");
return 0;
}
ret = fscanf(fp, "%u", &pid);
if (ret <= 0) {
USER_LOG_ERROR("get pid error.");
pid = 0;
goto out;
}
out:
pclose(fp);
return pid;
}
static uint32_t DjiTest_KillVoicePlayProcess(uint32_t pid)
{
FILE *fp;
char cmdStr[128];
snprintf(cmdStr, 128, "kill %d", pid);
fp = popen(cmdStr, "r");
if (fp == NULL) {
USER_LOG_ERROR("fp is null.");
return 0;
}
pclose(fp);
return pid;
}
static T_DjiReturnCode DjiTest_DecodeAudioData(void)
{
#ifdef OPUS_INSTALLED
FILE *fin;
FILE *fout;
OpusDecoder *decoder;
opus_int16 out[WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS];
uint8_t cbits[WIDGET_SPEAKER_AUDIO_OPUS_MAX_PACKET_SIZE];
int32_t nbBytes;
int32_t err;
/*! Attention: you can use "ffmpeg -i xxx.mp3 -ar 16000 -ac 1 out.wav" and use opus-tools to generate opus file for test */
fin = fopen(WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME, "r");
if (fin == NULL) {
fprintf(stderr, "failed to open input file: %s\n", strerror(errno));
return EXIT_FAILURE;
}
/* Create a new decoder state. */
decoder = opus_decoder_create(WIDGET_SPEAKER_AUDIO_OPUS_SAMPLE_RATE, WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS, &err);
if (err < 0) {
fprintf(stderr, "failed to create decoder: %s\n", opus_strerror(err));
return EXIT_FAILURE;
}
fout = fopen(WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME, "w");
if (fout == NULL) {
fprintf(stderr, "failed to open output file: %s\n", strerror(errno));
return EXIT_FAILURE;
}
USER_LOG_INFO("Decode Start...");
while (1) {
int i;
unsigned char pcm_bytes[WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS * 2];
int frame_size;
/* Read a 16 bits/sample audio frame. */
nbBytes = fread(cbits, 1, WIDGET_SPEAKER_AUDIO_OPUS_DECODE_FRAME_SIZE, fin);
if (feof(fin))
break;
/* Decode the data. In this example, frame_size will be constant because
the encoder is using a constant frame size. However, that may not
be the case for all encoders, so the decoder must always check
the frame size returned. */
frame_size = opus_decode(decoder, cbits, nbBytes, out, WIDGET_SPEAKER_AUDIO_OPUS_MAX_FRAME_SIZE, 0);
if (frame_size < 0) {
fprintf(stderr, "decoder failed: %s\n", opus_strerror(frame_size));
return EXIT_FAILURE;
}
USER_LOG_DEBUG("decode data to file: %d\r\n", frame_size * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS);
/* Convert to little-endian ordering. */
for (i = 0; i < WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS * frame_size; i++) {
pcm_bytes[2 * i] = out[i] & 0xFF;
pcm_bytes[2 * i + 1] = (out[i] >> 8) & 0xFF;
}
/* Write the decoded audio to file. */
fwrite(pcm_bytes, sizeof(short), frame_size * WIDGET_SPEAKER_AUDIO_OPUS_CHANNELS, fout);
}
/*Destroy the encoder state*/
opus_decoder_destroy(decoder);
fclose(fin);
fclose(fout);
USER_LOG_INFO("Decode Finished...");
#endif
return EXIT_SUCCESS;
}
static T_DjiReturnCode DjiTest_PlayAudioData(void)
{
char cmdStr[128];
memset(cmdStr, 0, sizeof(cmdStr));
snprintf(cmdStr, sizeof(cmdStr), "ffplay -nodisp -autoexit -ar 16000 -ac 1 -f s16le -i %s 2>/dev/null",
WIDGET_SPEAKER_AUDIO_PCM_FILE_NAME);
return DjiUserUtil_RunSystemCmd(cmdStr);
}
static T_DjiReturnCode DjiTest_PlayTtsData(void)
{
FILE *txtFile;
uint8_t data[WIDGET_SPEAKER_TTS_FILE_MAX_SIZE] = {0};
int32_t readLen;
char cmdStr[WIDGET_SPEAKER_TTS_FILE_MAX_SIZE + 128];
txtFile = fopen(WIDGET_SPEAKER_TTS_FILE_NAME, "r");
if (txtFile == NULL) {
fprintf(stderr, "failed to open input file: %s\n", strerror(errno));
return EXIT_FAILURE;
}
readLen = fread(data, 1, WIDGET_SPEAKER_TTS_FILE_MAX_SIZE, txtFile);
if (readLen <= 0) {
USER_LOG_ERROR("Read tts file failed, error code: %d", readLen);
fclose(txtFile);
return DJI_ERROR_SYSTEM_MODULE_CODE_NOT_FOUND;
}
fclose(txtFile);
USER_LOG_INFO("Read tts file success, len: %d", readLen);
USER_LOG_INFO("Content: %s", data);
memset(cmdStr, 0, sizeof(cmdStr));
/*! Attention: you can use other tts opensource function to convert txt to speech, example used ekho v7.5 */
snprintf(cmdStr, sizeof(cmdStr), " ekho %s -s 20 -p 20 -a 100", data);
return DjiUserUtil_RunSystemCmd(cmdStr);
}
static T_DjiReturnCode DjiTest_CheckFileMd5Sum(const char *path, uint8_t *buf, uint16_t size)
{
MD5_CTX md5Ctx;
uint32_t readFileTotalSize = 0;
uint16_t readLen;
T_DjiReturnCode returnCode;
uint8_t readBuf[1024];
uint8_t md5Sum[16];
FILE *file = NULL;;
UtilMd5_Init(&md5Ctx);
file = fopen(path, "rb");
if (file == NULL) {
USER_LOG_ERROR("Open tts file error.");
}
while (1) {
returnCode = fseek(file, readFileTotalSize, SEEK_SET);
if (returnCode != 0) {
USER_LOG_INFO("fseek file error");
}
readLen = fread(readBuf, 1, sizeof(readBuf), file);
if (readLen > 0) {
readFileTotalSize += readLen;
UtilMd5_Update(&md5Ctx, readBuf, readLen);
}
if (feof(file))
break;
}
UtilMd5_Final(&md5Ctx, md5Sum);
fclose(file);
if (size == sizeof(md5Sum)) {
if (memcmp(md5Sum, buf, sizeof(md5Sum)) == 0) {
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
} else {
return DJI_ERROR_SYSTEM_MODULE_CODE_SYSTEM_ERROR;
}
} else {
USER_LOG_ERROR("MD5 sum length error");
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetSpeakerState(T_DjiWidgetSpeakerState *speakerState)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
*speakerState = s_speakerState;
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetWorkMode(E_DjiWidgetSpeakerWorkMode workMode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
USER_LOG_INFO("Set widget speaker work mode: %d", workMode);
s_speakerState.workMode = workMode;
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetWorkMode(E_DjiWidgetSpeakerWorkMode *workMode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
*workMode = s_speakerState.workMode;
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetPlayMode(E_DjiWidgetSpeakerPlayMode playMode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
USER_LOG_INFO("Set widget speaker play mode: %d", playMode);
s_speakerState.playMode = playMode;
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetPlayMode(E_DjiWidgetSpeakerPlayMode *playMode)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
*playMode = s_speakerState.playMode;
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode StartPlay(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
USER_LOG_INFO("Start widget speaker play");
s_speakerState.state = DJI_WIDGET_SPEAKER_STATE_PLAYING;
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode StopPlay(void)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
uint32_t pid;
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
USER_LOG_INFO("Stop widget speaker play");
s_speakerState.state = DJI_WIDGET_SPEAKER_STATE_IDEL;
pid = DjiTest_GetVoicePlayProcessId();
if (pid != 0) {
DjiTest_KillVoicePlayProcess(pid);
}
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode SetVolume(uint8_t volume)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
char cmdStr[128];
int32_t ret = 0;
float realVolume;
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
realVolume = 1.5f * (float) volume;
USER_LOG_INFO("Set widget speaker volume: %d", volume);
s_speakerState.volume = volume;
memset(cmdStr, 0, sizeof(cmdStr));
snprintf(cmdStr, sizeof(cmdStr), "pactl set-sink-volume %s %d%%", WIDGET_SPEAKER_USB_AUDIO_DEVICE_NAME,
(int32_t) realVolume);
returnCode = DjiUserUtil_RunSystemCmd(cmdStr);
if (returnCode < 0) {
USER_LOG_ERROR("Set widget speaker volume error: %d", ret);
}
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode GetVolume(uint8_t *volume)
{
T_DjiReturnCode returnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
returnCode = osalHandler->MutexLock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
*volume = s_speakerState.volume;
returnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", returnCode);
return returnCode;
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode ReceiveTtsData(E_DjiWidgetTransmitDataEvent event,
uint32_t offset, uint8_t *buf, uint16_t size)
{
uint16_t writeLen;
T_DjiReturnCode returnCode;
if (event == DJI_WIDGET_TRANSMIT_DATA_EVENT_START) {
USER_LOG_INFO("Create tts file.");
ttsFile = fopen(WIDGET_SPEAKER_TTS_FILE_NAME, "wb");
if (ttsFile == NULL) {
USER_LOG_ERROR("Open tts file error.");
}
} else if (event == DJI_WIDGET_TRANSMIT_DATA_EVENT_TRANSMIT) {
USER_LOG_INFO("Transmit tts file, offset: %d, size: %d", offset, size);
if (ttsFile != NULL) {
fseek(ttsFile, offset, SEEK_SET);
writeLen = fwrite(buf, 1, size, ttsFile);
if (writeLen != size) {
USER_LOG_ERROR("Write tts file error %d", writeLen);
}
}
} else if (event == DJI_WIDGET_TRANSMIT_DATA_EVENT_FINISH) {
USER_LOG_INFO("Close tts file.");
if (ttsFile != NULL) {
fclose(ttsFile);
}
returnCode = DjiTest_CheckFileMd5Sum(WIDGET_SPEAKER_TTS_FILE_NAME, buf, size);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("File md5 sum check failed");
}
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
static T_DjiReturnCode ReceiveAudioData(E_DjiWidgetTransmitDataEvent event,
uint32_t offset, uint8_t *buf, uint16_t size)
{
uint16_t writeLen;
T_DjiReturnCode returnCode;
if (event == DJI_WIDGET_TRANSMIT_DATA_EVENT_START) {
USER_LOG_INFO("Create voice file.");
audioFile = fopen(WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME, "wb");
if (audioFile == NULL) {
USER_LOG_ERROR("Create tts file error.");
}
} else if (event == DJI_WIDGET_TRANSMIT_DATA_EVENT_TRANSMIT) {
USER_LOG_INFO("Transmit voice file, offset: %d, size: %d", offset, size);
if (audioFile != NULL) {
fseek(audioFile, offset, SEEK_SET);
writeLen = fwrite(buf, 1, size, audioFile);
if (writeLen != size) {
USER_LOG_ERROR("Write tts file error %d", writeLen);
}
}
} else if (event == DJI_WIDGET_TRANSMIT_DATA_EVENT_FINISH) {
USER_LOG_INFO("Close voice file.");
if (audioFile != NULL) {
fclose(audioFile);
}
returnCode = DjiTest_CheckFileMd5Sum(WIDGET_SPEAKER_AUDIO_OPUS_FILE_NAME, buf, size);
if (returnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("File md5 sum check failed");
}
DjiTest_DecodeAudioData();
}
return DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}
#ifndef __CC_ARM
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
#pragma GCC diagnostic ignored "-Wreturn-type"
#endif
static void *DjiTest_WidgetSpeakerTask(void *arg)
{
T_DjiReturnCode djiReturnCode;
T_DjiOsalHandler *osalHandler = DjiPlatform_GetOsalHandler();
USER_UTIL_UNUSED(arg);
while (1) {
osalHandler->TaskSleepMs(10);
if (s_speakerState.state == DJI_WIDGET_SPEAKER_STATE_PLAYING) {
if (s_speakerState.playMode == DJI_WIDGET_SPEAKER_PLAY_MODE_LOOP_PLAYBACK) {
if (s_speakerState.workMode == DJI_WIDGET_SPEAKER_WORK_MODE_VOICE) {
djiReturnCode = DjiTest_PlayAudioData();
if (djiReturnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Play audio data failed, error: 0x%08llX.", djiReturnCode);
}
} else {
djiReturnCode = DjiTest_PlayTtsData();
if (djiReturnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Play tts data failed, error: 0x%08llX.", djiReturnCode);
}
}
} else {
if (s_speakerState.workMode == DJI_WIDGET_SPEAKER_WORK_MODE_VOICE) {
djiReturnCode = DjiTest_PlayAudioData();
if (djiReturnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Play audio data failed, error: 0x%08llX.", djiReturnCode);
}
} else {
djiReturnCode = DjiTest_PlayTtsData();
if (djiReturnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("Play tts data failed, error: 0x%08llX.", djiReturnCode);
}
}
djiReturnCode = osalHandler->MutexLock(s_speakerMutex);
if (djiReturnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("lock mutex error: 0x%08llX.", djiReturnCode);
}
s_speakerState.state = DJI_WIDGET_SPEAKER_STATE_IDEL;
djiReturnCode = osalHandler->MutexUnlock(s_speakerMutex);
if (djiReturnCode != DJI_ERROR_SYSTEM_MODULE_CODE_SUCCESS) {
USER_LOG_ERROR("unlock mutex error: 0x%08llX.", djiReturnCode);
}
}
}
}
}
#ifndef __CC_ARM
#pragma GCC diagnostic pop
#endif
#endif
/****************** (C) COPYRIGHT DJI Innovations *****END OF FILE****/

View File

@ -0,0 +1,53 @@
/**
********************************************************************
* @file test_widget_speaker.h
* @brief This is the header file for "test_widget_speaker.c", defining the structure and
* (exported) function prototypes.
*
* @copyright (c) 2018 DJI. All rights reserved.
*
* All information contained herein is, and remains, the property of DJI.
* The intellectual and technical concepts contained herein are proprietary
* to DJI and may be covered by U.S. and foreign patents, patents in process,
* and protected by trade secret or copyright law. Dissemination of this
* information, including but not limited to data and other proprietary
* material(s) incorporated within the information, in any form, is strictly
* prohibited without the express written consent of DJI.
*
* If you receive this source code without DJIs authorization, you may not
* further disseminate the information, and you must immediately remove the
* source code and notify DJI of its removal. DJI reserves the right to pursue
* legal actions against you for any loss(es) or damage(s) caused by your
* failure to do so.
*
*********************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef TEST_WIDGET_SPEAKER_H
#define TEST_WIDGET_SPEAKER_H
/* Includes ------------------------------------------------------------------*/
#include "dji_widget.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef SYSTEM_ARCH_LINUX
/* Exported constants --------------------------------------------------------*/
T_DjiReturnCode DjiTest_WidgetSpeakerStartService(void);
/* Exported types ------------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
#endif
#ifdef __cplusplus
}
#endif
#endif // TEST_WIDGET_SPEAKER_H
/************************ (C) COPYRIGHT DJI Innovations *******END OF FILE******/

View File

@ -7,6 +7,10 @@
"floating_window": {
"is_enable": true
},
"speaker": {
"is_enable_tts": true,
"is_enable_voice": true
},
"widget_list": [
{
"widget_index": 0,

View File

@ -7,6 +7,10 @@
"floating_window": {
"is_enable": true
},
"speaker": {
"is_enable_tts": true,
"is_enable_voice": true
},
"widget_list": [
{
"widget_index": 0,