203
common/build.sh
Executable file
203
common/build.sh
Executable file
@ -0,0 +1,203 @@
|
||||
#!/bin/bash
|
||||
|
||||
source BoardConfig.mk
|
||||
echo "============================================"
|
||||
echo "TARGET_ARCH=$ARCH"
|
||||
echo "TARGET_PLATFORM=$TARGET_PRODUCT"
|
||||
echo "TARGET_UBOOT_CONFIG=$UBOOT_DEFCONFIG"
|
||||
echo "TARGET_KERNEL_CONFIG=$KERNEL_DEFCONFIG"
|
||||
echo "TARGET_BUILDROOT_CONFIG=$CFG_BUILDROOT"
|
||||
echo "TARGET_RECOVERY_CONFIG=$CFG_RECOVERY"
|
||||
echo "TARGET_PCBA_CONFIG=$CFG_PCBA"
|
||||
echo "============================================"
|
||||
|
||||
if [ ! -n "$1" ];then
|
||||
echo "build all as default"
|
||||
BUILD_TARGET=all
|
||||
else
|
||||
echo "build $1 only"
|
||||
BUILD_TARGET="$1"
|
||||
fi
|
||||
|
||||
usage()
|
||||
{
|
||||
echo "====USAGE: build.sh modules===="
|
||||
echo "uboot -build uboot"
|
||||
echo "kernel -build kernel"
|
||||
echo "rootfs -build buildroot rootfs"
|
||||
echo "yocto -build yocto rootfs"
|
||||
echo "debian -build debian rootfs"
|
||||
echo "pcba -build pcba"
|
||||
echo "default -build all modules"
|
||||
}
|
||||
|
||||
function build_uboot(){
|
||||
# build uboot
|
||||
echo "====Start build uboot===="
|
||||
cd u-boot && make distclean && ./make.sh $UBOOT_DEFCONFIG && cd -
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "====Build uboot ok!===="
|
||||
else
|
||||
echo "====Build uboot failed!===="
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function build_kernel(){
|
||||
# build kernel
|
||||
echo "====Start build kernel===="
|
||||
cd kernel && make ARCH=$ARCH distclean && make ARCH=$ARCH $KERNEL_DEFCONFIG && make ARCH=$ARCH $KERNEL_DTS.img -j$JOBS && cd -
|
||||
# arm use zboot.img
|
||||
if [ $ARCH == arm ]; then
|
||||
cp kernel/zboot.img kernel/boot.img
|
||||
fi
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "====Build kernel ok!===="
|
||||
else
|
||||
echo "====Build kernel failed!===="
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function build_rootfs(){
|
||||
# build buildroot
|
||||
echo "====Start build buildroot===="
|
||||
./device/rockchip/$TARGET_PRODUCT/mk-buildroot.sh
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "====Build buildroot ok!===="
|
||||
else
|
||||
echo "====Build buildroot failed!===="
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function build_yocto(){
|
||||
# build yocto
|
||||
echo "====Start build yocto===="
|
||||
./device/rockchip/$TARGET_PRODUCT/mk-yocto.sh
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "====Build yocto ok!===="
|
||||
else
|
||||
echo "====Build yocto failed!===="
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function build_recovery(){
|
||||
# build recovery
|
||||
echo "====Start build recovery===="
|
||||
./device/rockchip/$TARGET_PRODUCT/mk-recovery.sh
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "====Build recovery ok!===="
|
||||
else
|
||||
echo "====Build recovery failed!===="
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function build_pcba(){
|
||||
# build pcba
|
||||
echo "====Start build recovery===="
|
||||
./device/rockchip/$TARGET_PRODUCT/mk-pcba.sh
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "====Build pcba ok!===="
|
||||
else
|
||||
echo "====Build pcba failed!===="
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function build_all(){
|
||||
build_uboot
|
||||
build_kernel
|
||||
build_rootfs
|
||||
build_recovery
|
||||
}
|
||||
|
||||
TOP_DIR=$(pwd)
|
||||
source buildroot/build/envsetup.sh $CFG_BUILDROOT
|
||||
TARGET_PRODUCT=`get_target_board_type $CFG_BUILDROOT`
|
||||
PACK_TOOL_DIR=tools/linux/Linux_Pack_Firmware
|
||||
IMAGE_PATH=rockdev/Image-$TARGET_PRODUCT
|
||||
DATE=$(date +%Y%m%d.%H%M)
|
||||
STUB_PATH=Image/"$KERNEL_DTS"_"$DATE"_RELEASE_TEST
|
||||
STUB_PATH="$(echo $STUB_PATH | tr '[:lower:]' '[:upper:]')"
|
||||
export STUB_PATH=$TOP_DIR/$STUB_PATH
|
||||
export STUB_PATCH_PATH=$STUB_PATH/PATCHES
|
||||
|
||||
#=========================
|
||||
# build target
|
||||
#=========================
|
||||
if [ $BUILD_TARGET == uboot ];then
|
||||
build_uboot
|
||||
exit 0
|
||||
elif [ $BUILD_TARGET == kernel ];then
|
||||
build_kernel
|
||||
exit 0
|
||||
elif [ $BUILD_TARGET == rootfs ];then
|
||||
build_rootfs
|
||||
exit 0
|
||||
elif [ $BUILD_TARGET == recovery ];then
|
||||
build_recovery
|
||||
exit 0
|
||||
elif [ $BUILD_TARGET == pcba ];then
|
||||
build_pcba
|
||||
exit 0
|
||||
elif [ $BUILD_TARGET == yocto ];then
|
||||
build_yocto
|
||||
exit 0
|
||||
elif [ $BUILD_TARGET != all ];then
|
||||
echo "Can't found build config, please check again"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#==========================
|
||||
# default build all modules
|
||||
#==========================
|
||||
build_all
|
||||
|
||||
# mkfirmware.sh to genarate image
|
||||
echo "make and copy images"
|
||||
./mkfirmware.sh $CFG_BUILDROOT
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Make image ok!"
|
||||
else
|
||||
echo "Make image failed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p $PACK_TOOL_DIR/rockdev/Image/
|
||||
cp -f $IMAGE_PATH/* $PACK_TOOL_DIR/rockdev/Image/
|
||||
|
||||
echo "Make update.img"
|
||||
cd $PACK_TOOL_DIR/rockdev && ./mkupdate.sh
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Make update image ok!"
|
||||
else
|
||||
echo "Make update image failed!"
|
||||
exit 1
|
||||
fi
|
||||
cd -
|
||||
|
||||
mv $PACK_TOOL_DIR/rockdev/update.img $IMAGE_PATH/
|
||||
rm $PACK_TOOL_DIR/rockdev/Image -rf
|
||||
|
||||
mkdir -p $STUB_PATH
|
||||
|
||||
#Generate patches
|
||||
.repo/repo/repo forall -c "$TOP_DIR/device/rockchip/common/gen_patches_body.sh"
|
||||
|
||||
#Copy stubs
|
||||
.repo/repo/repo manifest -r -o $STUB_PATH/manifest_${DATE}.xml
|
||||
|
||||
mkdir -p $STUB_PATCH_PATH/kernel
|
||||
cp kernel/.config $STUB_PATCH_PATH/kernel
|
||||
cp kernel/vmlinux $STUB_PATCH_PATH/kernel
|
||||
mkdir -p $STUB_PATH/IMAGES/
|
||||
cp $IMAGE_PATH/* $STUB_PATH/IMAGES/
|
||||
|
||||
#Save build command info
|
||||
echo "UBOOT: defconfig: $UBOOT_DEFCONFIG" >> $STUB_PATH/build_cmd_info
|
||||
echo "KERNEL: defconfig: $KERNEL_DEFCONFIG, dts: $KERNEL_DTS" >> $STUB_PATH/build_cmd_info
|
||||
echo "BUILDROOT: $LUNCH" >> $STUB_PATH/build_cmd_info
|
||||
24
common/gen_patches_body.sh
Executable file
24
common/gen_patches_body.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
if [[ $REPO_REMOTE == rk* ]]; then
|
||||
REMOTE_DIFF=`git log $REPO_LREV..HEAD`
|
||||
LOCAL_DIFF=`git diff`
|
||||
if [ -n "$REMOTE_DIFF" ]; then
|
||||
mkdir -p $STUB_PATCH_PATH/$REPO_PATH/
|
||||
git format-patch $REPO_LREV..HEAD -o $STUB_PATCH_PATH/$REPO_PATH
|
||||
|
||||
echo "remote url:" >> $STUB_PATCH_PATH/$REPO_PATH/git-merge-base.txt
|
||||
REMOTE_URL=`git remote -v`
|
||||
echo "$REMOTE_URL" >> $STUB_PATCH_PATH/$REPO_PATH/git-merge-base.txt
|
||||
echo "remote branch:" >> $STUB_PATCH_PATH/$REPO_PATH/git-merge-base.txt
|
||||
git branch --contains $REPO_LREV -r >> $STUB_PATCH_PATH/$REPO_PATH/git-merge-base.txt
|
||||
git merge-base HEAD $REPO_LREV | xargs git show -s >> $STUB_PATCH_PATH/$REPO_PATH/git-merge-base.txt
|
||||
fi
|
||||
|
||||
if [ -n "$LOCAL_DIFF" ]; then
|
||||
mkdir -p $STUB_PATCH_PATH/$REPO_PATH/
|
||||
git diff --binary > $STUB_PATCH_PATH/$REPO_PATH/local_diff.patch
|
||||
fi
|
||||
if [ -n "$REMOTE_DIFF" -o -n "$LOCAL_DIFF" ]; then
|
||||
echo Generate patch for "$REPO_PATH" done
|
||||
fi
|
||||
fi
|
||||
7
px3se/build_all.sh
Executable file
7
px3se/build_all.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#! /bin/bash
|
||||
|
||||
./mk-uboot.sh
|
||||
./mk-kernel.sh
|
||||
./mk-rootfs.sh
|
||||
./mk-recovery.sh
|
||||
|
||||
10
px3se/mk-kernel.sh
Executable file
10
px3se/mk-kernel.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd kernel && make ARCH=arm rockchip_linux_defconfig && make ARCH=arm px3se-evb.img -j12 && cd -
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "====Build kernel ok!===="
|
||||
else
|
||||
echo "====Build kernel failed!===="
|
||||
exit 1
|
||||
fi
|
||||
70
px3se/mk-recovery.sh
Executable file
70
px3se/mk-recovery.sh
Executable file
@ -0,0 +1,70 @@
|
||||
#!/bin/bash
|
||||
#buildroot defconfig
|
||||
LUNCH=rockchip_px3se_recovery
|
||||
PROJECT_DIR=$(pwd)
|
||||
KERNEL_IMAGE=$PROJECT_DIR/kernel/arch/arm/boot/zImage
|
||||
KERNEL_DTB=$PROJECT_DIR/kernel/resource.img
|
||||
MAKE_KERNEL_SCRIPT=$PROJECT_DIR/device/rockchip/px3se/mk-kernel.sh
|
||||
usage()
|
||||
{
|
||||
echo "USAGE: build [-ovj]"
|
||||
echo "-o -Generate ota package"
|
||||
echo "-v -Set build version name for output image folder"
|
||||
echo "-j -Build jobs"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# check pass argument
|
||||
while getopts "ovj:" arg
|
||||
do
|
||||
case $arg in
|
||||
o)
|
||||
echo "will build ota package"
|
||||
BUILD_OTA=true
|
||||
;;
|
||||
v)
|
||||
BUILD_VERSION=$OPTARG
|
||||
;;
|
||||
j)
|
||||
JOBS=$OPTARG
|
||||
;;
|
||||
?)
|
||||
usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
TOP_DIR=$(pwd)
|
||||
source buildroot/build/envsetup.sh $LUNCH
|
||||
|
||||
BUILD_CONFIG=`get_defconfig_name`
|
||||
echo "$BUILD_CONFIG"
|
||||
|
||||
RAMDISK_IMAGE=buildroot/output/$BUILD_CONFIG/images/rootfs.cpio.gz
|
||||
RECOVERY_IMAGE=buildroot/output/$BUILD_CONFIG/images/recovery.img
|
||||
# build kernel
|
||||
if [ -f $KERNEL_IMAGE ]
|
||||
then
|
||||
echo "found kernel image"
|
||||
else
|
||||
echo "kernel image doesn't exist, now build kernel image"
|
||||
$MAKE_KERNEL_SCRIPT
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "build kernel done"
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# build recovery
|
||||
echo "====Start build recovery===="
|
||||
make
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "====Build recovery ok!===="
|
||||
else
|
||||
echo "====Build recovery failed!===="
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -n "pack recovery image..."
|
||||
$PROJECT_DIR/kernel/scripts/mkbootimg --kernel $KERNEL_IMAGE --ramdisk $RAMDISK_IMAGE --second $KERNEL_DTB -o $RECOVERY_IMAGE
|
||||
echo "done."
|
||||
23
px3se/mk-rootfs.sh
Executable file
23
px3se/mk-rootfs.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
#buildroot defconfig
|
||||
LUNCH=rockchip_px3se
|
||||
#build jobs
|
||||
JOBS=12
|
||||
TOP_DIR=$(pwd)
|
||||
source buildroot/build/envsetup.sh $LUNCH
|
||||
TARGET_PRODUCT=`get_target_board_type $LUNCH`
|
||||
echo "$TARGET_PRODUCT"
|
||||
export PROJECT_TOP=$TOP_DIR
|
||||
BUILD_CONFIG=`get_defconfig_name`
|
||||
echo "$BUILD_CONFIG"
|
||||
ROOTFS_IMAGE=buildroot/output/$BUILD_CONFIG/images/rootfs.img
|
||||
# build rootfs
|
||||
echo "====Start build rootfs===="
|
||||
make
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "====Build rootfs ok!===="
|
||||
else
|
||||
echo "====Build rootfs failed!===="
|
||||
exit 1
|
||||
fi
|
||||
|
||||
10
px3se/mk-uboot.sh
Executable file
10
px3se/mk-uboot.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd u-boot && ./make.sh evb-px3se && cd -
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "====Build uboot ok!===="
|
||||
else
|
||||
echo "====Build uboot failed!===="
|
||||
exit 1
|
||||
fi
|
||||
120
px3se/mkfirmware.sh
Executable file
120
px3se/mkfirmware.sh
Executable file
@ -0,0 +1,120 @@
|
||||
TOOL_PATH=$(pwd)/build
|
||||
IMAGE_OUT_PATH=$(pwd)/rockdev
|
||||
KERNEL_PATH=$(pwd)/kernel
|
||||
UBOOT_PATH=$(pwd)/u-boot
|
||||
ROOTFS_PATH=$(pwd)/rootfs
|
||||
DEVICE_IMG_PATH=$(pwd)/device/rockchip/px3se/rockdev
|
||||
PARAMETER_PATH=$DEVICE_IMG_PATH/parameter.txt
|
||||
OEM_IMG_PATH=$DEVICE_IMG_PATH/oem.img
|
||||
USER_DATA_IMG_PATH=$DEVICE_IMG_PATH/userdata.img
|
||||
MISC_IMG_PATH=$DEVICE_IMG_PATH/wipe_all-misc.img
|
||||
ROOTFS_IMG_PATH=$(pwd)/buildroot/output/rockchip_px3se/images/rootfs.ext4
|
||||
RECOVERY_PATH=$(pwd)/buildroot/output/rockchip_px3se_recovery/images/recovery.img
|
||||
TRUST_PATH=$UBOOT_PATH/trust_emmc.img
|
||||
BOOT_PATH=$KERNEL_PATH/zboot.img
|
||||
LOADER_PATH=$UBOOT_PATH/*_loader_*.bin
|
||||
|
||||
mkdir -p $IMAGE_OUT_PATH
|
||||
|
||||
if [ -f $ROOTFS_IMG_PATH ]
|
||||
then
|
||||
echo -n "create rootfs.img..."
|
||||
ln -s -f $ROOTFS_IMG_PATH $IMAGE_OUT_PATH/rootfs.img
|
||||
echo "done"
|
||||
else
|
||||
echo -e "\e[31m error: $ROOTFS_IMG_PATH not found! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $RECOVERY_PATH ]
|
||||
then
|
||||
echo -n "create recovery.img..."
|
||||
ln -s -f $RECOVERY_PATH $IMAGE_OUT_PATH/
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $RECOVERY_PATH not found! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $MISC_IMG_PATH ]
|
||||
then
|
||||
echo -n "create misc.img..."
|
||||
ln -s -f $MISC_IMG_PATH $IMAGE_OUT_PATH/misc.img
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $MISC_IMG_PATH not found! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $PARAMETER_PATH ]
|
||||
then
|
||||
echo -n "create parameter.txt..."
|
||||
ln -s -f $PARAMETER_PATH $IMAGE_OUT_PATH/
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $PARAMETER_PATH not found! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $OEM_IMG_PATH ]
|
||||
then
|
||||
echo -n "create oem.img..."
|
||||
ln -s -f $OEM_IMG_PATH $IMAGE_OUT_PATH/
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $OEM_IMG_PATH not found! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $USER_DATA_IMG_PATH ]
|
||||
then
|
||||
echo -n "create userdata.img..."
|
||||
ln -s -f $USER_DATA_IMG_PATH $IMAGE_OUT_PATH/
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $USER_DATA_IMG_PATH not found! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $UBOOT_PATH/uboot.img ]
|
||||
then
|
||||
echo -n "create uboot.img..."
|
||||
ln -s -f $UBOOT_PATH/uboot.img $IMAGE_OUT_PATH/uboot.img
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $UBOOT_PATH/uboot.img not found! Please make it from $UBOOT_PATH first! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $TRUST_PATH ]
|
||||
then
|
||||
echo -n "create trust.img..."
|
||||
ln -s -f $TRUST_PATH $IMAGE_OUT_PATH/trust.img
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $UBOOT_PATH/trust.img not found! Please make it from $UBOOT_PATH first! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $LOADER_PATH ]
|
||||
then
|
||||
echo -n "create loader..."
|
||||
ln -s -f $LOADER_PATH $IMAGE_OUT_PATH/MiniLoaderAll.bin
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $UBOOT_PATH/*loader_*.bin not found,or there are multiple loaders! Please make it from $UBOOT_PATH first! \e[0m"
|
||||
rm $LOADER_PATH
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $BOOT_PATH ]
|
||||
then
|
||||
echo -n "create boot.img..."
|
||||
ln -s -f $BOOT_PATH $IMAGE_OUT_PATH/boot.img
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $KERNEL_PATH/boot.img not found! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -e "\e[36m Image: image in rockdev is ready \e[0m"
|
||||
87
px3se/rkflash.sh
Executable file
87
px3se/rkflash.sh
Executable file
@ -0,0 +1,87 @@
|
||||
|
||||
UPGRADETOOL=$(pwd)/tools/linux/Linux_Upgrade_Tool/Linux_Upgrade_Tool/upgrade_tool
|
||||
ROCKDEV_DIR=$(pwd)/rockdev
|
||||
LOADER=$ROCKDEV_DIR/MiniLoaderAll.bin
|
||||
PARAMETER=$ROCKDEV_DIR/parameter.txt
|
||||
UBOOT=$ROCKDEV_DIR/uboot.img
|
||||
TRUST=$ROCKDEV_DIR/trust.img
|
||||
BOOT=$ROCKDEV_DIR/boot.img
|
||||
RECOVERY=$ROCKDEV_DIR/recovery.img
|
||||
OEM=$ROCKDEV_DIR/oem.img
|
||||
MISC=$ROCKDEV_DIR/misc.img
|
||||
ROOTFS=$ROCKDEV_DIR/rootfs.img
|
||||
USERDATA=$ROCKDEV_DIR/userdata.img
|
||||
|
||||
if [ ! -n "$1" ]
|
||||
then
|
||||
echo "flash all images as default"
|
||||
FLASH_TYPE=all
|
||||
else
|
||||
FLASH_TYPE="$1"
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = all ]
|
||||
then
|
||||
sudo $UPGRADETOOL ul $LOADER
|
||||
sudo $UPGRADETOOL di -p $PARAMETER
|
||||
sudo $UPGRADETOOL di -uboot $UBOOT
|
||||
sudo $UPGRADETOOL di -trust $TRUST
|
||||
sudo $UPGRADETOOL di -b $BOOT
|
||||
sudo $UPGRADETOOL di -r $RECOVERY
|
||||
sudo $UPGRADETOOL di -m $MISC
|
||||
sudo $UPGRADETOOL di -oem $OEM
|
||||
sudo $UPGRADETOOL di -userdata $USERDATA
|
||||
sudo $UPGRADETOOL di -rootfs $ROOTFS
|
||||
sudo $UPGRADETOOL rd
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = loader ]
|
||||
then
|
||||
sudo $UPGRADETOOL ul $LOADER
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = parameter ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -p $PARAMETER
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = uboot ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -uboot $UBOOT
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = trust ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -trust $TRUST
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = boot ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -b $BOOT
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = recovery ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -r $RECOVERY
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = misc ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -misc $MISC
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = oem ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -oem $OEM
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = userdata ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -userdata $USERDATA
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = rootfs ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -rootfs $ROOTFS
|
||||
fi
|
||||
|
||||
BIN
px3se/rockdev/blank-misc.img
Executable file
BIN
px3se/rockdev/blank-misc.img
Executable file
Binary file not shown.
BIN
px3se/rockdev/oem.img
Normal file
BIN
px3se/rockdev/oem.img
Normal file
Binary file not shown.
12
px3se/rockdev/parameter.txt
Normal file
12
px3se/rockdev/parameter.txt
Normal file
@ -0,0 +1,12 @@
|
||||
FIRMWARE_VER: 8.1
|
||||
MACHINE_MODEL: RK3128
|
||||
MACHINE_ID: 007
|
||||
MANUFACTURER: RK3128
|
||||
MAGIC: 0x5041524B
|
||||
ATAG: 0x00200800
|
||||
MACHINE: 3128
|
||||
CHECK_MASK: 0x80
|
||||
PWR_HLD: 0,0,A,0,1
|
||||
TYPE: GPT
|
||||
CMDLINE: mtdparts=rk29xxnand:0x00002000@0x00004000(uboot),0x00002000@0x00006000(trust),0x00002000@0x00008000(misc),0x00010000@0x0000a000(boot),0x00010000@0x0001a000(recovery),0x00010000@0x0002a000(backup),0x00020000@0x0003a000(oem),0x00700000@0x0005a000(rootfs),-@0x0075a000(userdata:grow)
|
||||
uuid:rootfs=614e0000-0000-4b53-8000-1d28000054a9
|
||||
BIN
px3se/rockdev/pcba_small_misc.img
Executable file
BIN
px3se/rockdev/pcba_small_misc.img
Executable file
Binary file not shown.
BIN
px3se/rockdev/pcba_whole_misc.img
Executable file
BIN
px3se/rockdev/pcba_whole_misc.img
Executable file
Binary file not shown.
BIN
px3se/rockdev/userdata.img
Normal file
BIN
px3se/rockdev/userdata.img
Normal file
Binary file not shown.
BIN
px3se/rockdev/wipe_all-misc.img
Executable file
BIN
px3se/rockdev/wipe_all-misc.img
Executable file
Binary file not shown.
7
rk3288/build_all.sh
Executable file
7
rk3288/build_all.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#! /bin/bash
|
||||
|
||||
./mk-uboot.sh
|
||||
./mk-kernel.sh
|
||||
./mk-rootfs.sh
|
||||
./mk-recovery.sh
|
||||
|
||||
10
rk3288/mk-kernel.sh
Executable file
10
rk3288/mk-kernel.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd kernel && make ARCH=arm rockchip_linux_defconfig && make ARCH=arm rk3288-evb-rk808-linux.img -j12 && cd -
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "====Build kernel ok!===="
|
||||
else
|
||||
echo "====Build kernel failed!===="
|
||||
exit 1
|
||||
fi
|
||||
70
rk3288/mk-recovery.sh
Executable file
70
rk3288/mk-recovery.sh
Executable file
@ -0,0 +1,70 @@
|
||||
#!/bin/bash
|
||||
#buildroot defconfig
|
||||
LUNCH=rockchip_rk3288_recovery
|
||||
PROJECT_DIR=$(pwd)
|
||||
KERNEL_IMAGE=$PROJECT_DIR/kernel/arch/arm/boot/zImage
|
||||
KERNEL_DTB=$PROJECT_DIR/kernel/resource.img
|
||||
MAKE_KERNEL_SCRIPT=$PROJECT_DIR/device/rockchip/rk3288/mk-kernel.sh
|
||||
usage()
|
||||
{
|
||||
echo "USAGE: build [-ovj]"
|
||||
echo "-o -Generate ota package"
|
||||
echo "-v -Set build version name for output image folder"
|
||||
echo "-j -Build jobs"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# check pass argument
|
||||
while getopts "ovj:" arg
|
||||
do
|
||||
case $arg in
|
||||
o)
|
||||
echo "will build ota package"
|
||||
BUILD_OTA=true
|
||||
;;
|
||||
v)
|
||||
BUILD_VERSION=$OPTARG
|
||||
;;
|
||||
j)
|
||||
JOBS=$OPTARG
|
||||
;;
|
||||
?)
|
||||
usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
TOP_DIR=$(pwd)
|
||||
source buildroot/build/envsetup.sh $LUNCH
|
||||
|
||||
BUILD_CONFIG=`get_defconfig_name`
|
||||
echo "$BUILD_CONFIG"
|
||||
|
||||
RAMDISK_IMAGE=buildroot/output/$BUILD_CONFIG/images/rootfs.cpio.gz
|
||||
RECOVERY_IMAGE=buildroot/output/$BUILD_CONFIG/images/recovery.img
|
||||
# build kernel
|
||||
if [ -f $KERNEL_IMAGE ]
|
||||
then
|
||||
echo "found kernel image"
|
||||
else
|
||||
echo "kernel image doesn't exist, now build kernel image"
|
||||
$MAKE_KERNEL_SCRIPT
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "build kernel done"
|
||||
else
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# build recovery
|
||||
echo "====Start build recovery===="
|
||||
make
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "====Build recovery ok!===="
|
||||
else
|
||||
echo "====Build recovery failed!===="
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -n "pack recovery image..."
|
||||
$PROJECT_DIR/kernel/scripts/mkbootimg --kernel $KERNEL_IMAGE --ramdisk $RAMDISK_IMAGE --second $KERNEL_DTB -o $RECOVERY_IMAGE
|
||||
echo "done."
|
||||
23
rk3288/mk-rootfs.sh
Executable file
23
rk3288/mk-rootfs.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
#buildroot defconfig
|
||||
LUNCH=rockchip_rk3288
|
||||
#build jobs
|
||||
JOBS=12
|
||||
TOP_DIR=$(pwd)
|
||||
source buildroot/build/envsetup.sh $LUNCH
|
||||
TARGET_PRODUCT=`get_target_board_type $LUNCH`
|
||||
echo "$TARGET_PRODUCT"
|
||||
export PROJECT_TOP=$TOP_DIR
|
||||
BUILD_CONFIG=`get_defconfig_name`
|
||||
echo "$BUILD_CONFIG"
|
||||
ROOTFS_IMAGE=buildroot/output/$BUILD_CONFIG/images/rootfs.img
|
||||
# build rootfs
|
||||
echo "====Start build rootfs===="
|
||||
make
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "====Build rootfs ok!===="
|
||||
else
|
||||
echo "====Build rootfs failed!===="
|
||||
exit 1
|
||||
fi
|
||||
|
||||
10
rk3288/mk-uboot.sh
Executable file
10
rk3288/mk-uboot.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd u-boot && ./make.sh fennec-rk3288 && cd -
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "====Build uboot ok!===="
|
||||
else
|
||||
echo "====Build uboot failed!===="
|
||||
exit 1
|
||||
fi
|
||||
128
rk3288/mkfirmware.sh
Executable file
128
rk3288/mkfirmware.sh
Executable file
@ -0,0 +1,128 @@
|
||||
TOOL_PATH=$(pwd)/build
|
||||
IMAGE_OUT_PATH=$(pwd)/rockdev
|
||||
KERNEL_PATH=$(pwd)/kernel
|
||||
UBOOT_PATH=$(pwd)/u-boot
|
||||
ROOTFS_PATH=$(pwd)/rootfs
|
||||
DEVICE_IMG_PATH=$(pwd)/device/rockchip/rk3288/rockdev
|
||||
PARAMETER_PATH=$DEVICE_IMG_PATH/parameter.txt
|
||||
OEM_IMG_PATH=$DEVICE_IMG_PATH/oem.img
|
||||
USER_DATA_IMG_PATH=$DEVICE_IMG_PATH/userdata.img
|
||||
MISC_IMG_PATH=$DEVICE_IMG_PATH/wipe_all-misc.img
|
||||
ROOTFS_IMG_PATH=$(pwd)/buildroot/output/rockchip_rk3288/images/rootfs.ext4
|
||||
RECOVERY_PATH=$(pwd)/buildroot/output/rockchip_rk3288_recovery/images/recovery.img
|
||||
TRUST_PATH=$UBOOT_PATH/trust.img
|
||||
BOOT_PATH=$KERNEL_PATH/zboot.img
|
||||
LOADER_PATH=$UBOOT_PATH/*_loader_*.bin
|
||||
ROOTFS_TYPE=
|
||||
mkdir -p $IMAGE_OUT_PATH
|
||||
if [ ! -n "$1" ]
|
||||
then
|
||||
echo "build buildroot type rootfs as default"
|
||||
ROOTFS_TYPE=buildroot
|
||||
else
|
||||
ROOTFS_TYPE="$1"
|
||||
fi
|
||||
|
||||
if [ $ROOTFS_TYPE = debian ]
|
||||
then
|
||||
echo -n "create rootfs.img..."
|
||||
ln -s -f $ROOTFS_PATH/linaro-rootfs.img $IMAGE_OUT_PATH/rootfs.img
|
||||
echo "done."
|
||||
else
|
||||
echo -n "create rootfs.img..."
|
||||
ln -s -f $ROOTFS_IMG_PATH $IMAGE_OUT_PATH/rootfs.img
|
||||
echo "done"
|
||||
fi
|
||||
|
||||
if [ -f $RECOVERY_PATH ]
|
||||
then
|
||||
echo -n "create recovery.img..."
|
||||
ln -s -f $RECOVERY_PATH $IMAGE_OUT_PATH/
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $RECOVERY_PATH not found! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $MISC_IMG_PATH ]
|
||||
then
|
||||
echo -n "create misc.img..."
|
||||
ln -s -f $MISC_IMG_PATH $IMAGE_OUT_PATH/misc.img
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $MISC_IMG_PATH not found! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $PARAMETER_PATH ]
|
||||
then
|
||||
echo -n "create parameter.txt..."
|
||||
ln -s -f $PARAMETER_PATH $IMAGE_OUT_PATH/
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $PARAMETER_PATH not found! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $OEM_IMG_PATH ]
|
||||
then
|
||||
echo -n "create oem.img..."
|
||||
ln -s -f $OEM_IMG_PATH $IMAGE_OUT_PATH/
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $OEM_IMG_PATH not found! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $USER_DATA_IMG_PATH ]
|
||||
then
|
||||
echo -n "create userdata.img..."
|
||||
ln -s -f $USER_DATA_IMG_PATH $IMAGE_OUT_PATH/
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $USER_DATA_IMG_PATH not found! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $UBOOT_PATH/uboot.img ]
|
||||
then
|
||||
echo -n "create uboot.img..."
|
||||
ln -s -f $UBOOT_PATH/uboot.img $IMAGE_OUT_PATH/uboot.img
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $UBOOT_PATH/uboot.img not found! Please make it from $UBOOT_PATH first! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $TRUST_PATH ]
|
||||
then
|
||||
echo -n "create trust.img..."
|
||||
ln -s -f $TRUST_PATH $IMAGE_OUT_PATH/trust.img
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $UBOOT_PATH/trust.img not found! Please make it from $UBOOT_PATH first! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $LOADER_PATH ]
|
||||
then
|
||||
echo -n "create loader..."
|
||||
ln -s -f $LOADER_PATH $IMAGE_OUT_PATH/MiniLoaderAll.bin
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $UBOOT_PATH/*loader_*.bin not found,or there are multiple loaders! Please make it from $UBOOT_PATH first! \e[0m"
|
||||
rm $LOADER_PATH
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -f $BOOT_PATH ]
|
||||
then
|
||||
echo -n "create boot.img..."
|
||||
ln -s -f $BOOT_PATH $IMAGE_OUT_PATH/boot.img
|
||||
echo "done."
|
||||
else
|
||||
echo -e "\e[31m error: $KERNEL_PATH/boot.img not found! \e[0m"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -e "\e[36m Image: image in rockdev is ready \e[0m"
|
||||
87
rk3288/rkflash.sh
Executable file
87
rk3288/rkflash.sh
Executable file
@ -0,0 +1,87 @@
|
||||
|
||||
UPGRADETOOL=$(pwd)/tools/linux/Linux_Upgrade_Tool/Linux_Upgrade_Tool/upgrade_tool
|
||||
ROCKDEV_DIR=$(pwd)/rockdev
|
||||
LOADER=$ROCKDEV_DIR/MiniLoaderAll.bin
|
||||
PARAMETER=$ROCKDEV_DIR/parameter.txt
|
||||
UBOOT=$ROCKDEV_DIR/uboot.img
|
||||
TRUST=$ROCKDEV_DIR/trust.img
|
||||
BOOT=$ROCKDEV_DIR/boot.img
|
||||
RECOVERY=$ROCKDEV_DIR/recovery.img
|
||||
OEM=$ROCKDEV_DIR/oem.img
|
||||
MISC=$ROCKDEV_DIR/misc.img
|
||||
ROOTFS=$ROCKDEV_DIR/rootfs.img
|
||||
USERDATA=$ROCKDEV_DIR/userdata.img
|
||||
|
||||
if [ ! -n "$1" ]
|
||||
then
|
||||
echo "flash all images as default"
|
||||
FLASH_TYPE=all
|
||||
else
|
||||
FLASH_TYPE="$1"
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = all ]
|
||||
then
|
||||
sudo $UPGRADETOOL ul $LOADER
|
||||
sudo $UPGRADETOOL di -p $PARAMETER
|
||||
sudo $UPGRADETOOL di -uboot $UBOOT
|
||||
sudo $UPGRADETOOL di -trust $TRUST
|
||||
sudo $UPGRADETOOL di -b $BOOT
|
||||
sudo $UPGRADETOOL di -r $RECOVERY
|
||||
sudo $UPGRADETOOL di -m $MISC
|
||||
sudo $UPGRADETOOL di -oem $OEM
|
||||
sudo $UPGRADETOOL di -userdata $USERDATA
|
||||
sudo $UPGRADETOOL di -rootfs $ROOTFS
|
||||
sudo $UPGRADETOOL rd
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = loader ]
|
||||
then
|
||||
sudo $UPGRADETOOL ul $LOADER
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = parameter ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -p $PARAMETER
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = uboot ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -uboot $UBOOT
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = trust ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -trust $TRUST
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = boot ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -b $BOOT
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = recovery ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -r $RECOVERY
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = misc ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -misc $MISC
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = oem ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -oem $OEM
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = userdata ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -userdata $USERDATA
|
||||
fi
|
||||
|
||||
if [ $FLASH_TYPE = rootfs ]
|
||||
then
|
||||
sudo $UPGRADETOOL di -rootfs $ROOTFS
|
||||
fi
|
||||
|
||||
BIN
rk3288/rockdev/blank-misc.img
Executable file
BIN
rk3288/rockdev/blank-misc.img
Executable file
Binary file not shown.
BIN
rk3288/rockdev/oem.img
Normal file
BIN
rk3288/rockdev/oem.img
Normal file
Binary file not shown.
12
rk3288/rockdev/parameter.txt
Normal file
12
rk3288/rockdev/parameter.txt
Normal file
@ -0,0 +1,12 @@
|
||||
FIRMWARE_VER: 8.1
|
||||
MACHINE_MODEL:rk3288
|
||||
MACHINE_ID:007
|
||||
MANUFACTURER:RK3288
|
||||
MAGIC: 0x5041524B
|
||||
ATAG: 0x00200800
|
||||
MACHINE: 3288
|
||||
CHECK_MASK: 0x80
|
||||
PWR_HLD: 0,0,A,0,1
|
||||
TYPE: GPT
|
||||
CMDLINE: mtdparts=rk29xxnand:0x00002000@0x00004000(uboot),0x00002000@0x00006000(trust),0x00002000@0x00008000(misc),0x00010000@0x0000a000(boot),0x00010000@0x0001a000(recovery),0x00010000@0x0002a000(backup),0x00020000@0x0003a000(oem),0x00700000@0x0005a000(rootfs),-@0x0075a000(userdata:grow)
|
||||
uuid:rootfs=614e0000-0000-4b53-8000-1d28000054a9
|
||||
BIN
rk3288/rockdev/pcba_small_misc.img
Executable file
BIN
rk3288/rockdev/pcba_small_misc.img
Executable file
Binary file not shown.
BIN
rk3288/rockdev/pcba_whole_misc.img
Executable file
BIN
rk3288/rockdev/pcba_whole_misc.img
Executable file
Binary file not shown.
BIN
rk3288/rockdev/userdata.img
Normal file
BIN
rk3288/rockdev/userdata.img
Normal file
Binary file not shown.
BIN
rk3288/rockdev/wipe_all-misc.img
Executable file
BIN
rk3288/rockdev/wipe_all-misc.img
Executable file
Binary file not shown.
41
rk3308/BoardConfig.mk
Executable file
41
rk3308/BoardConfig.mk
Executable file
@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
|
||||
#=========================
|
||||
# Compile Config
|
||||
#=========================
|
||||
# Target arch
|
||||
ARCH=arm64
|
||||
# Uboot defconfig
|
||||
UBOOT_DEFCONFIG=evb-rk3308
|
||||
# Kernel defconfig
|
||||
KERNEL_DEFCONFIG=rk3308_linux_defconfig
|
||||
# Kernel dts
|
||||
KERNEL_DTS=rk3308-evb-dmic-pdm-v11
|
||||
# Buildroot config
|
||||
CFG_BUILDROOT=rockchip_rk3308_release
|
||||
# Recovery config
|
||||
CFG_RECOVERY=rockchip_rk3308_recovery
|
||||
# Pcba config
|
||||
CFG_PCBA=rockchip_rk3308_pcba
|
||||
# Build jobs
|
||||
JOBS=12
|
||||
|
||||
#=========================
|
||||
# Platform Target
|
||||
#=========================
|
||||
TARGET_PRODUCT=rk3308
|
||||
|
||||
# Set rootfs type, see buildroot.
|
||||
# ext4 squashfs
|
||||
ROOTFS_TYPE=squashfs
|
||||
|
||||
# Set data partition type.
|
||||
# ext2 squashfs
|
||||
OEM_PARTITION_TYPE=ext2
|
||||
|
||||
# Set flash type.
|
||||
# support <emmc, nand, spi_nand, spi_nor>
|
||||
FLASH_TYPE=nand
|
||||
|
||||
#OEM config: /oem/dueros/aispeech/iflytekSDK/CaeDemo_VAD/smart_voice
|
||||
OEM_PATH=oem
|
||||
41
rk3308/BoardConfig_32bit.mk
Executable file
41
rk3308/BoardConfig_32bit.mk
Executable file
@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
|
||||
#=========================
|
||||
# Compile Config
|
||||
#=========================
|
||||
# Target arch
|
||||
ARCH=arm
|
||||
# Uboot defconfig
|
||||
UBOOT_DEFCONFIG=evb-aarch32-rk3308
|
||||
# Kernel defconfig
|
||||
KERNEL_DEFCONFIG=rk3308_linux_aarch32_debug_defconfig
|
||||
# Kernel dts
|
||||
KERNEL_DTS=rk3308-voice-module-board-v10-aarch32
|
||||
# Buildroot config
|
||||
CFG_BUILDROOT=rockchip_rk3308_32_release
|
||||
# Recovery config
|
||||
CFG_RECOVERY=rockchip_rk3308_recovery
|
||||
# Pcba config
|
||||
CFG_PCBA=rockchip_rk3308_pcba
|
||||
# Build jobs
|
||||
JOBS=12
|
||||
|
||||
#=========================
|
||||
# Platform Target
|
||||
#=========================
|
||||
TARGET_PRODUCT=rk3308
|
||||
|
||||
# Set rootfs type, see buildroot.
|
||||
# ext4 squashfs
|
||||
ROOTFS_TYPE=squashfs
|
||||
|
||||
# Set data partition type.
|
||||
# ext2 squashfs
|
||||
OEM_PARTITION_TYPE=ext2
|
||||
|
||||
# Set flash type.
|
||||
# support <emmc, nand, spi_nand, spi_nor>
|
||||
FLASH_TYPE=nand
|
||||
|
||||
#OEM config: /oem/dueros/aispeech/iflytekSDK/CaeDemo_VAD
|
||||
OEM_PATH=oem
|
||||
21
rk3308/CaeDemo_VAD/RkLunch.sh
Executable file
21
rk3308/CaeDemo_VAD/RkLunch.sh
Executable file
@ -0,0 +1,21 @@
|
||||
#cd /data
|
||||
#wpa_supplicant -B -i wlan0 -c /data/cfg/wpa_supplicant.conf
|
||||
#kill input-event-daemon
|
||||
#input-event-daemon -v -c /data/input-event-daemon.conf
|
||||
|
||||
#echo 0x60 0x00ff0050 > /sys/kernel/debug/vad/reg
|
||||
#echo 5 > /sys/class/gpio/export
|
||||
#echo out > /sys/class/gpio/gpio5/direction
|
||||
#echo 0> /sys/class/gpio/gpio5/value
|
||||
#sleep 1
|
||||
#echo 0 > /sys/class/gpio/gpio5/value
|
||||
|
||||
echo 0x60 0x40ff0168 > /sys/kernel/debug/vad/reg
|
||||
echo 0x5c 0x000e2200 > /sys/kernel/debug/vad/reg
|
||||
#echo 0x64 0x365fe663> /sys/kernel/debug/vad/reg
|
||||
#echo 0x68 0x365f9343> /sys/kernel/debug/vad/reg
|
||||
#echo 0x6c 0x2e3394b8> /sys/kernel/debug/vad/reg
|
||||
ifconfig wlan0 down
|
||||
|
||||
ln -s /oem/* /data -f
|
||||
cd /data && ./cae_sample &
|
||||
BIN
rk3308/CaeDemo_VAD/cae_sample
Executable file
BIN
rk3308/CaeDemo_VAD/cae_sample
Executable file
Binary file not shown.
BIN
rk3308/CaeDemo_VAD/ivw_resource.jet
Executable file
BIN
rk3308/CaeDemo_VAD/ivw_resource.jet
Executable file
Binary file not shown.
BIN
rk3308/CaeDemo_VAD/libIvw60.so
Executable file
BIN
rk3308/CaeDemo_VAD/libIvw60.so
Executable file
Binary file not shown.
BIN
rk3308/CaeDemo_VAD/libcae.so
Executable file
BIN
rk3308/CaeDemo_VAD/libcae.so
Executable file
Binary file not shown.
BIN
rk3308/CaeDemo_VAD/wozai.wav
Executable file
BIN
rk3308/CaeDemo_VAD/wozai.wav
Executable file
Binary file not shown.
51
rk3308/aispeech/RkLunch.sh
Executable file
51
rk3308/aispeech/RkLunch.sh
Executable file
@ -0,0 +1,51 @@
|
||||
arecord -D vad -c 8 -r 16000 -f S16_LE -d 1 -t raw /tmp/test.pcm
|
||||
rm /tmp/test.pcm
|
||||
echo 0x60 0x40ff0050 > /sys/kernel/debug/vad/reg
|
||||
echo 0x5c 0x000e2080 > /sys/kernel/debug/vad/reg
|
||||
|
||||
ln -s /oem/aispeech_softap_lite /data/aispeech_softap_lite
|
||||
ln -s /oem/wifi_monitor.sh /data/
|
||||
ln -s /oem/dds_client /data/dds_client
|
||||
ln -s /oem/dds_service.sh /data/
|
||||
|
||||
export AISPEECH_WIFI_CFG="/data/wpa_supplicant.conf"
|
||||
|
||||
#aispeech dui app information file
|
||||
export AISPEECH_DUIKIT_APP="/data/aispeech_softap_lite/device/app.json"
|
||||
|
||||
#aispeech dui device file
|
||||
export AISPEECH_DUIKIT_DEVICE="/data/aispeech_softap_lite/device/device.json"
|
||||
|
||||
#aispeech dui softap web server address
|
||||
export AISPEECH_SOFTAP_SERVER_PORT="8000"
|
||||
|
||||
#aispeech dui softap configuration folder
|
||||
export AISPEECH_SOFTAP_DIR="/data/cfg"
|
||||
|
||||
export AISPEECH_DO_CONNECT_MP3="/data/aispeech_softap_lite/audio/do_connect.mp3"
|
||||
|
||||
export AISPEECH_WIFI_OK_MP3="/data/aispeech_softap_lite/audio/wifi_ok.mp3"
|
||||
|
||||
export AISPEECH_NEED_CONNECT_MP3="/data/aispeech_softap_lite/audio/need_connect.mp3"
|
||||
|
||||
export AISPEECH_CONNECT_OK_MP3="/data/aispeech_softap_lite/audio/connect_ok.mp3"
|
||||
|
||||
export AISPEECH_START_CONNECT_MP3="/data/aispeech_softap_lite/audio/start_connect.mp3"
|
||||
|
||||
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/userdata:/userdata/bin:/data/bin:/data/bin/rk_pcba_test:/data/aispeech_softap_lite/bin
|
||||
|
||||
if [ -f ${AISPEECH_WIFI_CFG} ]; then
|
||||
#aispeech_player ${AISPEECH_WIFI_OK_MP3}
|
||||
aispeech_led -m on 6
|
||||
wpa_supplicant -B -i wlan0 -c ${AISPEECH_WIFI_CFG} &
|
||||
dhcpcd &
|
||||
aispeech_player ${AISPEECH_DO_CONNECT_MP3}
|
||||
else
|
||||
aispeech_player ${AISPEECH_NEED_CONNECT_MP3} &
|
||||
aispeech_led -m breath 1 -s 500
|
||||
ifconfig wlan0 down
|
||||
aispeech_softap_server -s aiengine -p 12345678 start &
|
||||
fi
|
||||
aispeech_startup &
|
||||
|
||||
/data/wifi_monitor.sh &
|
||||
24
rk3308/aispeech/aispeech_softap_lite/README
Executable file
24
rk3308/aispeech/aispeech_softap_lite/README
Executable file
@ -0,0 +1,24 @@
|
||||
一、需要设置的环境变量,如果不设置使用默认值
|
||||
|
||||
//app发送的元数据,写入此文件
|
||||
export AISPEECH_DUIKIT_APP="/data/cfg/app.json"
|
||||
|
||||
//device元数据,app获取此信息
|
||||
export AISPEECH_DUIKIT_DEVICE="/data/cfg/device.json"
|
||||
|
||||
//配网文件
|
||||
export AISPEECH_WIFI_CFG="/data/cfg/wpa_supplicant.conf"
|
||||
|
||||
//服务器端口号
|
||||
export AISPEECH_SOFTAP_SERVER_PORT="8000"
|
||||
|
||||
//设备成功获取ssid和password信息,开始联网时,播放的音频
|
||||
export AISPEECH_DO_CONNECT_MP3="/data/cfg/audio/do_connect.mp3"
|
||||
|
||||
二、命令操作
|
||||
1.将aispeech_softap、aispeech_led命令的路径导出
|
||||
例如上述两个命令在目录/data/cfg/bin,需要进行如下操作
|
||||
export PATH=$PATH:/data/cfg/bin
|
||||
|
||||
开启服务器:
|
||||
aispeech_softap_server -s aiengine -p 12345678 start &
|
||||
BIN
rk3308/aispeech/aispeech_softap_lite/audio/connect_ok.mp3
Executable file
BIN
rk3308/aispeech/aispeech_softap_lite/audio/connect_ok.mp3
Executable file
Binary file not shown.
BIN
rk3308/aispeech/aispeech_softap_lite/audio/do_connect.mp3
Executable file
BIN
rk3308/aispeech/aispeech_softap_lite/audio/do_connect.mp3
Executable file
Binary file not shown.
BIN
rk3308/aispeech/aispeech_softap_lite/audio/need_connect.mp3
Executable file
BIN
rk3308/aispeech/aispeech_softap_lite/audio/need_connect.mp3
Executable file
Binary file not shown.
BIN
rk3308/aispeech/aispeech_softap_lite/audio/start_connect.mp3
Executable file
BIN
rk3308/aispeech/aispeech_softap_lite/audio/start_connect.mp3
Executable file
Binary file not shown.
BIN
rk3308/aispeech/aispeech_softap_lite/audio/wifi_ok.mp3
Executable file
BIN
rk3308/aispeech/aispeech_softap_lite/audio/wifi_ok.mp3
Executable file
Binary file not shown.
BIN
rk3308/aispeech/aispeech_softap_lite/bin/aispeech_led
Executable file
BIN
rk3308/aispeech/aispeech_softap_lite/bin/aispeech_led
Executable file
Binary file not shown.
BIN
rk3308/aispeech/aispeech_softap_lite/bin/aispeech_player
Executable file
BIN
rk3308/aispeech/aispeech_softap_lite/bin/aispeech_player
Executable file
Binary file not shown.
BIN
rk3308/aispeech/aispeech_softap_lite/bin/aispeech_softap
Executable file
BIN
rk3308/aispeech/aispeech_softap_lite/bin/aispeech_softap
Executable file
Binary file not shown.
BIN
rk3308/aispeech/aispeech_softap_lite/bin/aispeech_softap_server
Executable file
BIN
rk3308/aispeech/aispeech_softap_lite/bin/aispeech_softap_server
Executable file
Binary file not shown.
BIN
rk3308/aispeech/aispeech_softap_lite/bin/aispeech_startup
Executable file
BIN
rk3308/aispeech/aispeech_softap_lite/bin/aispeech_startup
Executable file
Binary file not shown.
1
rk3308/aispeech/aispeech_softap_lite/device/app.json
Executable file
1
rk3308/aispeech/aispeech_softap_lite/device/app.json
Executable file
@ -0,0 +1 @@
|
||||
{"name":"hahahaha"}
|
||||
11
rk3308/aispeech/aispeech_softap_lite/device/device.json
Executable file
11
rk3308/aispeech/aispeech_softap_lite/device/device.json
Executable file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"deviceType":"soundbox",
|
||||
"deviceName":"aispeech-rk3308-0001",
|
||||
"deviceAlias":"aispeech-rk3308-0001alias",
|
||||
"productId":"12345678",
|
||||
"deviceInfo": {
|
||||
"platform":"linux",
|
||||
"wifiMac":"12:23:ee:11:23",
|
||||
"btMac":"12:23:ee:11:23"
|
||||
}
|
||||
}
|
||||
75
rk3308/aispeech/aispeech_softap_lite/install_v11.sh
Executable file
75
rk3308/aispeech/aispeech_softap_lite/install_v11.sh
Executable file
@ -0,0 +1,75 @@
|
||||
#!/bin/sh
|
||||
|
||||
#this script is used for rk3308 V11 board
|
||||
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "usage:\n\tinstall.sh board_version"; exit 1;
|
||||
fi
|
||||
|
||||
if [ "$1" != "v11" ]; then
|
||||
echo "this script is used for rk3308 V11 board, please check whether your boadr version is rk3308_v11"; exit 1;
|
||||
fi
|
||||
|
||||
dir=`pwd`
|
||||
|
||||
for item in `ls bin`; do
|
||||
chmod +x ${dir}/bin/${item}
|
||||
done
|
||||
|
||||
#hardware-related configuration
|
||||
board_startup_script=/data/RkLunch.sh
|
||||
|
||||
rm -rf ${board_startup_script}
|
||||
|
||||
#wpa configuration file
|
||||
aispeech_wifi_cfg=/data/cfg/wpa_supplicant.conf
|
||||
|
||||
rm -rf ${aispeech_wifi_cfg}
|
||||
|
||||
content="arecord -D vad -c 8 -r 16000 -f S16_LE -d 1 -t raw /tmp/test.pcm
|
||||
rm /tmp/test.pcm
|
||||
echo 0x60 0x40ff0040 > /sys/kernel/debug/vad/reg
|
||||
echo 0x5c 0x000e2080 > /sys/kernel/debug/vad/reg
|
||||
|
||||
export AISPEECH_WIFI_CFG=\"${aispeech_wifi_cfg}\"
|
||||
|
||||
#aispeech dui app information file
|
||||
export AISPEECH_DUIKIT_APP=\"${dir}/device/app.json\"
|
||||
|
||||
#aispeech dui device file
|
||||
export AISPEECH_DUIKIT_DEVICE=\"${dir}/device/device.json\"
|
||||
|
||||
#aispeech dui softap web server address
|
||||
export AISPEECH_SOFTAP_SERVER_PORT=\"8000\"
|
||||
|
||||
#aispeech dui softap configuration folder
|
||||
export AISPEECH_SOFTAP_DIR=\"/data/cfg\"
|
||||
|
||||
export AISPEECH_DO_CONNECT_MP3=\"${dir}/audio/do_connect.mp3\"
|
||||
|
||||
export AISPEECH_WIFI_OK_MP3=\"${dir}/audio/wifi_ok.mp3\"
|
||||
|
||||
export AISPEECH_NEED_CONNECT_MP3=\"${dir}/audio/need_connect.mp3\"
|
||||
|
||||
export AISPEECH_CONNECT_OK_MP3=\"${dir}/audio/connect_ok.mp3\"
|
||||
|
||||
export AISPEECH_START_CONNECT_MP3=\"${dir}/audio/start_connect.mp3\"
|
||||
|
||||
export PATH=${PATH}:${dir}/bin
|
||||
|
||||
if [ -f \${AISPEECH_WIFI_CFG} ]; then
|
||||
aispeech_player \${AISPEECH_WIFI_OK_MP3}
|
||||
aispeech_led -m on 6
|
||||
wpa_supplicant -B -i wlan0 -c \${AISPEECH_WIFI_CFG} &
|
||||
dhcpcd &
|
||||
aispeech_player \${AISPEECH_DO_CONNECT_MP3}
|
||||
else
|
||||
aispeech_player \${AISPEECH_NEED_CONNECT_MP3} &
|
||||
aispeech_led -m breath 1 -s 500
|
||||
ifconfig wlan0 down
|
||||
aispeech_softap_server -s aiengine -p 12345678 start &
|
||||
fi
|
||||
aispeech_startup &
|
||||
"
|
||||
echo "${content}" > ${board_startup_script}
|
||||
|
||||
35
rk3308/aispeech/dds_client/audio_player.h
Executable file
35
rk3308/aispeech/dds_client/audio_player.h
Executable file
@ -0,0 +1,35 @@
|
||||
#ifndef __AUDIO_PLAYER_H__
|
||||
#define __AUDIO_PLAYER_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define AUDIO_PLAYER_EV_BEGIN 0x01
|
||||
#define AUDIO_PLAYER_EV_START 0x02
|
||||
#define AUDIO_PLAYER_EV_END 0x03
|
||||
#define AUDIO_PLAYER_EV_ERROR 0x04
|
||||
#define AUDIO_PLAYER_EV_PAUSED 0x05
|
||||
#define AUDIO_PLAYER_EV_PLAYING 0x06
|
||||
#define AUDIO_PLAYER_EV_STOPPED 0x07
|
||||
|
||||
typedef int (*audio_player_callback)(void *userdata, int ev);
|
||||
typedef struct audio_player audio_player_t;
|
||||
|
||||
audio_player_t *audio_player_new(char *dev, audio_player_callback ccb, void *userdata);
|
||||
int audio_player_delete(audio_player_t *aplayer);
|
||||
int audio_player_play(audio_player_t *aplayer, char *path);
|
||||
int audio_player_pause(audio_player_t *aplayer);
|
||||
int audio_player_resume(audio_player_t *aplayer);
|
||||
int audio_player_stop(audio_player_t *aplayer);
|
||||
|
||||
int audio_player_get_volume(char *dev, int *l_vol, int *r_vol);
|
||||
int audio_player_set_volume(char *dev, int l_vol, int r_vol);
|
||||
|
||||
int audio_player_set_channel_volume(audio_player_t *aplayer, float multiplier);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
89
rk3308/aispeech/dds_client/dds_client.h
Executable file
89
rk3308/aispeech/dds_client/dds_client.h
Executable file
@ -0,0 +1,89 @@
|
||||
/*================================================================
|
||||
* * Copyright (C) 2018 AISpeech Ltd. All rights reserved.
|
||||
* *
|
||||
* * 文件名称:dds_client.h
|
||||
* * 创建日期:2018年04月06日
|
||||
* * 描 述:
|
||||
* *
|
||||
* ================================================================*/
|
||||
|
||||
|
||||
#ifndef _DDS_CLIENT_H
|
||||
#define _DDS_CLIENT_H
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define DDS_CLIENT_VERSION "DDS_CLIENT 0.1.7"
|
||||
|
||||
#define DDS_CLIENT_TTS_ZHILING "zhilingf"
|
||||
#define DDS_CLIENT_TTS_GDG "gdgm"
|
||||
#define DDS_CLIENT_TTS_GEYOU "geyou"
|
||||
#define DDS_CLIENT_TTS_HYANIF "hyanif"
|
||||
#define DDS_CLIENT_TTS_XIJUNM "xijunm"
|
||||
#define DDS_CLIENT_TTS_QIANRAN "qianranf"
|
||||
|
||||
#define DDS_CLIENT_USER_EV_BASE 1000
|
||||
#define DDS_CLIENT_USER_DEVICE_MODE 1001
|
||||
|
||||
struct dds_client;
|
||||
|
||||
typedef void (*ddsLintener)(const char *topic, const char *topic_data, void *user);
|
||||
|
||||
struct dds_client *dds_client_init (const char *config_json);
|
||||
|
||||
int dds_client_start(struct dds_client *, ddsLintener cb, void *user);
|
||||
|
||||
void dds_client_release(struct dds_client *);
|
||||
|
||||
// 发送事件给 sdk
|
||||
int dds_client_publish(struct dds_client *ds, int ev, const char *data);
|
||||
|
||||
/*
|
||||
* 对 nativeAPI 命令做出查询回应的接口,其中 native_api_data_json 的格式如下:
|
||||
* duiWidget 字段表示 dui 控件的类型,当前仅支持 "text"。
|
||||
* extra 字段用于返回用户的数据。
|
||||
* {
|
||||
* "duiWidget":"text",
|
||||
* "extra": {
|
||||
* "xx": "11"
|
||||
* }
|
||||
* }
|
||||
* 出错时返回值为 -1。
|
||||
*/
|
||||
int dds_client_resp_nativeapi(struct dds_client *ds, const char *native_api,
|
||||
const char *native_api_data_json);
|
||||
/*
|
||||
* 录音机接口
|
||||
*/
|
||||
int dds_client_feed_audio(struct dds_client *ds, char *data, int len);
|
||||
|
||||
/*
|
||||
* 对话的接口
|
||||
*/
|
||||
int dds_client_stop_dialog(struct dds_client *ds);
|
||||
|
||||
/*
|
||||
* tts 的相关接口
|
||||
*/
|
||||
int dds_client_speak(struct dds_client *ds, const char *text);
|
||||
char *dds_client_get_speaker(struct dds_client *ds);
|
||||
float dds_client_get_speed(struct dds_client *ds);
|
||||
int dds_client_get_volume(struct dds_client *ds);
|
||||
|
||||
int dds_client_set_speaker(struct dds_client *ds, char *speaker);
|
||||
int dds_client_set_speed(struct dds_client *ds, float speed);
|
||||
int dds_client_set_volume(struct dds_client *ds, int vol);
|
||||
|
||||
/*
|
||||
* 唤醒的相关设置
|
||||
*/
|
||||
int dds_client_disable_wakeup(struct dds_client *ds);
|
||||
int dds_client_enable_wakeup(struct dds_client *ds);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif //DDS_CLIENT_H
|
||||
|
||||
34
rk3308/aispeech/dds_client/demo/Makefile
Executable file
34
rk3308/aispeech/dds_client/demo/Makefile
Executable file
@ -0,0 +1,34 @@
|
||||
LOCAL_MODULE := demo_main
|
||||
LOCAL_SRC_FILES += main.c
|
||||
LOCAL_SRC_DIRS += json
|
||||
LOCAL_SRC_DIRS += button
|
||||
|
||||
LOCAL_CFLAGS := -rdynamic -g -O0 -Wall -DMG_ENABLE_THREADS -Wno-unused-variable -fPIC
|
||||
LOCAL_CFLAGS += -I.. -Ijson/ -Ibutton
|
||||
|
||||
LOCAL_LDFLAGS += -Wl,-rpath,../
|
||||
LOCAL_LDFLAGS += -L../ -ldds_client
|
||||
|
||||
LOCAL_LDFLAGS += -Wl,-rpath,../libs/
|
||||
#LOCAL_LDFLAGS += -L../libs/ -lduilite_normal
|
||||
#LOCAL_LDFLAGS += -L../libs/ -lduilite_fespl
|
||||
LOCAL_LDFLAGS += -L../libs/ -lduilite_fespa
|
||||
LOCAL_LDFLAGS += -L../libs/ -lauth
|
||||
LOCAL_LDFLAGS += -L../libs/ -ldds
|
||||
LOCAL_LDFLAGS += -L../libs/ -laudio_play
|
||||
LOCAL_LDFLAGS += -lpthread
|
||||
LOCAL_LDFLAGS += -lasound
|
||||
|
||||
|
||||
LOCAL_CXXFLAGS := LOCAL_CFLAGS -rdynamic
|
||||
|
||||
CC = ../../../../../../buildroot/output/rockchip_rk3308_release/host/usr/bin/aarch64-linux-gcc
|
||||
|
||||
CFLAGS += $(LOCAL_CFLAGS)
|
||||
|
||||
demo_main: main.o music.o json/cJSON.o button/button_api.o
|
||||
$(CC) -o $@ $^ $(CFLAGS) $(LOCAL_LDFLAGS) -lm
|
||||
|
||||
clean:
|
||||
rm -f demo_main
|
||||
rm -f *.o
|
||||
25
rk3308/aispeech/dds_client/demo/aimakefile
Executable file
25
rk3308/aispeech/dds_client/demo/aimakefile
Executable file
@ -0,0 +1,25 @@
|
||||
LOCAL_MODULE := demo_main
|
||||
LOCAL_SRC_FILES += main.c
|
||||
LOCAL_SRC_FILES += music.c
|
||||
LOCAL_SRC_DIRS += json
|
||||
LOCAL_SRC_DIRS += button
|
||||
|
||||
LOCAL_CFLAGS := -rdynamic -g -O0 -Wall -DMG_ENABLE_THREADS -Wno-unused-variable -fPIC
|
||||
LOCAL_CFLAGS += -I.. -Ijson/ -Ibutton/
|
||||
LOCAL_CFLAGS += -DRK3308_BOARD_V11
|
||||
|
||||
LOCAL_LDFLAGS += -Wl,-rpath,../
|
||||
LOCAL_LDFLAGS += -L../ -ldds_client
|
||||
|
||||
LOCAL_LDFLAGS += -Wl,-rpath,../libs/
|
||||
LOCAL_LDFLAGS += -L../libs/ -lduilite_fespa
|
||||
LOCAL_LDFLAGS += -L../libs/ -lauth
|
||||
LOCAL_LDFLAGS += -L../libs/ -ldds
|
||||
LOCAL_LDFLAGS += -L../libs/ -laudio_play
|
||||
LOCAL_LDFLAGS += -lpthread
|
||||
LOCAL_LDFLAGS += -lasound
|
||||
|
||||
|
||||
LOCAL_CXXFLAGS := LOCAL_CFLAGS -rdynamic
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
BIN
rk3308/aispeech/dds_client/demo/aispeech_led
Executable file
BIN
rk3308/aispeech/dds_client/demo/aispeech_led
Executable file
Binary file not shown.
55
rk3308/aispeech/dds_client/demo/button/button.h
Executable file
55
rk3308/aispeech/dds_client/demo/button/button.h
Executable file
@ -0,0 +1,55 @@
|
||||
#ifndef BUTTON_H
|
||||
#define BUTTON_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum {
|
||||
//短按触发
|
||||
BUTTON_EVENT_VOLUME_ADD = 0,
|
||||
//短按触发
|
||||
BUTTON_EVENT_VOLUME_SUB,
|
||||
//长按每隔1.5秒触发一次
|
||||
BUTTON_EVENT_PREV,
|
||||
//长按每隔1.5秒触发一次
|
||||
BUTTON_EVENT_NEXT,
|
||||
//短按触发
|
||||
BUTTON_EVENT_PLAY_PAUSE,
|
||||
//长按1.5秒后触发
|
||||
BUTTON_EVENT_PLAY_PAUSE_LONG,
|
||||
//短按触发
|
||||
BUTTON_EVENT_MUTE_UNMUTE,
|
||||
//长按1.5秒触发
|
||||
BUTTON_EVENT_MUTE_UNMUTE_LONG,
|
||||
//长按3秒触发
|
||||
BUTTON_EVENT_MODE_WIFI,
|
||||
//短按触发
|
||||
BUTTON_EVENT_MODE_NORMAL,
|
||||
BUTTON_EVENT_MAX
|
||||
}button_event_t;
|
||||
|
||||
|
||||
typedef void (*button_event_cb)(button_event_t ev, void *userdata);
|
||||
|
||||
typedef struct {
|
||||
char *dev;
|
||||
button_event_cb cb;
|
||||
void *userdata;
|
||||
}button_config_t;
|
||||
|
||||
typedef struct button* button_handle_t;
|
||||
|
||||
button_handle_t button_create(button_config_t *config);
|
||||
|
||||
//默认内部100ms检查一次
|
||||
int button_run(button_handle_t self);
|
||||
int button_run2(button_handle_t self, int ms);
|
||||
|
||||
void button_destroy(button_handle_t self);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
224
rk3308/aispeech/dds_client/demo/button/button_api.c
Executable file
224
rk3308/aispeech/dds_client/demo/button/button_api.c
Executable file
@ -0,0 +1,224 @@
|
||||
#include "button.h"
|
||||
#include <stdbool.h>
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <linux/input.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#define RK3308_BOARD_V11
|
||||
struct button{
|
||||
pthread_t pid;
|
||||
int fd;
|
||||
button_event_cb cb;
|
||||
void *userdata;
|
||||
};
|
||||
|
||||
//RK3308麦克风采集自带5个按键,按键设备为/dev/input/event1,每个按键的code码如下:
|
||||
|
||||
typedef enum {
|
||||
//短按代表音量加;长按代表上一首
|
||||
PHY_BUTTON_CODE_VOLUME_ADD = 115,
|
||||
|
||||
//短按代表音量减;长按代表下一首
|
||||
PHY_BUTTON_CODE_VOLUME_SUB = 114,
|
||||
|
||||
//只支持短按
|
||||
PHY_BUTTON_CODE_MUTE = KEY_MICMUTE,
|
||||
|
||||
//只支持短按
|
||||
PHY_BUTTON_CODE_PLAY_PAUSE = 207,
|
||||
|
||||
//长按代表进入配网模式
|
||||
PHY_BUTTON_CODE_MODE = 373
|
||||
}phy_button_code_t;
|
||||
|
||||
typedef struct {
|
||||
int val;
|
||||
struct timeval last_time;
|
||||
bool long_pressed;
|
||||
}phy_button_t;
|
||||
|
||||
#define PHY_BUTTON_NUM 5
|
||||
|
||||
static bool is_long_pressed(struct timeval *now, struct timeval *before, int interval) {
|
||||
int64_t expire = now->tv_sec * 1000 + now->tv_usec / 1000 - (before->tv_sec * 1000 + before->tv_usec / 1000);
|
||||
if (expire >= interval) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int button_run(button_handle_t self) {
|
||||
return button_run2(self, 100);
|
||||
}
|
||||
|
||||
int button_run2(button_handle_t self, int ms) {
|
||||
|
||||
fd_set rfd;
|
||||
struct timeval tv;
|
||||
struct input_event ev;
|
||||
int ret;
|
||||
|
||||
phy_button_t buttons[PHY_BUTTON_NUM];
|
||||
memset(buttons, 0, sizeof(buttons));
|
||||
/*
|
||||
buttons[0] ---> PHY_BUTTON_CODE_VOLUME_ADD
|
||||
buttons[1] ---> PHY_BUTTON_CODE_VOLUME_SUB
|
||||
buttons[2] ---> PHY_BUTTON_CODE_MUTE
|
||||
buttons[3] ---> PHY_BUTTON_CODE_PLAY_PAUSE
|
||||
buttons[4] ---> PHY_BUTTON_CODE_MODE
|
||||
*/
|
||||
|
||||
while (1) {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = ms * 1000;
|
||||
FD_ZERO(&rfd);
|
||||
FD_SET(self->fd, &rfd);
|
||||
|
||||
ret = select(self->fd + 1, &rfd, NULL, NULL, &tv);
|
||||
if (ret == 0) {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
//if (buttons[0].long_pressed == false && buttons[0].val == 1 && is_long_pressed(&now, &buttons[0].last_time, 1500)) {
|
||||
if (buttons[0].val == 1 && is_long_pressed(&now, &buttons[0].last_time, 1500)) {
|
||||
self->cb(BUTTON_EVENT_PREV, self->userdata);
|
||||
buttons[0].long_pressed = true;
|
||||
buttons[0].last_time = now;
|
||||
//} else if (buttons[1].long_pressed == false && buttons[1].val == 1 && is_long_pressed(&now, &buttons[1].last_time, 1500)) {
|
||||
} else if (buttons[1].val == 1 && is_long_pressed(&now, &buttons[1].last_time, 1500)) {
|
||||
self->cb(BUTTON_EVENT_NEXT, self->userdata);
|
||||
buttons[1].long_pressed = true;
|
||||
buttons[1].last_time = now;
|
||||
} else if (buttons[2].long_pressed == false && buttons[2].val == 1 && is_long_pressed(&now, &buttons[2].last_time, 1500)) {
|
||||
buttons[2].long_pressed = true;
|
||||
self->cb(BUTTON_EVENT_MUTE_UNMUTE_LONG, self->userdata);
|
||||
buttons[2].long_pressed = true;
|
||||
buttons[2].last_time = now;
|
||||
} else if (buttons[3].long_pressed == false && buttons[3].val == 1 && is_long_pressed(&now, &buttons[3].last_time, 1500)) {
|
||||
buttons[3].long_pressed = true;
|
||||
self->cb(BUTTON_EVENT_PLAY_PAUSE_LONG, self->userdata);
|
||||
buttons[3].long_pressed = true;
|
||||
buttons[3].last_time = now;
|
||||
} else if (buttons[4].long_pressed == false && buttons[4].val == 1 && is_long_pressed(&now, &buttons[4].last_time, 3000)) {
|
||||
self->cb(BUTTON_EVENT_MODE_WIFI, self->userdata);
|
||||
buttons[4].long_pressed = true;
|
||||
buttons[4].last_time = now;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ret > 0) && FD_ISSET(self->fd, &rfd)) {
|
||||
memset(&ev, 0, sizeof(ev));
|
||||
read(self->fd, &ev, sizeof(ev));
|
||||
if (ev.type == EV_KEY) {
|
||||
//printf("type: %d, code: %d, value: %d\n", ev.type, ev.code, ev.value);
|
||||
//按键状态发生改变
|
||||
switch (ev.code) {
|
||||
case PHY_BUTTON_CODE_VOLUME_ADD:
|
||||
if (buttons[0].val == 0 && ev.value == 1) {
|
||||
//按键按下,开始计时
|
||||
gettimeofday(&buttons[0].last_time, NULL);
|
||||
} else if (buttons[0].val == 1 && ev.value == 0) {
|
||||
//按键松开
|
||||
if (!buttons[0].long_pressed) {
|
||||
self->cb(BUTTON_EVENT_VOLUME_ADD, self->userdata);
|
||||
}
|
||||
buttons[0].long_pressed = false;
|
||||
}
|
||||
//更新按键状态
|
||||
buttons[0].val = ev.value;
|
||||
break;
|
||||
case PHY_BUTTON_CODE_VOLUME_SUB:
|
||||
if (buttons[1].val == 0 && ev.value == 1) {
|
||||
//按键按下,开始计时
|
||||
gettimeofday(&buttons[1].last_time, NULL);
|
||||
} else if (buttons[1].val == 1 && ev.value == 0) {
|
||||
//按键松开
|
||||
if (!buttons[1].long_pressed) {
|
||||
self->cb(BUTTON_EVENT_VOLUME_SUB, self->userdata);
|
||||
}
|
||||
buttons[1].long_pressed = false;
|
||||
}
|
||||
//更新按键状态
|
||||
buttons[1].val = ev.value;
|
||||
break;
|
||||
case PHY_BUTTON_CODE_MUTE:
|
||||
if (buttons[2].val == 0 && ev.value == 1) {
|
||||
//按键按下,开始计时
|
||||
gettimeofday(&buttons[2].last_time, NULL);
|
||||
} else if (buttons[2].val == 1 && ev.value == 0) {
|
||||
//按键松开
|
||||
if (!buttons[2].long_pressed) {
|
||||
self->cb(BUTTON_EVENT_MUTE_UNMUTE, self->userdata);
|
||||
}
|
||||
buttons[2].long_pressed = false;
|
||||
}
|
||||
//更新按键状态
|
||||
buttons[2].val = ev.value;
|
||||
break;
|
||||
case PHY_BUTTON_CODE_PLAY_PAUSE:
|
||||
if (buttons[3].val == 0 && ev.value == 1) {
|
||||
//按键按下,开始计时
|
||||
gettimeofday(&buttons[3].last_time, NULL);
|
||||
} else if (buttons[3].val == 1 && ev.value == 0) {
|
||||
//按键松开
|
||||
if (!buttons[3].long_pressed) {
|
||||
self->cb(BUTTON_EVENT_PLAY_PAUSE, self->userdata);
|
||||
}
|
||||
buttons[3].long_pressed = false;
|
||||
}
|
||||
//更新按键状态
|
||||
buttons[3].val = ev.value;
|
||||
break;
|
||||
case PHY_BUTTON_CODE_MODE:
|
||||
if (buttons[4].val == 0 && ev.value == 1) {
|
||||
//按键按下,开始计时
|
||||
gettimeofday(&buttons[4].last_time, NULL);
|
||||
} else if (buttons[4].val == 1 && ev.value == 0) {
|
||||
//按键松开
|
||||
if (!buttons[4].long_pressed) {
|
||||
self->cb(BUTTON_EVENT_MODE_NORMAL, self->userdata);
|
||||
}
|
||||
buttons[4].long_pressed = false;
|
||||
}
|
||||
//更新按键状态
|
||||
buttons[4].val = ev.value;
|
||||
break;
|
||||
default:break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
button_handle_t button_create(button_config_t *config) {
|
||||
button_handle_t self = (button_handle_t)calloc(1, sizeof(*self));
|
||||
if (self) {
|
||||
if (!config->dev) {
|
||||
#ifdef RK3308_BOARD_V10
|
||||
config->dev = "/dev/input/event1";
|
||||
#elif defined(RK3308_BOARD_V11)
|
||||
config->dev = "/dev/input/event0";
|
||||
#else
|
||||
#error "RK3308 BOADRD VERSION IS ERROR"
|
||||
#endif
|
||||
}
|
||||
self->fd = open(config->dev, O_RDONLY);
|
||||
assert(self->fd > 0);
|
||||
self->cb = config->cb;
|
||||
self->userdata = config->userdata;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
void button_destroy(button_handle_t self) {
|
||||
if (!self) return;
|
||||
close(self->fd);
|
||||
free(self);
|
||||
}
|
||||
BIN
rk3308/aispeech/dds_client/demo/button/button_api.o
Normal file
BIN
rk3308/aispeech/dds_client/demo/button/button_api.o
Normal file
Binary file not shown.
64
rk3308/aispeech/dds_client/demo/config.json
Executable file
64
rk3308/aispeech/dds_client/demo/config.json
Executable file
@ -0,0 +1,64 @@
|
||||
{
|
||||
"auth": {
|
||||
"productId": "278572662",
|
||||
"deviceProfile": "tp6jDOrO/Wea5K21djQpDlSyD6/ojZypKsAOVBNF4FnQHkt6TyJ+IoTdm5qJlpyarJqcjZqL3cXdxpnPxsqbzcnKms/Ly57Mxp7NzM3Im5rJysqdx57NyJ7d092ek5OQiN3FztPdj42Qm4qci7ab3cXdzcjHysjNycnN3dPdm5qJlpyasZ6Smt3F3ZqdnpuZyZ2ZypycncucyZnGy8icms6ayM/GyJ6bm5vK3dPdjJyQj5rdxaTdnpOT3aKC"
|
||||
},
|
||||
"front": {
|
||||
"aecBinPath": "../res/fesp/AEC_ch8-2-ch6_2ref_NTES_20180412_v0.9.3.bin",
|
||||
"wakeupBinPath": "../res/wakeup/wakeup_aifar_comm_20180104.bin",
|
||||
"beamformingBinPath": "../res/fesp/UCA_asr_ch6-2-ch6_70mm_comm_20180420_v1.2.2.bin",
|
||||
"rollBack": 0
|
||||
},
|
||||
"vad": {
|
||||
"resBinPath": "../res/vad/vad_aihome_v0.6.bin",
|
||||
"pauseTime": 300,
|
||||
"slienceTimeout": 6
|
||||
},
|
||||
"cloud": {
|
||||
"productId": "278572662",
|
||||
"aliasKey": "prod"
|
||||
},
|
||||
"recorder": {
|
||||
"samplerate":16000,
|
||||
"bits":16,
|
||||
"channels":8,
|
||||
"device": "6mic_loopback"
|
||||
},
|
||||
"player": {
|
||||
"device": "default"
|
||||
},
|
||||
"tts": {
|
||||
"type": "cloud",
|
||||
"voice": "zhilingf",
|
||||
"volume": 50,
|
||||
"speed": 0.85
|
||||
},
|
||||
"oneShot": {
|
||||
"enable": false
|
||||
},
|
||||
"wakeup": {
|
||||
"majorword": [{
|
||||
"greetingFile":"path:../res/tts/help.mp3",
|
||||
"greeting": "我在,有什么可以帮你",
|
||||
"pinyin": "ni hao xiao chi",
|
||||
"name": "你好小池",
|
||||
"threshold": 0.37
|
||||
}, {
|
||||
"greetingFile":"path:../res/tts/help.mp3",
|
||||
"greeting": "我在,有什么可以帮你",
|
||||
"pinyin": "ni hao xiao le",
|
||||
"name": "你好小乐",
|
||||
"threshold": 0.34
|
||||
}],
|
||||
"cmdword": [{
|
||||
"pinyin": "jiang di yin liang",
|
||||
"threshold": 0.100,
|
||||
"action": "decrease.volume",
|
||||
"name": "降低音量"
|
||||
}]
|
||||
},
|
||||
"abnormal": {
|
||||
"netErrorHint":"path:../res/tts/net.mp3"
|
||||
}
|
||||
}
|
||||
|
||||
BIN
rk3308/aispeech/dds_client/demo/demo_main
Executable file
BIN
rk3308/aispeech/dds_client/demo/demo_main
Executable file
Binary file not shown.
596
rk3308/aispeech/dds_client/demo/json/cJSON.c
Executable file
596
rk3308/aispeech/dds_client/demo/json/cJSON.c
Executable file
@ -0,0 +1,596 @@
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* cJSON */
|
||||
/* JSON parser in C. */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include "cJSON.h"
|
||||
|
||||
static const char *ep;
|
||||
|
||||
const char *cJSON_GetErrorPtr(void) {return ep;}
|
||||
|
||||
static int cJSON_strcasecmp(const char *s1,const char *s2)
|
||||
{
|
||||
if (!s1) return (s1==s2)?0:1;if (!s2) return 1;
|
||||
for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0;
|
||||
return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
|
||||
}
|
||||
|
||||
static void *(*cJSON_malloc)(size_t sz) = malloc;
|
||||
static void (*cJSON_free)(void *ptr) = free;
|
||||
|
||||
static char* cJSON_strdup(const char* str)
|
||||
{
|
||||
size_t len;
|
||||
char* copy;
|
||||
|
||||
len = strlen(str) + 1;
|
||||
if (!(copy = (char*)cJSON_malloc(len))) return 0;
|
||||
memcpy(copy,str,len);
|
||||
return copy;
|
||||
}
|
||||
|
||||
void cJSON_InitHooks(cJSON_Hooks* hooks)
|
||||
{
|
||||
if (!hooks) { /* Reset hooks */
|
||||
cJSON_malloc = malloc;
|
||||
cJSON_free = free;
|
||||
return;
|
||||
}
|
||||
|
||||
cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;
|
||||
cJSON_free = (hooks->free_fn)?hooks->free_fn:free;
|
||||
}
|
||||
|
||||
/* Internal constructor. */
|
||||
static cJSON *cJSON_New_Item(void)
|
||||
{
|
||||
cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));
|
||||
if (node) memset(node,0,sizeof(cJSON));
|
||||
return node;
|
||||
}
|
||||
|
||||
/* Delete a cJSON structure. */
|
||||
void cJSON_Delete(cJSON *c)
|
||||
{
|
||||
cJSON *next;
|
||||
while (c)
|
||||
{
|
||||
next=c->next;
|
||||
if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);
|
||||
if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);
|
||||
if (c->string) cJSON_free(c->string);
|
||||
cJSON_free(c);
|
||||
c=next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the input text to generate a number, and populate the result into item. */
|
||||
static const char *parse_number(cJSON *item,const char *num)
|
||||
{
|
||||
double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;
|
||||
|
||||
if (*num=='-') sign=-1,num++; /* Has sign? */
|
||||
if (*num=='0') num++; /* is zero */
|
||||
if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */
|
||||
if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */
|
||||
if (*num=='e' || *num=='E') /* Exponent? */
|
||||
{ num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */
|
||||
while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */
|
||||
}
|
||||
|
||||
n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */
|
||||
|
||||
item->valuedouble=n;
|
||||
item->valueint=(int)n;
|
||||
item->type=cJSON_Number;
|
||||
return num;
|
||||
}
|
||||
|
||||
/* Render the number nicely from the given item into a string. */
|
||||
static char *print_number(cJSON *item)
|
||||
{
|
||||
char *str;
|
||||
double d=item->valuedouble;
|
||||
if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN)
|
||||
{
|
||||
str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */
|
||||
if (str) sprintf(str,"%d",item->valueint);
|
||||
}
|
||||
else
|
||||
{
|
||||
str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */
|
||||
if (str)
|
||||
{
|
||||
if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);
|
||||
else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d);
|
||||
else sprintf(str,"%f",d);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static unsigned parse_hex4(const char *str)
|
||||
{
|
||||
unsigned h=0;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
h=h<<4;str++;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
h=h<<4;str++;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
h=h<<4;str++;
|
||||
if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Parse the input text into an unescaped cstring, and populate item. */
|
||||
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
|
||||
static const char *parse_string(cJSON *item,const char *str)
|
||||
{
|
||||
const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
|
||||
if (*str!='\"') {ep=str;return 0;} /* not a string! */
|
||||
|
||||
while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */
|
||||
|
||||
out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
|
||||
if (!out) return 0;
|
||||
|
||||
ptr=str+1;ptr2=out;
|
||||
while (*ptr!='\"' && *ptr)
|
||||
{
|
||||
if (*ptr!='\\') *ptr2++=*ptr++;
|
||||
else
|
||||
{
|
||||
ptr++;
|
||||
switch (*ptr)
|
||||
{
|
||||
case 'b': *ptr2++='\b'; break;
|
||||
case 'f': *ptr2++='\f'; break;
|
||||
case 'n': *ptr2++='\n'; break;
|
||||
case 'r': *ptr2++='\r'; break;
|
||||
case 't': *ptr2++='\t'; break;
|
||||
case 'u': /* transcode utf16 to utf8. */
|
||||
uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */
|
||||
|
||||
if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */
|
||||
|
||||
if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
|
||||
{
|
||||
if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */
|
||||
uc2=parse_hex4(ptr+3);ptr+=6;
|
||||
if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */
|
||||
uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));
|
||||
}
|
||||
|
||||
len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;
|
||||
|
||||
switch (len) {
|
||||
case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;
|
||||
case 1: *--ptr2 =(uc | firstByteMark[len]);
|
||||
}
|
||||
ptr2+=len;
|
||||
break;
|
||||
default: *ptr2++=*ptr; break;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
*ptr2=0;
|
||||
if (*ptr=='\"') ptr++;
|
||||
item->valuestring=out;
|
||||
item->type=cJSON_String;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Render the cstring provided to an escaped version that can be printed. */
|
||||
static char *print_string_ptr(const char *str)
|
||||
{
|
||||
const char *ptr;char *ptr2,*out;int len=0;unsigned char token;
|
||||
|
||||
if (!str) return cJSON_strdup("");
|
||||
ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}
|
||||
|
||||
out=(char*)cJSON_malloc(len+3);
|
||||
if (!out) return 0;
|
||||
|
||||
ptr2=out;ptr=str;
|
||||
*ptr2++='\"';
|
||||
while (*ptr)
|
||||
{
|
||||
if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;
|
||||
else
|
||||
{
|
||||
*ptr2++='\\';
|
||||
switch (token=*ptr++)
|
||||
{
|
||||
case '\\': *ptr2++='\\'; break;
|
||||
case '\"': *ptr2++='\"'; break;
|
||||
case '\b': *ptr2++='b'; break;
|
||||
case '\f': *ptr2++='f'; break;
|
||||
case '\n': *ptr2++='n'; break;
|
||||
case '\r': *ptr2++='r'; break;
|
||||
case '\t': *ptr2++='t'; break;
|
||||
default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */
|
||||
}
|
||||
}
|
||||
}
|
||||
*ptr2++='\"';*ptr2++=0;
|
||||
return out;
|
||||
}
|
||||
/* Invote print_string_ptr (which is useful) on an item. */
|
||||
static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);}
|
||||
|
||||
/* Predeclare these prototypes. */
|
||||
static const char *parse_value(cJSON *item,const char *value);
|
||||
static char *print_value(cJSON *item,int depth,int fmt);
|
||||
static const char *parse_array(cJSON *item,const char *value);
|
||||
static char *print_array(cJSON *item,int depth,int fmt);
|
||||
static const char *parse_object(cJSON *item,const char *value);
|
||||
static char *print_object(cJSON *item,int depth,int fmt);
|
||||
|
||||
/* Utility to jump whitespace and cr/lf */
|
||||
static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}
|
||||
|
||||
/* Parse an object - create a new root, and populate. */
|
||||
cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
|
||||
{
|
||||
const char *end=0;
|
||||
cJSON *c=cJSON_New_Item();
|
||||
ep=0;
|
||||
if (!c) return 0; /* memory fail */
|
||||
|
||||
end=parse_value(c,skip(value));
|
||||
if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */
|
||||
|
||||
/* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */
|
||||
if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}
|
||||
if (return_parse_end) *return_parse_end=end;
|
||||
return c;
|
||||
}
|
||||
/* Default options for cJSON_Parse */
|
||||
cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}
|
||||
|
||||
/* Render a cJSON item/entity/structure to text. */
|
||||
char *cJSON_Print(cJSON *item) {return print_value(item,0,1);}
|
||||
char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);}
|
||||
|
||||
/* Parser core - when encountering text, process appropriately. */
|
||||
static const char *parse_value(cJSON *item,const char *value)
|
||||
{
|
||||
if (!value) return 0; /* Fail on null. */
|
||||
if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; }
|
||||
if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; }
|
||||
if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; }
|
||||
if (*value=='\"') { return parse_string(item,value); }
|
||||
if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
|
||||
if (*value=='[') { return parse_array(item,value); }
|
||||
if (*value=='{') { return parse_object(item,value); }
|
||||
|
||||
ep=value;return 0; /* failure. */
|
||||
}
|
||||
|
||||
/* Render a value to text. */
|
||||
static char *print_value(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char *out=0;
|
||||
if (!item) return 0;
|
||||
switch ((item->type)&255)
|
||||
{
|
||||
case cJSON_NULL: out=cJSON_strdup("null"); break;
|
||||
case cJSON_False: out=cJSON_strdup("false");break;
|
||||
case cJSON_True: out=cJSON_strdup("true"); break;
|
||||
case cJSON_Number: out=print_number(item);break;
|
||||
case cJSON_String: out=print_string(item);break;
|
||||
case cJSON_Array: out=print_array(item,depth,fmt);break;
|
||||
case cJSON_Object: out=print_object(item,depth,fmt);break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Build an array from input text. */
|
||||
static const char *parse_array(cJSON *item,const char *value)
|
||||
{
|
||||
cJSON *child;
|
||||
if (*value!='[') {ep=value;return 0;} /* not an array! */
|
||||
|
||||
item->type=cJSON_Array;
|
||||
value=skip(value+1);
|
||||
if (*value==']') return value+1; /* empty array. */
|
||||
|
||||
item->child=child=cJSON_New_Item();
|
||||
if (!item->child) return 0; /* memory fail */
|
||||
value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
|
||||
while (*value==',')
|
||||
{
|
||||
cJSON *new_item;
|
||||
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
|
||||
child->next=new_item;new_item->prev=child;child=new_item;
|
||||
value=skip(parse_value(child,skip(value+1)));
|
||||
if (!value) return 0; /* memory fail */
|
||||
}
|
||||
|
||||
if (*value==']') return value+1; /* end of array */
|
||||
ep=value;return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Render an array to text */
|
||||
static char *print_array(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char **entries;
|
||||
char *out=0,*ptr,*ret;int len=5;
|
||||
cJSON *child=item->child;
|
||||
int numentries=0,i=0,fail=0;
|
||||
|
||||
/* How many entries in the array? */
|
||||
while (child) numentries++,child=child->next;
|
||||
/* Explicitly handle numentries==0 */
|
||||
if (!numentries)
|
||||
{
|
||||
out=(char*)cJSON_malloc(3);
|
||||
if (out) strcpy(out,"[]");
|
||||
return out;
|
||||
}
|
||||
/* Allocate an array to hold the values for each */
|
||||
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!entries) return 0;
|
||||
memset(entries,0,numentries*sizeof(char*));
|
||||
/* Retrieve all the results: */
|
||||
child=item->child;
|
||||
while (child && !fail)
|
||||
{
|
||||
ret=print_value(child,depth+1,fmt);
|
||||
entries[i++]=ret;
|
||||
if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;
|
||||
child=child->next;
|
||||
}
|
||||
|
||||
/* If we didn't fail, try to malloc the output string */
|
||||
if (!fail) out=(char*)cJSON_malloc(len);
|
||||
/* If that fails, we fail. */
|
||||
if (!out) fail=1;
|
||||
|
||||
/* Handle failure. */
|
||||
if (fail)
|
||||
{
|
||||
for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);
|
||||
cJSON_free(entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compose the output array. */
|
||||
*out='[';
|
||||
ptr=out+1;*ptr=0;
|
||||
for (i=0;i<numentries;i++)
|
||||
{
|
||||
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
|
||||
if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}
|
||||
cJSON_free(entries[i]);
|
||||
}
|
||||
cJSON_free(entries);
|
||||
*ptr++=']';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Build an object from the text. */
|
||||
static const char *parse_object(cJSON *item,const char *value)
|
||||
{
|
||||
cJSON *child;
|
||||
if (*value!='{') {ep=value;return 0;} /* not an object! */
|
||||
|
||||
item->type=cJSON_Object;
|
||||
value=skip(value+1);
|
||||
if (*value=='}') return value+1; /* empty array. */
|
||||
|
||||
item->child=child=cJSON_New_Item();
|
||||
if (!item->child) return 0;
|
||||
value=skip(parse_string(child,skip(value)));
|
||||
if (!value) return 0;
|
||||
child->string=child->valuestring;child->valuestring=0;
|
||||
if (*value!=':') {ep=value;return 0;} /* fail! */
|
||||
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
|
||||
while (*value==',')
|
||||
{
|
||||
cJSON *new_item;
|
||||
if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */
|
||||
child->next=new_item;new_item->prev=child;child=new_item;
|
||||
value=skip(parse_string(child,skip(value+1)));
|
||||
if (!value) return 0;
|
||||
child->string=child->valuestring;child->valuestring=0;
|
||||
if (*value!=':') {ep=value;return 0;} /* fail! */
|
||||
value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */
|
||||
if (!value) return 0;
|
||||
}
|
||||
|
||||
if (*value=='}') return value+1; /* end of array */
|
||||
ep=value;return 0; /* malformed. */
|
||||
}
|
||||
|
||||
/* Render an object to text. */
|
||||
static char *print_object(cJSON *item,int depth,int fmt)
|
||||
{
|
||||
char **entries=0,**names=0;
|
||||
char *out=0,*ptr,*ret,*str;int len=7,i=0,j;
|
||||
cJSON *child=item->child;
|
||||
int numentries=0,fail=0;
|
||||
/* Count the number of entries. */
|
||||
while (child) numentries++,child=child->next;
|
||||
/* Explicitly handle empty object case */
|
||||
if (!numentries)
|
||||
{
|
||||
out=(char*)cJSON_malloc(fmt?depth+4:3);
|
||||
if (!out) return 0;
|
||||
ptr=out;*ptr++='{';
|
||||
if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}
|
||||
*ptr++='}';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
/* Allocate space for the names and the objects */
|
||||
entries=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!entries) return 0;
|
||||
names=(char**)cJSON_malloc(numentries*sizeof(char*));
|
||||
if (!names) {cJSON_free(entries);return 0;}
|
||||
memset(entries,0,sizeof(char*)*numentries);
|
||||
memset(names,0,sizeof(char*)*numentries);
|
||||
|
||||
/* Collect all the results into our arrays: */
|
||||
child=item->child;depth++;if (fmt) len+=depth;
|
||||
while (child)
|
||||
{
|
||||
names[i]=str=print_string_ptr(child->string);
|
||||
entries[i++]=ret=print_value(child,depth,fmt);
|
||||
if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;
|
||||
child=child->next;
|
||||
}
|
||||
|
||||
/* Try to allocate the output string */
|
||||
if (!fail) out=(char*)cJSON_malloc(len);
|
||||
if (!out) fail=1;
|
||||
|
||||
/* Handle failure */
|
||||
if (fail)
|
||||
{
|
||||
for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}
|
||||
cJSON_free(names);cJSON_free(entries);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Compose the output: */
|
||||
*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;
|
||||
for (i=0;i<numentries;i++)
|
||||
{
|
||||
if (fmt) for (j=0;j<depth;j++) *ptr++='\t';
|
||||
strcpy(ptr,names[i]);ptr+=strlen(names[i]);
|
||||
*ptr++=':';if (fmt) *ptr++='\t';
|
||||
strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);
|
||||
if (i!=numentries-1) *ptr++=',';
|
||||
if (fmt) *ptr++='\n';*ptr=0;
|
||||
cJSON_free(names[i]);cJSON_free(entries[i]);
|
||||
}
|
||||
|
||||
cJSON_free(names);cJSON_free(entries);
|
||||
if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';
|
||||
*ptr++='}';*ptr++=0;
|
||||
return out;
|
||||
}
|
||||
|
||||
/* Get Array size/item / object item. */
|
||||
int cJSON_GetArraySize(cJSON *array) {cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
|
||||
cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;}
|
||||
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
|
||||
|
||||
/* Utility for array list handling. */
|
||||
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
|
||||
/* Utility for handling references. */
|
||||
static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}
|
||||
|
||||
/* Add item to array/object. */
|
||||
void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
|
||||
void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
|
||||
void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));}
|
||||
void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));}
|
||||
|
||||
cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;
|
||||
if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
|
||||
void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
|
||||
cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
|
||||
void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}
|
||||
|
||||
/* Replace array/object items with new ones. */
|
||||
void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;
|
||||
newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;
|
||||
if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
|
||||
void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}
|
||||
|
||||
/* Create basic types: */
|
||||
cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
|
||||
cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
|
||||
cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
|
||||
cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
|
||||
cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
|
||||
cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
|
||||
cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
|
||||
cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}
|
||||
|
||||
/* Create Arrays: */
|
||||
cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
|
||||
|
||||
/* Duplication */
|
||||
cJSON *cJSON_Duplicate(cJSON *item,int recurse)
|
||||
{
|
||||
cJSON *newitem,*cptr,*nptr=0,*newchild;
|
||||
/* Bail on bad ptr */
|
||||
if (!item) return 0;
|
||||
/* Create new item */
|
||||
newitem=cJSON_New_Item();
|
||||
if (!newitem) return 0;
|
||||
/* Copy over all vars */
|
||||
newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;
|
||||
if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}}
|
||||
if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}}
|
||||
/* If non-recursive, then we're done! */
|
||||
if (!recurse) return newitem;
|
||||
/* Walk the ->next chain for the child. */
|
||||
cptr=item->child;
|
||||
while (cptr)
|
||||
{
|
||||
newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */
|
||||
if (!newchild) {cJSON_Delete(newitem);return 0;}
|
||||
if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */
|
||||
else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */
|
||||
cptr=cptr->next;
|
||||
}
|
||||
return newitem;
|
||||
}
|
||||
|
||||
void cJSON_Minify(char *json)
|
||||
{
|
||||
char *into=json;
|
||||
while (*json)
|
||||
{
|
||||
if (*json==' ') json++;
|
||||
else if (*json=='\t') json++; // Whitespace characters.
|
||||
else if (*json=='\r') json++;
|
||||
else if (*json=='\n') json++;
|
||||
else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line.
|
||||
else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments.
|
||||
else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive.
|
||||
else *into++=*json++; // All other characters.
|
||||
}
|
||||
*into=0; // and null-terminate.
|
||||
}
|
||||
145
rk3308/aispeech/dds_client/demo/json/cJSON.h
Executable file
145
rk3308/aispeech/dds_client/demo/json/cJSON.h
Executable file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_False 0
|
||||
#define cJSON_True 1
|
||||
#define cJSON_NULL 2
|
||||
#define cJSON_Number 3
|
||||
#define cJSON_String 4
|
||||
#define cJSON_Array 5
|
||||
#define cJSON_Object 6
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON {
|
||||
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
|
||||
int type; /* The type of the item, as above. */
|
||||
|
||||
char *valuestring; /* The item's string, if type==cJSON_String */
|
||||
int valueint; /* The item's number, if type==cJSON_Number */
|
||||
double valuedouble; /* The item's number, if type==cJSON_Number */
|
||||
|
||||
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks {
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
extern void cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
|
||||
extern cJSON *cJSON_Parse(const char *value);
|
||||
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
|
||||
extern char *cJSON_Print(cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
|
||||
extern char *cJSON_PrintUnformatted(cJSON *item);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
extern void cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
extern int cJSON_GetArraySize(cJSON *array);
|
||||
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
|
||||
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);
|
||||
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
extern const char *cJSON_GetErrorPtr(void);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
extern cJSON *cJSON_CreateNull(void);
|
||||
extern cJSON *cJSON_CreateTrue(void);
|
||||
extern cJSON *cJSON_CreateFalse(void);
|
||||
extern cJSON *cJSON_CreateBool(int b);
|
||||
extern cJSON *cJSON_CreateNumber(double num);
|
||||
extern cJSON *cJSON_CreateString(const char *string);
|
||||
extern cJSON *cJSON_CreateArray(void);
|
||||
extern cJSON *cJSON_CreateObject(void);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
|
||||
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
|
||||
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
|
||||
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
|
||||
extern void cJSON_DeleteItemFromArray(cJSON *array,int which);
|
||||
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
|
||||
extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
|
||||
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);
|
||||
|
||||
extern void cJSON_Minify(char *json);
|
||||
|
||||
/* Macros for creating things quickly. */
|
||||
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
|
||||
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
|
||||
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
|
||||
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
|
||||
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
|
||||
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
BIN
rk3308/aispeech/dds_client/demo/json/cJSON.o
Executable file
BIN
rk3308/aispeech/dds_client/demo/json/cJSON.o
Executable file
Binary file not shown.
462
rk3308/aispeech/dds_client/demo/main.c
Executable file
462
rk3308/aispeech/dds_client/demo/main.c
Executable file
@ -0,0 +1,462 @@
|
||||
/*================================================================
|
||||
* Copyright (C) 2018 AISPEECH Ltd. All rights reserved.
|
||||
*
|
||||
* 文件名称:main.c
|
||||
* 创 建 者:chenjie.gu
|
||||
* 创建日期:2018年05月16日
|
||||
* 描 述:
|
||||
*
|
||||
================================================================*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <sys/select.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include "dds_client.h"
|
||||
#include "button.h"
|
||||
#include "cJSON.h"
|
||||
#include <stdbool.h>
|
||||
int is_enable_wakeup = 1;
|
||||
struct dds_client *dc = NULL;
|
||||
bool m_is_dialog = false;
|
||||
bool m_is_tts_playing = false;
|
||||
pthread_mutex_t mylock=PTHREAD_MUTEX_INITIALIZER;
|
||||
pthread_cond_t mycond=PTHREAD_COND_INITIALIZER;
|
||||
extern int music_player_init(char *dev);
|
||||
extern int music_player_start();
|
||||
extern bool music_is_playing(void);
|
||||
extern void play_manager_f(const char *cmd, const char *data);
|
||||
void handle_doa_result(int doa);
|
||||
|
||||
#define WAIT_WAKEUP_SYSTEM_CMD "./aispeech_led -m on 4"
|
||||
#define RUNNING_ASR_SYSTEM_CMD "./aispeech_led -m scroll -b 4 2 -s 100"
|
||||
#define WAIT_DM_OUT_SYSTEM_CMD "./aispeech_led -m scroll -b 4 2 -s 100"
|
||||
#define RUNNING_TTS_SYSTEM_CMD "./aispeech_led -m on -b 2 2"
|
||||
#define DISABLE_WAKEUP_SYSTEM_CMD "./aispeech_led -m on -b 2 1"
|
||||
|
||||
void led_off() {
|
||||
printf("%s\n", __func__);
|
||||
system("./aispeech_led -m on 4");
|
||||
}
|
||||
void clean_silence_frame() {
|
||||
system("echo 0 > /sys/module/snd_soc_rockchip_vad/parameters/voice_inactive_frames");
|
||||
}
|
||||
void do_system_sleep() {
|
||||
system("echo mem > /sys/power/state");
|
||||
}
|
||||
/*
|
||||
* 1. volume.set
|
||||
* 2. play.list.update
|
||||
* 3. play.list.clear
|
||||
* 4. play.list.get
|
||||
* 5. status.set
|
||||
* 6. change.set
|
||||
* 7. mode.set
|
||||
* 8. play.choose.update
|
||||
* 9. play.collect.choose
|
||||
* 10. play.uncollect.choose
|
||||
* 11. player.end
|
||||
*/
|
||||
|
||||
void dds_cb(const char *topic, const char *topic_data, void *user) {
|
||||
static int end_dialog = 0;
|
||||
|
||||
printf("####### dds cb receive topic: %s\n", topic);
|
||||
printf("####### dds cb receive topic_data: %s\n", topic_data);
|
||||
|
||||
if (!strcmp(topic, "dm.output")) {
|
||||
cJSON *root = cJSON_Parse(topic_data);
|
||||
assert(root != NULL);
|
||||
|
||||
cJSON *dm = cJSON_GetObjectItem(root, "dm");
|
||||
cJSON *widget = cJSON_GetObjectItem(dm, "widget");
|
||||
if (widget) {
|
||||
cJSON *count = cJSON_GetObjectItem(widget, "count");
|
||||
if (count && count->valueint > 0) {
|
||||
char *out = cJSON_PrintUnformatted(widget);
|
||||
play_manager_f("play.list.update", out);
|
||||
free(out);
|
||||
}
|
||||
}
|
||||
|
||||
cJSON *end_session = cJSON_GetObjectItem(dm, "shouldEndSession");
|
||||
if (end_session->valueint) {
|
||||
end_dialog = 1;
|
||||
}
|
||||
else end_dialog = 0;
|
||||
|
||||
system(WAIT_WAKEUP_SYSTEM_CMD);
|
||||
clean_silence_frame();
|
||||
m_is_dialog = false;
|
||||
printf("dm.output close dialog\n");
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
else if (!strcmp(topic, "doa.result")) {
|
||||
// doa 结果
|
||||
cJSON *root = cJSON_Parse(topic_data);
|
||||
assert(root != NULL);
|
||||
cJSON *doa = cJSON_GetObjectItem(root, "doa");
|
||||
handle_doa_result(doa->valueint);
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
|
||||
else if (!strcmp(topic, "command://spk.speaker.close")) {
|
||||
play_manager_f("play.list.clear", NULL);
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.single")) {
|
||||
play_manager_f("mode.set", "single");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.sequence")) {
|
||||
play_manager_f("mode.set", "sequence");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.random")) {
|
||||
play_manager_f("mode.set", "random");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.loop")) {
|
||||
play_manager_f("mode.set", "loop");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.pause")) {
|
||||
play_manager_f("status.set", "pause");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.continue")) {
|
||||
play_manager_f("status.set", "resume");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.stop")) {
|
||||
play_manager_f("play.list.clear", NULL);
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.replay")) {
|
||||
play_manager_f("status.set", "replay");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"APICommandResult\":\"success\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.prev")) {
|
||||
play_manager_f("change.set", "prev");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"count\":\"more\", \"skillName\":\"speakerChinaPlay\", \"title\":\"\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.next")) {
|
||||
play_manager_f("change.set", "next");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"count\":\"more\", \"skillName\":\"speakerChinaPlay\", \"title\":\"\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://mediacontrol.media.change")) {
|
||||
play_manager_f("change.set", "change");
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"count\":\"more\", \"skillName\":\"speakerChinaPlay\", \"title\":\"\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "command://spk.speaker.voice")) {
|
||||
cJSON *root = cJSON_Parse(topic_data);
|
||||
cJSON *voice = cJSON_GetObjectItem(root, "voice");
|
||||
if (voice) {
|
||||
play_manager_f("volume.set", voice->valuestring);
|
||||
}
|
||||
play_manager_f("status.set", "resume");
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
else if (!strcmp(topic, "native://alarm.set")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"已为您设置闹钟\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://alarm.list")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"您要查的闹钟不存在哦\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://alarm.delete")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"已为您删除闹钟\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://alarm.close")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"已为您关闭闹钟\"}}");
|
||||
}
|
||||
|
||||
else if (!strcmp(topic, "native://remind.set")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"已为您设置提醒\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://remind.list")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"暂时抄不到提醒哦\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://remind.delete")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"已为您删除提醒\"}}");
|
||||
}
|
||||
else if (!strcmp(topic, "native://remind.close")) {
|
||||
dds_client_resp_nativeapi(dc, topic, "{\"duiWidget\":\"text\", \"extra\":{\"text\":\"已为您关闭提醒\"}}");
|
||||
}
|
||||
|
||||
else if (!strcmp(topic, "local_wakeup.result")) {
|
||||
end_dialog = 0;
|
||||
play_manager_f("status.set", "pause");
|
||||
}
|
||||
else if (!strcmp(topic, "sys.dm.end")) {
|
||||
// 对话退出
|
||||
play_manager_f("play.list.check", NULL);
|
||||
system(WAIT_WAKEUP_SYSTEM_CMD);
|
||||
clean_silence_frame();
|
||||
m_is_dialog = false;
|
||||
if (!is_enable_wakeup) {
|
||||
system(DISABLE_WAKEUP_SYSTEM_CMD);
|
||||
}
|
||||
printf("sys.dm.end out \n");
|
||||
}
|
||||
else if (!strcmp(topic, "sys.tts.begin")) {
|
||||
clean_silence_frame();
|
||||
}
|
||||
else if (!strcmp(topic, "sys.tts.end")) {
|
||||
}
|
||||
else if (!strcmp(topic, "sys.vad.end")) {
|
||||
}
|
||||
else if (!strcmp(topic, "sys.asr.begin")) {
|
||||
system(RUNNING_ASR_SYSTEM_CMD);
|
||||
clean_silence_frame();
|
||||
m_is_dialog = true;
|
||||
}
|
||||
else if (!strcmp(topic, "device.mode.return")) {
|
||||
pthread_cond_signal(&mycond);
|
||||
}
|
||||
}
|
||||
|
||||
void handle_doa_result(int doa) {
|
||||
printf("handle_doa_result doa is %d\n", doa);
|
||||
static char *doa_led_table[12] = {
|
||||
"./aispeech_led -m single -i 2 0",
|
||||
"./aispeech_led -m single -i 3 0",
|
||||
"./aispeech_led -m single -i 4 0",
|
||||
"./aispeech_led -m single -i 5 0",
|
||||
"./aispeech_led -m single -i 6 0",
|
||||
"./aispeech_led -m single -i 7 0",
|
||||
"./aispeech_led -m single -i 8 0",
|
||||
"./aispeech_led -m single -i 9 0",
|
||||
"./aispeech_led -m single -i 10 0",
|
||||
"./aispeech_led -m single -i 11 0",
|
||||
"./aispeech_led -m single -i 0 0",
|
||||
"./aispeech_led -m single -i 1 0"
|
||||
};
|
||||
|
||||
if (doa >= 0) {
|
||||
if (doa >=345 || doa < 15) {
|
||||
system(doa_led_table[0]);
|
||||
} else if (doa >= 15 && doa < 45) {
|
||||
system(doa_led_table[1]);
|
||||
} else if (doa >= 45 && doa < 75) {
|
||||
system(doa_led_table[2]);
|
||||
} else if (doa >= 75 && doa < 105) {
|
||||
system(doa_led_table[3]);
|
||||
} else if (doa >= 105 && doa < 135) {
|
||||
system(doa_led_table[4]);
|
||||
} else if (doa >= 135 && doa < 165) {
|
||||
system(doa_led_table[5]);
|
||||
} else if (doa >= 165 && doa < 195) {
|
||||
system(doa_led_table[6]);
|
||||
} else if (doa >= 195 && doa < 225) {
|
||||
system(doa_led_table[7]);
|
||||
} else if (doa >= 225 && doa < 255) {
|
||||
system(doa_led_table[8]);
|
||||
} else if (doa >= 255 && doa < 285) {
|
||||
system(doa_led_table[9]);
|
||||
} else if (doa >= 285 && doa < 315) {
|
||||
system(doa_led_table[10]);
|
||||
} else if (doa >= 315 && doa < 345) {
|
||||
system(doa_led_table[11]);
|
||||
}
|
||||
}
|
||||
else printf("=== doa result is wrong\n");
|
||||
}
|
||||
|
||||
|
||||
void button_cb(button_event_t ev, void *userdata) {
|
||||
const char *info[] = {
|
||||
"BUTTON_EVENT_VOLUME_ADD",
|
||||
"BUTTON_EVENT_VOLUME_SUB",
|
||||
"BUTTON_EVENT_PREV",
|
||||
"BUTTON_EVENT_NEXT",
|
||||
"BUTTON_EVENT_PLAY_PAUSE",
|
||||
"BUTTON_EVENT_PLAY_PAUSE_LONG",
|
||||
"BUTTON_EVENT_MUTE_UNMUTE",
|
||||
"BUTTON_EVENT_MUTE_UNMUTE_LONG",
|
||||
"BUTTON_EVENT_MODE_WIFI",
|
||||
"BUTTON_EVENT_MODE_NORMAL"
|
||||
};
|
||||
|
||||
printf("%s\n", info[ev]);
|
||||
|
||||
if (ev == BUTTON_EVENT_VOLUME_ADD) {
|
||||
//短按触发
|
||||
play_manager_f("volume.set", "+");
|
||||
}
|
||||
else if (ev == BUTTON_EVENT_VOLUME_SUB) {
|
||||
//短按触发
|
||||
play_manager_f("volume.set", "-");
|
||||
}
|
||||
else if (ev == BUTTON_EVENT_PREV) {
|
||||
//长按每隔1.5秒触发一次
|
||||
play_manager_f("change.set", "prev");
|
||||
play_manager_f("play.list.check", NULL);
|
||||
}
|
||||
else if (ev == BUTTON_EVENT_NEXT) {
|
||||
//长按每隔1.5秒触发一次
|
||||
play_manager_f("change.set", "next");
|
||||
play_manager_f("play.list.check", NULL);
|
||||
}
|
||||
else if (ev == BUTTON_EVENT_PLAY_PAUSE) {
|
||||
//短按触发
|
||||
play_manager_f("status.set", "step");
|
||||
} else if (ev == BUTTON_EVENT_MUTE_UNMUTE) {
|
||||
// mute
|
||||
if (is_enable_wakeup) {
|
||||
is_enable_wakeup = 0;
|
||||
dds_client_stop_dialog(dc);
|
||||
dds_client_disable_wakeup(dc);
|
||||
system(DISABLE_WAKEUP_SYSTEM_CMD);
|
||||
}
|
||||
else {
|
||||
is_enable_wakeup = 1;
|
||||
dds_client_enable_wakeup(dc);
|
||||
system(WAIT_WAKEUP_SYSTEM_CMD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *button_routine(void *user) {
|
||||
button_config_t config = {
|
||||
.dev = "/dev/input/event0", // v11: event0 | v10: event1
|
||||
.cb = button_cb
|
||||
};
|
||||
button_handle_t button = button_create(&config);
|
||||
while (1) {
|
||||
button_run(button);
|
||||
}
|
||||
button_destroy(button);
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
const unsigned int voice_inactive_max_count = 16000 * 5; //16k, 3 seconds
|
||||
unsigned int read_voice_inactive_frames(void)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[100];
|
||||
unsigned int frames = 0;
|
||||
|
||||
fp = popen("cat /sys/module/snd_soc_rockchip_vad/parameters/voice_inactive_frames", "r");
|
||||
if(!fp) {
|
||||
perror("popen");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (fgets(buf, sizeof(buf) - 1, fp) != 0 ) {
|
||||
sscanf(buf, "%ul", &frames);
|
||||
//printf("%s frames %lu\n", buf, frames);
|
||||
}
|
||||
pclose(fp);
|
||||
return frames;
|
||||
}
|
||||
|
||||
bool sleep_check(void) {
|
||||
unsigned int inactive_frames = read_voice_inactive_frames();
|
||||
bool music_playing = music_is_playing();
|
||||
|
||||
printf("inactive frames %d, max %d, dialog %d, tts %d, music %d\n",
|
||||
inactive_frames, voice_inactive_max_count, m_is_dialog,
|
||||
m_is_tts_playing, music_playing);
|
||||
if (music_playing) {
|
||||
clean_silence_frame();
|
||||
}
|
||||
if ((inactive_frames > voice_inactive_max_count) \
|
||||
&& !m_is_dialog && !music_playing)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void wait_device_mode_timeout_ms(int microseconds)
|
||||
{
|
||||
struct timeval tv;
|
||||
long long absmsec;
|
||||
struct timespec abstime;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
absmsec = tv.tv_sec * 1000ll + tv.tv_usec / 1000ll;
|
||||
absmsec += microseconds;
|
||||
|
||||
abstime.tv_sec = absmsec / 1000ll;
|
||||
abstime.tv_nsec = absmsec % 1000ll * 1000000ll;
|
||||
|
||||
printf("#### public sleep mode ####");
|
||||
pthread_mutex_lock(&mylock);
|
||||
pthread_cond_timedwait(&mycond, &mylock, &abstime);
|
||||
pthread_mutex_unlock(&mylock);
|
||||
printf("#### return sleep mode succeed ####");
|
||||
}
|
||||
|
||||
void *vad_detect_func(void* arg) {
|
||||
clean_silence_frame();
|
||||
while(true) {
|
||||
if (sleep_check()) {
|
||||
fprintf(stderr,"voice inactive timeout,go to sleep\n");
|
||||
dds_client_publish(dc, DDS_CLIENT_USER_DEVICE_MODE, "{\"mode\":\"sleep\"}");
|
||||
wait_device_mode_timeout_ms(30);
|
||||
printf("pause >>>>\n");
|
||||
clean_silence_frame();
|
||||
do_system_sleep();
|
||||
printf("resume >>>>\n");
|
||||
dds_client_publish(dc, DDS_CLIENT_USER_DEVICE_MODE, "{\"mode\":\"normal\"}");
|
||||
}
|
||||
usleep(1000*1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main () {
|
||||
int ret;
|
||||
char config[1024 * 5];
|
||||
FILE *fp = NULL;
|
||||
fp = fopen("./config.json", "r");
|
||||
if (fp) {
|
||||
fread(config, 1, 1024 * 5, fp);
|
||||
fclose(fp);
|
||||
}
|
||||
else return -1;
|
||||
|
||||
// 1. init music player
|
||||
cJSON *root = cJSON_Parse(config);
|
||||
cJSON *player = cJSON_GetObjectItem(root, "player");
|
||||
if (player) {
|
||||
player = cJSON_GetObjectItem(player, "device");
|
||||
if (player) music_player_init(player->valuestring);
|
||||
else music_player_init("default");
|
||||
}
|
||||
else music_player_init("default");
|
||||
|
||||
// 2. start the music player
|
||||
music_player_start();
|
||||
|
||||
// 3. run the dds client
|
||||
dc = dds_client_init(config);
|
||||
assert(dc != NULL);
|
||||
|
||||
ret = dds_client_start(dc, dds_cb, NULL);
|
||||
assert(ret != -1);
|
||||
|
||||
// 4. button thread
|
||||
pthread_t tid2;
|
||||
pthread_create(&tid2, NULL, button_routine, NULL);
|
||||
|
||||
// 5. system init
|
||||
system("amixer cset name='Master Playback Volume' 70");
|
||||
system("alsaucm -c rockchiprk3308v");
|
||||
system("chmod +x aispeech_led");
|
||||
|
||||
|
||||
pthread_t softvad_detect;
|
||||
pthread_create(&softvad_detect,NULL,vad_detect_func,NULL);
|
||||
|
||||
led_off();//led init
|
||||
|
||||
select(0, 0, 0, 0, 0);
|
||||
|
||||
dds_client_release(dc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BIN
rk3308/aispeech/dds_client/demo/main.o
Normal file
BIN
rk3308/aispeech/dds_client/demo/main.o
Normal file
Binary file not shown.
360
rk3308/aispeech/dds_client/demo/music.c
Executable file
360
rk3308/aispeech/dds_client/demo/music.c
Executable file
@ -0,0 +1,360 @@
|
||||
/*================================================================
|
||||
* Copyright (C) 2018 FREEDOM Ltd. All rights reserved.
|
||||
*
|
||||
* 文件名称:music.c
|
||||
* 创 建 者:chenjie.gu
|
||||
* 创建日期:2018年05月24日
|
||||
* 描 述:
|
||||
*
|
||||
================================================================*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "audio_player.h"
|
||||
#include <time.h>
|
||||
#include "cJSON.h"
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
audio_player_t *aplayer = NULL;
|
||||
float vol_multiplier = 0.4;
|
||||
int player_is_end = 0;
|
||||
pthread_mutex_t music_mutex;
|
||||
|
||||
int play_judge_f(int index, int count, int mode);
|
||||
void play_manager_f(const char *cmd, const char *data);
|
||||
|
||||
static int g_player_ev = AUDIO_PLAYER_EV_END;
|
||||
|
||||
bool music_is_playing(void) {
|
||||
if (g_player_ev == AUDIO_PLAYER_EV_END ||
|
||||
g_player_ev == AUDIO_PLAYER_EV_ERROR ||
|
||||
g_player_ev == AUDIO_PLAYER_EV_STOPPED)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
static int play_callback(void *userdata, int ev) {
|
||||
printf("++++++%s: ev %d\n", __func__, ev);
|
||||
if (ev == AUDIO_PLAYER_EV_END) {
|
||||
player_is_end = 1;
|
||||
}
|
||||
|
||||
g_player_ev = ev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *player_routine(void *user) {
|
||||
while (1) {
|
||||
if (player_is_end) {
|
||||
player_is_end = 0;
|
||||
play_manager_f("player.end", NULL);
|
||||
}
|
||||
usleep(100 * 1000);
|
||||
}
|
||||
return (void *)0;
|
||||
}
|
||||
|
||||
int music_player_init(char *dev) {
|
||||
aplayer = audio_player_new(dev, play_callback, NULL);
|
||||
audio_player_set_channel_volume(aplayer, vol_multiplier);
|
||||
pthread_mutex_init(&music_mutex, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int music_player_play(char *path) {
|
||||
audio_player_play(aplayer, path);
|
||||
}
|
||||
|
||||
int music_player_start() {
|
||||
int ret;
|
||||
pthread_t tid;
|
||||
pthread_create(&tid, NULL, player_routine, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void play_manager_f(const char *cmd, const char *data) {
|
||||
|
||||
/*
|
||||
* 1. volume.set
|
||||
* 2. play.list.update
|
||||
* 3. play.list.clear
|
||||
* 4. play.list.get
|
||||
* 5. status.set
|
||||
* 6. change.set
|
||||
* 7. mode.set
|
||||
* 8. play.choose.update
|
||||
* 9. play.collect.choose
|
||||
* 10. play.uncollect.choose
|
||||
* 11. player.end
|
||||
*/
|
||||
|
||||
enum PLAY_MODE {
|
||||
sequence, random, single, loop
|
||||
};
|
||||
|
||||
enum PLAY_STATUS {
|
||||
idle, pause, playing
|
||||
};
|
||||
|
||||
static enum PLAY_MODE mode = sequence;
|
||||
static enum PLAY_STATUS status = idle;
|
||||
static int count = 0;
|
||||
static int index = 0;
|
||||
static int old_index = 0;
|
||||
static cJSON *root = NULL;
|
||||
|
||||
printf("play_manager_f cmd: %s\tdata: %s\n", cmd, data);
|
||||
|
||||
pthread_mutex_lock(&music_mutex);
|
||||
|
||||
if (!strcmp(cmd, "volume.set")) {
|
||||
// 设置音量
|
||||
if (!strcmp(data, "+")) {
|
||||
vol_multiplier += 0.05;
|
||||
if (vol_multiplier > 1.0) vol_multiplier = 0.99;
|
||||
audio_player_set_channel_volume(aplayer, vol_multiplier);
|
||||
|
||||
printf("set vol_multiplier to %f\n", vol_multiplier);
|
||||
printf("set vol to %d\n", (int)(vol_multiplier * 100.0));
|
||||
}
|
||||
|
||||
else if (!strcmp(data, "-")) {
|
||||
vol_multiplier -= 0.05;
|
||||
if (vol_multiplier < 0.01) vol_multiplier = 0.01;
|
||||
|
||||
audio_player_set_channel_volume(aplayer, vol_multiplier);
|
||||
printf("set vol_multiplier to %f\n", vol_multiplier);
|
||||
printf("set vol to %d\n", (int)(vol_multiplier * 100.0));
|
||||
}
|
||||
else {
|
||||
int vol = atoi(data);
|
||||
vol_multiplier = vol / 100.0;
|
||||
|
||||
audio_player_set_channel_volume(aplayer, vol_multiplier);
|
||||
printf("set vol_multiplier to %f\n", vol_multiplier);
|
||||
printf("set vol to %d\n", (int)(vol_multiplier * 100.0));
|
||||
}
|
||||
}
|
||||
|
||||
else if (!strcmp(cmd, "play.list.clear")) {
|
||||
// 清空播放列表
|
||||
printf("clear the play list info\n");
|
||||
audio_player_stop(aplayer);
|
||||
cJSON_Delete(root);
|
||||
root = NULL;
|
||||
index = 0;
|
||||
old_index = 0;
|
||||
count = 0;
|
||||
status = idle;
|
||||
}
|
||||
|
||||
else if (!strcmp(cmd, "play.list.get")) {
|
||||
}
|
||||
else if (!strcmp(cmd, "play.list.check")) {
|
||||
// 开始真正播放
|
||||
cJSON *temp, *music;
|
||||
if (root) {
|
||||
if (status == idle) {
|
||||
temp = cJSON_GetObjectItem(root, "count");
|
||||
count = temp->valueint;
|
||||
if (count > 0) {
|
||||
status = playing;
|
||||
music = cJSON_GetObjectItem(root, "content");
|
||||
temp = cJSON_GetArrayItem(music, index);
|
||||
temp = cJSON_GetObjectItem(temp, "linkUrl");
|
||||
printf("ready to play url is %s\n", temp->valuestring);
|
||||
audio_player_play(aplayer, temp->valuestring);
|
||||
}
|
||||
}
|
||||
else if (status == pause) {
|
||||
status = playing;
|
||||
audio_player_resume(aplayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(cmd, "play.list.update")) {
|
||||
// 更新播放列表
|
||||
// TODO: update
|
||||
printf("update the play list info\n");
|
||||
audio_player_stop(aplayer);
|
||||
if (root) cJSON_Delete(root);
|
||||
root = NULL;
|
||||
index = 0;
|
||||
old_index = 0;
|
||||
count = 0;
|
||||
status = idle;
|
||||
root = cJSON_Parse(data);
|
||||
}
|
||||
else if (!strcmp(cmd, "status.set")) {
|
||||
// 设置播放状态
|
||||
printf("status.set data is %s status is %d\n", data, status);
|
||||
if (!strcmp(data, "pause") && status == playing) {
|
||||
status = pause;
|
||||
audio_player_pause(aplayer);
|
||||
}
|
||||
else if (!strcmp(data, "resume") && status == pause) {
|
||||
status = playing;
|
||||
audio_player_resume(aplayer);
|
||||
}
|
||||
else if (!strcmp(data, "replay") && status == pause) {
|
||||
status = playing;
|
||||
|
||||
cJSON *temp, *music;
|
||||
music = cJSON_GetObjectItem(root, "content");
|
||||
temp = cJSON_GetArrayItem(music, index);
|
||||
temp = cJSON_GetObjectItem(temp, "linkUrl");
|
||||
printf("ready to play url is %s\n", temp->valuestring);
|
||||
audio_player_stop(aplayer);
|
||||
audio_player_play(aplayer, temp->valuestring);
|
||||
}
|
||||
else if (!strcmp(data, "step")) {
|
||||
if (status == playing) {
|
||||
status = pause;
|
||||
audio_player_pause(aplayer);
|
||||
}
|
||||
else if (status == pause) {
|
||||
status = playing;
|
||||
audio_player_resume(aplayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strcmp(cmd, "mode.set")) {
|
||||
// 播放模式
|
||||
if (!strcmp(data, "sequence")) mode = sequence;
|
||||
else if (!strcmp(data, "random")) mode = random;
|
||||
else if (!strcmp(data, "single")) mode = single;
|
||||
else if (!strcmp(data, "loop")) mode = loop;
|
||||
}
|
||||
else if (!strcmp(cmd, "change.set")) {
|
||||
// 歌曲切换
|
||||
// TODO: update
|
||||
if (!strcmp(data, "prev")) {
|
||||
// 上一首
|
||||
index = old_index;
|
||||
}
|
||||
else if (!strcmp(data, "next")) {
|
||||
// 下一首
|
||||
old_index = index;
|
||||
index = play_judge_f(index, count, mode);
|
||||
}
|
||||
else if (!strcmp(data, "change")) {
|
||||
// 换一首
|
||||
old_index = index;
|
||||
index = play_judge_f(index, count, mode);
|
||||
}
|
||||
|
||||
if (index == -1) {
|
||||
// 播放结束
|
||||
cJSON_Delete(root);
|
||||
audio_player_stop(aplayer);
|
||||
root = NULL;
|
||||
index = 0;
|
||||
old_index = 0;
|
||||
count = 0;
|
||||
status = idle;
|
||||
}
|
||||
else {
|
||||
// 待播放指定的音频
|
||||
status = idle;
|
||||
}
|
||||
}
|
||||
else if (!strcmp(cmd, "play.choose.update")) {
|
||||
// 播放特定歌曲
|
||||
// TODO: update
|
||||
int find = 0;
|
||||
int i = 0;
|
||||
cJSON *temp = cJSON_Parse(data);
|
||||
temp = cJSON_GetObjectItem(temp, "linkUrl");
|
||||
|
||||
cJSON *music = cJSON_GetObjectItem(root, "content");
|
||||
cJSON *xx;
|
||||
for (i = 0; i < count; i++) {
|
||||
xx = cJSON_GetArrayItem(music, i);
|
||||
xx = cJSON_GetObjectItem(xx, "linkUrl");
|
||||
if (!strcmp(xx->valuestring, temp->valuestring)) {
|
||||
find = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (find) {
|
||||
old_index = index;
|
||||
index = i;
|
||||
printf("ready to play url is %s\n", temp->valuestring);
|
||||
audio_player_stop(aplayer);
|
||||
audio_player_play(aplayer, temp->valuestring);
|
||||
}
|
||||
else {
|
||||
// 播放歌曲不在播放列表里面
|
||||
printf("wwwwwwwwwwwwwwwwwwwwwwwwwww\n");
|
||||
}
|
||||
}
|
||||
else if (!strcmp(cmd, "play.collect.choose")) {
|
||||
// 收藏歌曲
|
||||
}
|
||||
|
||||
else if (!strcmp(cmd, "play.uncollect.choose")) {
|
||||
// 取消收藏
|
||||
}
|
||||
|
||||
else if (!strcmp(cmd, "player.end") && root) {
|
||||
// 播放器播放结束
|
||||
// TODO: update
|
||||
old_index = index;
|
||||
index = play_judge_f(index, count, mode);
|
||||
printf("play_judge_f index is %d\n", index);
|
||||
if (index == -1) {
|
||||
// 播放结束
|
||||
audio_player_stop(aplayer);
|
||||
cJSON_Delete(root);
|
||||
root = NULL;
|
||||
index = 0;
|
||||
old_index = 0;
|
||||
count = 0;
|
||||
status = idle;
|
||||
}
|
||||
else {
|
||||
// 播放指定的音频
|
||||
cJSON *temp, *music;
|
||||
music = cJSON_GetObjectItem(root, "content");
|
||||
temp = cJSON_GetArrayItem(music, index);
|
||||
temp = cJSON_GetObjectItem(temp, "linkUrl");
|
||||
printf("ready to play url is %s\n", temp->valuestring);
|
||||
audio_player_stop(aplayer);
|
||||
audio_player_play(aplayer, temp->valuestring);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&music_mutex);
|
||||
}
|
||||
|
||||
int play_judge_f(int index, int count, int mode) {
|
||||
// sequence, random, single, loop
|
||||
if (mode == 0) {
|
||||
// 顺序播放
|
||||
if (index + 1 == count) return -1;
|
||||
else return index + 1;
|
||||
}
|
||||
else if (mode == 1) {
|
||||
// 随机播放
|
||||
srand(time(0));
|
||||
return rand() % count;
|
||||
}
|
||||
else if (mode == 2) {
|
||||
// 单曲循环
|
||||
return index;
|
||||
}
|
||||
else if (mode == 3) {
|
||||
// 循环播放
|
||||
return (index + 1) % count;
|
||||
}
|
||||
|
||||
else return -1;
|
||||
}
|
||||
|
||||
|
||||
BIN
rk3308/aispeech/dds_client/demo/music.o
Normal file
BIN
rk3308/aispeech/dds_client/demo/music.o
Normal file
Binary file not shown.
663
rk3308/aispeech/dds_client/doc/sdk帮助文档.md
Executable file
663
rk3308/aispeech/dds_client/doc/sdk帮助文档.md
Executable file
@ -0,0 +1,663 @@
|
||||
## linux-sdk 使用说明
|
||||
|
||||
### 接口说明
|
||||
|
||||
**sdk语音相关的接口**
|
||||
|
||||
```
|
||||
sdk 初始化函数,主要包括sdk参数初始化和授权两个过程,这个函数是阻塞的,
|
||||
授权的超时时间为 15 秒。
|
||||
|
||||
struct dds_client *dds_client_init (const char *config_json);
|
||||
|
||||
参数说明:
|
||||
|
||||
@ config_json: 配置选项,json 格式的字符串;
|
||||
|
||||
返回值:
|
||||
|
||||
错误情况下返回NULL, 否则返回 struct dds_client 实例指针;
|
||||
```
|
||||
```
|
||||
运行 sdk 函数,调用此函数之后就可以语音交互了。
|
||||
|
||||
int dds_client_start(struct dds_client *ds, ddsLintener cb,
|
||||
void *user);
|
||||
|
||||
参数说明:
|
||||
|
||||
@ ds: 由 dds_client_init 返回的 struct dds_client 实例指针;
|
||||
@ cb: 监听 sdk 事件的回调函数;
|
||||
@ user: 用户参数;
|
||||
|
||||
返回值:
|
||||
|
||||
出错返回 -1
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
释放 sdk 实例的函数:
|
||||
|
||||
void dds_client_release(struct dds_client *ds);
|
||||
|
||||
参数说明:
|
||||
|
||||
@ ds: 由 dds_client_init 返回的 struct dds_client 实例指针;
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
向 sdk 内部发送消息:
|
||||
|
||||
int dds_client_publish(struct dds_client *ds, int ev,
|
||||
const char *data);
|
||||
|
||||
参数说明:
|
||||
@ ds: 由 dds_client_init 返回的 struct dds_client 实例指针;
|
||||
@ ev: 发送的消息事件;
|
||||
@ data: 此消息附带的数据, json 格式;
|
||||
|
||||
|
||||
返回值:
|
||||
|
||||
只有当 sdk 完成初始化并且授权成功之后才能正确返回,否则返回 -1
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
返回 nativeAPI 查询结果的接口
|
||||
|
||||
int dds_client_resp_nativeapi(struct dds_client *ds,
|
||||
const char *native_api, const char *native_api_data_json);
|
||||
|
||||
参数说明:
|
||||
|
||||
ds: sdk 实例指针;
|
||||
|
||||
native_api: 这个 nativeAPI topic 名;
|
||||
|
||||
native_api_data_json: 查询数据结果,json string,格式如下,
|
||||
"duiWidget" 字段必须包含, 且目前取值为 "text"。 用户自定义的数据必须放在
|
||||
extra 字段中。
|
||||
|
||||
{
|
||||
"duiWidget": "text",
|
||||
"extra": {
|
||||
"xx": "11"
|
||||
}
|
||||
}
|
||||
|
||||
返回值: 如果 sdk 没有初始化完成或者授权成功则返回-1
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
内部合成的接口:
|
||||
|
||||
int dds_client_speak(struct dds_client *ds, const char *text);
|
||||
|
||||
参数说明:
|
||||
|
||||
ds: sdk 实例指针
|
||||
|
||||
text: 需要合成的文本
|
||||
|
||||
返回值: 如果 sdk 没有初始化完成或者授权成功则返回-1
|
||||
```
|
||||
|
||||
```
|
||||
外部 feed 音频接口:
|
||||
|
||||
int dds_client_feed_audio(struct dds_client *ds, char *data, int len);
|
||||
|
||||
参数说明:
|
||||
|
||||
ds: sdk 实例指针
|
||||
|
||||
data: 录音机数据
|
||||
|
||||
len: 数据长度
|
||||
|
||||
返回值: 出错返回 -1 ,此接口只有在 recorder 配置为外部方式才会生效。
|
||||
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
停止当前对话,包括停止合成,取消识别等。
|
||||
|
||||
int dds_client_stop_dialog(struct dds_client *ds);
|
||||
|
||||
参数说明:
|
||||
|
||||
ds: sdk 实例指针
|
||||
|
||||
text: 需要合成的文本
|
||||
|
||||
返回值: 如果 sdk 没有初始化完成或者授权成功则返回-1
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
关闭唤醒,此接口会终止当前的对话。
|
||||
|
||||
int dds_client_disable_wakeup(struct dds_client *ds);
|
||||
|
||||
参数说明:
|
||||
|
||||
ds: sdk 实例指针
|
||||
|
||||
返回值: 如果 sdk 没有初始化完成或者授权成功则返回-1
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
打开唤醒
|
||||
|
||||
int dds_client_enable_wakeup(struct dds_client *ds);
|
||||
|
||||
参数说明:
|
||||
|
||||
ds: sdk 实例指针
|
||||
|
||||
返回值: 如果 sdk 没有初始化完成或者授权成功则返回-1
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
// 获取当前的 tts 发音人,出错返回 NULL
|
||||
char *dds_client_get_speaker(struct dds_client *ds);
|
||||
|
||||
// 获取当前的 tts 播报速度,为 float 型, 在 0 ~ 1 之间,越大表示速度越慢。
|
||||
float dds_clent_get_speed(struct dds_client *ds);
|
||||
|
||||
// 获取当前的 tts 的播报音量大小, 为 int 型, 在 0 ~ 100 之间。
|
||||
int dds_client_get_volume(struct dds_client *ds);
|
||||
|
||||
// 设置当前的 tts 的播报音色人,出错返回 -1
|
||||
int dds_client_set_speaker(struct dds_client *ds, char *speaker);
|
||||
|
||||
// 设置当前的 tts 的播报速度大小,出错返回 -1
|
||||
int dds_client_set_speed(struct dds_client *ds, float speed);
|
||||
|
||||
// 设置当前的 tts 的播报音量大小,出错返回 -1
|
||||
int dds_client_set_volume(struct dds_client *ds, int vol);
|
||||
|
||||
```
|
||||
|
||||
|
||||
**sdk回调消息接口**
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>回调函数</th>
|
||||
<th>消息</th>
|
||||
<th>含义</th>
|
||||
<th>参数</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> local_wakeup.result </td>
|
||||
<td> 唤醒事件 </td>
|
||||
<td> json string,形如
|
||||
{"type":"major","greeting":"好的",
|
||||
"word":"你好小驰"} </td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> doa.result </td>
|
||||
<td> doa事件 </td>
|
||||
<td> json string, 形如 {"dao": 100} </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> sys.vad.begin </td>
|
||||
<td> vad开始的事件 </td>
|
||||
<td> 无 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> sys.vad.end </td>
|
||||
<td> vad结束的事件 </td>
|
||||
<td> 无 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> sys.tts.begin </td>
|
||||
<td> 合成音开始的事件 </td>
|
||||
<td> 无 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> sys.tts.end </td>
|
||||
<td> 合成音结束的事件,播放结束 </td>
|
||||
<td> 无 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> sys.asr.begin </td>
|
||||
<td> sdk内部开始做识别 </td>
|
||||
<td> 无 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> asr.speech.text </td>
|
||||
<td> 实时的语音识别结果反馈 </td>
|
||||
<td> json string </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> asr.speech.result </td>
|
||||
<td> 最终的语音识别结果反馈 </td>
|
||||
<td> json string </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> dm.output </td>
|
||||
<td> 对话的输出结果 </td>
|
||||
<td> json string </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> sys.dm.end </td>
|
||||
<td> 表示结束对话 </td>
|
||||
<td> 无 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> device.mode.return </td>
|
||||
<td> 表示设置设备状态的回复消息 </td>
|
||||
<td> json string "{"result":"success"}"</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> command://xx </td>
|
||||
<td> 在dui平台上配置的 command 指令 </td>
|
||||
<td> json string </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> ddsLintener </td>
|
||||
<td> native://xx </td>
|
||||
<td> 在dui平台上配置的 native 指令 </td>
|
||||
<td> json string </td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
### 配置选项
|
||||
|
||||
```
|
||||
|
||||
{
|
||||
"auth": {
|
||||
"productId": "278569448",
|
||||
"deviceProfile": ""
|
||||
},
|
||||
"front": {
|
||||
"aecBinPath": "",
|
||||
"wakeupBinPath": "",
|
||||
"beamformingBinPath": "",
|
||||
"rollBack": 0
|
||||
},
|
||||
"vad": {
|
||||
"resBinPath": "",
|
||||
"pauseTime": 500,
|
||||
"slienceTimeout": 5
|
||||
},
|
||||
"cloud": {
|
||||
"productId": "278569448",
|
||||
"aliasKey": "prod"
|
||||
},
|
||||
"recorder": {
|
||||
"mode": "internal"
|
||||
"samplerate":16000,
|
||||
"bits":16,
|
||||
"channels":1,
|
||||
"device": "default"
|
||||
},
|
||||
"player": {
|
||||
"device": "default"
|
||||
},
|
||||
"tts": {
|
||||
"type": "cloud",
|
||||
"voice": "zhilingf",
|
||||
"volume": 50,
|
||||
"speed": 0.85
|
||||
},
|
||||
"oneShot": {
|
||||
"enable": false
|
||||
},
|
||||
"wakeup": {
|
||||
"majorword": [{
|
||||
"greetingFile":"path:./res/tts/help.mp3",
|
||||
"greeting": "我在,有什么可以帮你",
|
||||
"pinyin": "ni hao xiao chi",
|
||||
"name": "你好小驰",
|
||||
"threshold": 0.127
|
||||
}, {
|
||||
"greetingFile":"path:./res/tts/help.mp3",
|
||||
"greeting": "我在,有什么可以帮你",
|
||||
"pinyin": "ni hao xiao le",
|
||||
"name": "你好小乐",
|
||||
"threshold": 0.144
|
||||
}],
|
||||
"cmdword": [{
|
||||
"pinyin": "jiang di yin liang",
|
||||
"threshold": 0.100,
|
||||
"action": "decrease.volume",
|
||||
"name": "降低音量"
|
||||
}]
|
||||
},
|
||||
"abnormal": {
|
||||
"netErrorHint":"path:../res/tts/net.mp3"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>参数</th>
|
||||
<th>类型</th>
|
||||
<th>含义</th>
|
||||
<th>是否必须</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> auth </td>
|
||||
<td> json 对象 </td>
|
||||
<td> 授权信息 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> auth.productId </td>
|
||||
<td>string</td>
|
||||
<td> dui 上创建产品ID </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> auth.deviceProfile </td>
|
||||
<td>string</td>
|
||||
<td>授权信息</td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> front </td>
|
||||
<td>json 对象 </td>
|
||||
<td> 前端信号处理的相关配置 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> front.aecBinPath </td>
|
||||
<td> string</td>
|
||||
<td>aec 算法资源路径</td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> front.wakeupBinPath </td>
|
||||
<td>string</td>
|
||||
<td>唤醒算法资源路径</td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> front.beamformingBinPath </td>
|
||||
<td>string</td>
|
||||
<td>beamforming 算法资源路径</td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> vad </td>
|
||||
<td> json 对象 </td>
|
||||
<td>vad 算法模块配置 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> vad.resBinPath </td>
|
||||
<td>string</td>
|
||||
<td>vad算法资源路径 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> vad.pauseTime </td>
|
||||
<td>int</td>
|
||||
<td>vad截止检测时长,单位为 ms,默认为 500ms </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> vad.slienceTimeout </td>
|
||||
<td>int</td>
|
||||
<td> vad 的静音检测超时时长,单位为s,默认为 6s </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> cloud </td>
|
||||
<td>json 对象 </td>
|
||||
<td>云端产品的相关配置 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>cloud.productId </td>
|
||||
<td>string</td>
|
||||
<td>dui平台上创建的产品ID</td>
|
||||
<td>必选 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> cloud.aliasKey </td>
|
||||
<td>string</td>
|
||||
<td> dui平台上创建的产品ID 发布支持, 取值为 "prod | test"</td>
|
||||
<td>可选,默认为 prod 分支</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>recorder </td>
|
||||
<td>json 对象 </td>
|
||||
<td>录音机的相关配置 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> recorder.mode </td>
|
||||
<td> string </td>
|
||||
<td> 录音方式,取值为 "internal | external" 分列表示内部录音和外部录音。 </td>
|
||||
<td> 可选 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> recorder.samplerate </td>
|
||||
<td> int </td>
|
||||
<td> 录音采样率 </td>
|
||||
<td> 必选 </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> recorder.bits </td>
|
||||
<td>int</td>
|
||||
<td>录音采样位数</td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> recorder.channels </td>
|
||||
<td>int</td>
|
||||
<td>录音采用通道数</td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> recorder.device </td>
|
||||
<td> string </td>
|
||||
<td>内部录音机的设备名,默认当前系统的 default 音频设备 </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> player</td>
|
||||
<td> json 对象 </td>
|
||||
<td>内部播放器的设置 </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> player.device </td>
|
||||
<td> string </td>
|
||||
<td>内部播放器的设备名,默认为 default </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> tts </td>
|
||||
<td>json 对象</td>
|
||||
<td>合成音的相关配置</td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr>
|
||||
<td> tts.type </td>
|
||||
<td>string </td>
|
||||
<td>合成音的类型,当前仅支持 "cloud" </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> tts.voice </td>
|
||||
<td>string </td>
|
||||
<td>合成音的音色 </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> tts.volume </td>
|
||||
<td> int </td>
|
||||
<td>合成音的音量 </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> tts.speed </td>
|
||||
<td> int </td>
|
||||
<td>合成音的速度 </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> oneShot </td>
|
||||
<td> json 对象 </td>
|
||||
<td> oneshot 模块配置 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> oneShot.enable </td>
|
||||
<td> bool </td>
|
||||
<td> 是否启用oneshot,当前仅支持 false </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> wakeup </td>
|
||||
<td> json 对象 </td>
|
||||
<td> 唤醒词的相关配置</td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> wakeup.majorword </td>
|
||||
<td> json 数组 </td>
|
||||
<td> 唤醒词的相关配置</td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> wakeup.cmdword </td>
|
||||
<td> json 数组 </td>
|
||||
<td> 快捷唤醒词配置 </td>
|
||||
<td>必选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> abnormal </td>
|
||||
<td> json 对象 </td>
|
||||
<td> sdk异常情况下对话配置 </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td> abnormal.netErrorHint </td>
|
||||
<td> string </td>
|
||||
<td> 网络错误下的提示音,需要配置成本地文件,网络不好的情况下云端合成也用不了。 </td>
|
||||
<td>可选</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
**唤醒词说明**
|
||||
|
||||
```
|
||||
{
|
||||
"greetingFile":"path:./res/tts/help.mp3",
|
||||
"greeting": "我在,有什么可以帮你",
|
||||
"pinyin": "ni hao xiao chi",
|
||||
"name": "你好小驰",
|
||||
"threshold": 0.127
|
||||
}
|
||||
|
||||
|
||||
greetingFile: 唤醒之后播放的提示音,支持本地录音文件,传入文件路径。
|
||||
greeting: 唤醒之后的提示文本, sdk内部合成。
|
||||
pinyin: 唤醒词拼音。
|
||||
name: 唤醒词的中文。
|
||||
threshold: 唤醒词阈值。
|
||||
|
||||
唤醒提示音播放优先级: 如果配置了 greetingFile 则播放 greetingFile ,
|
||||
否则播放 greeting 。
|
||||
|
||||
```
|
||||
|
||||
|
||||
**命令唤醒词说明**
|
||||
|
||||
```
|
||||
{
|
||||
"pinyin": "jiang di yin liang",
|
||||
"threshold": 0.100,
|
||||
"action": "decrease.volume",
|
||||
"name": "降低音量"
|
||||
}
|
||||
|
||||
pinyin: 唤醒词拼音。
|
||||
name: 唤醒词的中文。
|
||||
threshold: 唤醒词阈值。
|
||||
action: 该命令唤醒词对应的动作,比如这个例子中,sdk回调函数会抛出
|
||||
command://decrease.volume 消息。
|
||||
```
|
||||
BIN
rk3308/aispeech/dds_client/doc/sdk帮助文档.pdf
Executable file
BIN
rk3308/aispeech/dds_client/doc/sdk帮助文档.pdf
Executable file
Binary file not shown.
BIN
rk3308/aispeech/dds_client/libdds_client.so
Executable file
BIN
rk3308/aispeech/dds_client/libdds_client.so
Executable file
Binary file not shown.
BIN
rk3308/aispeech/dds_client/libs/libaudio_play.so
Executable file
BIN
rk3308/aispeech/dds_client/libs/libaudio_play.so
Executable file
Binary file not shown.
BIN
rk3308/aispeech/dds_client/libs/libauth.so
Executable file
BIN
rk3308/aispeech/dds_client/libs/libauth.so
Executable file
Binary file not shown.
BIN
rk3308/aispeech/dds_client/libs/libdds.so
Executable file
BIN
rk3308/aispeech/dds_client/libs/libdds.so
Executable file
Binary file not shown.
BIN
rk3308/aispeech/dds_client/libs/libduilite_fespa.so
Executable file
BIN
rk3308/aispeech/dds_client/libs/libduilite_fespa.so
Executable file
Binary file not shown.
BIN
rk3308/aispeech/dds_client/res/fesp/AEC_ch8-2-ch6_2ref_NTES_20180412_v0.9.3.bin
Executable file
BIN
rk3308/aispeech/dds_client/res/fesp/AEC_ch8-2-ch6_2ref_NTES_20180412_v0.9.3.bin
Executable file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
rk3308/aispeech/dds_client/res/tts/help.mp3
Executable file
BIN
rk3308/aispeech/dds_client/res/tts/help.mp3
Executable file
Binary file not shown.
BIN
rk3308/aispeech/dds_client/res/tts/net.mp3
Executable file
BIN
rk3308/aispeech/dds_client/res/tts/net.mp3
Executable file
Binary file not shown.
BIN
rk3308/aispeech/dds_client/res/vad/vad_aihome_v0.6.bin
Executable file
BIN
rk3308/aispeech/dds_client/res/vad/vad_aihome_v0.6.bin
Executable file
Binary file not shown.
BIN
rk3308/aispeech/dds_client/res/wakeup/wakeup_aifar_comm_20180104.bin
Executable file
BIN
rk3308/aispeech/dds_client/res/wakeup/wakeup_aifar_comm_20180104.bin
Executable file
Binary file not shown.
23
rk3308/aispeech/dds_service.sh
Executable file
23
rk3308/aispeech/dds_service.sh
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
#
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo "Starting $0..."
|
||||
cd /oem/dds_client/demo && ./demo_main &
|
||||
;;
|
||||
stop)
|
||||
echo "Stop $0..."
|
||||
killall demo_main
|
||||
;;
|
||||
restart|reload)
|
||||
killall demo_main
|
||||
cd /oem/dds_client/demo && ./demo_main &
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart}"
|
||||
exit 1
|
||||
esac
|
||||
|
||||
exit $?
|
||||
93
rk3308/aispeech/wifi_monitor.sh
Executable file
93
rk3308/aispeech/wifi_monitor.sh
Executable file
@ -0,0 +1,93 @@
|
||||
#!/bin/sh
|
||||
|
||||
PROCESS=/data/dds_service.sh
|
||||
|
||||
softap_stop()
|
||||
{
|
||||
echo softap_stoping
|
||||
|
||||
killall dnsmasq || echo dnsmasq-exit
|
||||
ip addr delete 192.168.1.1 dev wlan1 || echo ip-addr-delete
|
||||
killall hostapd || echo hostapd-exit
|
||||
ifconfig wlan1 down || echo wlan1-down
|
||||
|
||||
echo softap_stopped
|
||||
}
|
||||
|
||||
dds_start()
|
||||
{
|
||||
softap_stop
|
||||
#echo dds_start
|
||||
pidof demo_main || $PROCESS start
|
||||
|
||||
gst-play-1.0 /data/aispeech_softap_lite/audio/connect_ok.mp3
|
||||
}
|
||||
|
||||
dds_stop()
|
||||
{
|
||||
echo dds_stop
|
||||
#$PROCESS stop
|
||||
}
|
||||
wifiReadyAction()
|
||||
{
|
||||
pidof demo_main || $PROCESS start
|
||||
}
|
||||
wifiUpAction()
|
||||
{
|
||||
echo wifiUp
|
||||
dds_start
|
||||
}
|
||||
wifiDownAction()
|
||||
{
|
||||
echo wifiDown
|
||||
dds_stop
|
||||
}
|
||||
wifiChangeAction()
|
||||
{
|
||||
echo wifiChange
|
||||
dds_stop
|
||||
dds_start
|
||||
}
|
||||
wifiRequestingIp()
|
||||
{
|
||||
echo wifiRequestingIp
|
||||
}
|
||||
|
||||
checkwifistate()
|
||||
{
|
||||
local flag=0
|
||||
local last_ip_address=0
|
||||
while true
|
||||
do
|
||||
wpa_state=`wpa_cli -iwlan0 status | grep wpa_state | awk -F '=' '{printf $2}'`
|
||||
ip_address=`wpa_cli -iwlan0 status | grep ip_address | awk -F '=' '{printf $2}'`
|
||||
|
||||
if [ "${wpa_state}"x = "COMPLETED"x ];then
|
||||
if [ "${ip_address}"x != ""x ] && [ "${ip_address}"x != "0.0.0.0"x ];then
|
||||
if [ $flag -eq 0 ];then
|
||||
flag=1
|
||||
wifiUpAction
|
||||
elif [ "${ip_address}"x != "${last_ip_address}"x ];then
|
||||
flag=1
|
||||
wifiChangeAction
|
||||
else
|
||||
flag=1
|
||||
wifiReadyAction
|
||||
fi
|
||||
else
|
||||
flag=0
|
||||
wifiRequestingIp
|
||||
fi
|
||||
else
|
||||
if [ $flag -eq 1 ];then
|
||||
flag=0
|
||||
wifiDownAction
|
||||
fi
|
||||
fi
|
||||
sleep 3
|
||||
last_ip_address="${ip_address}"
|
||||
done
|
||||
}
|
||||
|
||||
$PROCESS stop
|
||||
checkwifistate
|
||||
25
rk3308/dueros/RkLunch.sh
Executable file
25
rk3308/dueros/RkLunch.sh
Executable file
@ -0,0 +1,25 @@
|
||||
cd /data/
|
||||
|
||||
# for ai-va demo
|
||||
amixer cset name='Master Volume' 120
|
||||
amixer cset name='Speaker Volume' 255
|
||||
|
||||
# for evb-codec
|
||||
#amixer -c 1 cset name='DAC HPMIX Left Volume' 1
|
||||
#amixer -c 1 cset name='DAC HPMIX Right Volume' 1
|
||||
|
||||
ifconfig lo 127.0.0.1 netmask 255.255.255.0
|
||||
|
||||
#dueros take over control
|
||||
killall dhcpcd
|
||||
killall hostapd
|
||||
killall dnsmasq
|
||||
|
||||
aplay /usr/appresources/startup.wav &
|
||||
|
||||
#wpa_supplicant -B -i wlan0 -c /data/cfg/wpa_supplicant.conf
|
||||
#sleep 3
|
||||
#dhcpcd &
|
||||
|
||||
# start dueros
|
||||
/oem/dueros_service.sh start
|
||||
BIN
rk3308/dueros/baidu_spil_rk3308/alsa_audio_client_sample
Executable file
BIN
rk3308/dueros/baidu_spil_rk3308/alsa_audio_client_sample
Executable file
Binary file not shown.
BIN
rk3308/dueros/baidu_spil_rk3308/alsa_audio_main_service
Executable file
BIN
rk3308/dueros/baidu_spil_rk3308/alsa_audio_main_service
Executable file
Binary file not shown.
4
rk3308/dueros/baidu_spil_rk3308/config_rk3229_linux_6_2.lst
Executable file
4
rk3308/dueros/baidu_spil_rk3308/config_rk3229_linux_6_2.lst
Executable file
@ -0,0 +1,4 @@
|
||||
MIC_NUM: 6
|
||||
MIC_COORD:[0.035,0,0];[0.0175,-0.03031,0];[-0.0175,-0.03031,0];[-0.035,0,0];[-0.0175,0.03031,0];[0.0175,0.03031,0]
|
||||
REF_CH: 2
|
||||
WAKEUP_MIC_INDEX: 0
|
||||
BIN
rk3308/dueros/baidu_spil_rk3308/libbdSPILAudioProc.so
Executable file
BIN
rk3308/dueros/baidu_spil_rk3308/libbdSPILAudioProc.so
Executable file
Binary file not shown.
BIN
rk3308/dueros/baidu_spil_rk3308/libbd_alsa_audio_client.so
Executable file
BIN
rk3308/dueros/baidu_spil_rk3308/libbd_alsa_audio_client.so
Executable file
Binary file not shown.
BIN
rk3308/dueros/baidu_spil_rk3308/libbd_audio_vdev.so
Executable file
BIN
rk3308/dueros/baidu_spil_rk3308/libbd_audio_vdev.so
Executable file
Binary file not shown.
BIN
rk3308/dueros/baidu_spil_rk3308/libbdaudResample.so
Executable file
BIN
rk3308/dueros/baidu_spil_rk3308/libbdaudResample.so
Executable file
Binary file not shown.
20
rk3308/dueros/baidu_spil_rk3308/readme.txt
Executable file
20
rk3308/dueros/baidu_spil_rk3308/readme.txt
Executable file
@ -0,0 +1,20 @@
|
||||
libbdSPILAudioProc.so
|
||||
md5: 78b343f4d5f393d119dc88e3c019835c
|
||||
|
||||
libbd_audio_vdev.so
|
||||
md5: f31ade415b132a07eda1ccef039b260a
|
||||
|
||||
libbdaudResample.so
|
||||
md5: 73f66d2c73248bb6778d455206cac7ed
|
||||
|
||||
libbd_alsa_audio_client.so
|
||||
md5: 236132ef695cef50deffe2dde95e4fc8
|
||||
|
||||
使用说明:
|
||||
1. adb push so库和alsa_audio_main_service, setup.sh, config_rk3229_linux_6_2.lst到/data目录
|
||||
2. 修改权限chmod 777 setup.sh
|
||||
chmod 777 alsa_audio_main_service
|
||||
3. 运行录音程序
|
||||
cd /data
|
||||
./alsa_audio_main_service 6mic_loopback &
|
||||
4. 运行duer_linux或者demo
|
||||
11
rk3308/dueros/baidu_spil_rk3308/setup.sh
Executable file
11
rk3308/dueros/baidu_spil_rk3308/setup.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
touch /dev/shm/shm_bd_a278_asr
|
||||
touch /dev/shm/shm_bd_a278_comm
|
||||
touch /tmp/sem_bd_a278_asr
|
||||
touch /tmp/sem_bd_a278_comm
|
||||
touch /tmp/sem_bd_a278_read
|
||||
chmod 666 /dev/shm/shm_bd_a278_asr
|
||||
chmod 666 /dev/shm/shm_bd_a278_comm
|
||||
chmod 666 /tmp/sem_bd_a278_asr
|
||||
chmod 666 /tmp/sem_bd_a278_comm
|
||||
chmod 666 /tmp/sem_bd_a278_read
|
||||
4
rk3308/dueros/bin/dnsmasq.conf
Executable file
4
rk3308/dueros/bin/dnsmasq.conf
Executable file
@ -0,0 +1,4 @@
|
||||
user=root
|
||||
listen-address=10.201.126.1
|
||||
dhcp-range=10.201.126.50,10.201.126.150
|
||||
server=/google/8.8.8.8
|
||||
3
rk3308/dueros/cfg/wpa_supplicant.conf
Executable file
3
rk3308/dueros/cfg/wpa_supplicant.conf
Executable file
@ -0,0 +1,3 @@
|
||||
ctrl_interface=/var/run/wpa_supplicant
|
||||
ap_scan=1
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user