PcmAudioPlay.c 5.2 KB
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <dirent.h>  
#include <sys/stat.h>  
#include <math.h>

#include "JZsdkLib.h"
#include "Megaphone/PcmAudio/PcmAudioFile.h"
#include "Megaphone/Megaphone.h"
#include "AudioDeal/AudioDeal.h"

#define PCM_DIR "/root/sdcard/pcm"
static int g_opus_sampleRate = 16000; //解码采样率

typedef struct t_PcmParam{
    unsigned char *FileName;
    unsigned int FileSize;
}t_PcmParam;

static T_JZTaskHandle g_pcmplay_task = NULL;

static T_JZsdkReturnCode PcmPlay_Interface(t_PcmParam *PcmParam)
{
    unsigned int nbBytes;
    uint8_t cbits[3 * 1276];
    int timeNum = 0;
    int loop = JZ_FLAGCODE_OFF;
    int loop_interval;
    double total_duration = 0;
    int last_printed_second = -1; // 上次打印的秒数,初始化为-1表示还没有打印过

    unsigned char PcmPath[JZSDK_FILE_PATH_SIZE_MAX];
    snprintf(PcmPath, JZSDK_FILE_PATH_SIZE_MAX, "%s/%s", PCM_DIR, PcmParam->FileName);

    FILE *Pcm_fp = fopen(PcmPath, "rb");
    if (Pcm_fp == NULL)
    {
        JZSDK_LOG_ERROR("PcmPlay_Interface: fopen failed, file name = %s", PcmParam->FileName);
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }

    while (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_ON)
    {
        nbBytes = fread(cbits, 1, 3 * 1276, Pcm_fp);
		if(nbBytes > 0)
        {
            AudioDeal_PcmDataInput(g_opus_sampleRate, (unsigned char *)cbits, nbBytes);
        }

        int totalSamples = nbBytes / (2);

        // 计算当前帧的持续时间(秒)  
        double frame_duration = (double)totalSamples / g_opus_sampleRate;  
        total_duration += frame_duration;  

        int current_second = (int)floor(total_duration); // 获取当前总时间的整数秒部分  
        if (current_second > last_printed_second)  
        {  
            printf("nb:%d rate:%d duration:%f total_duration:%f\n", totalSamples, g_opus_sampleRate, frame_duration, current_second);  

            //回传播放时间
            Megaphone_PlayBackTime(current_second);

            last_printed_second = current_second; // 更新上次打印的秒数  
        }  

		if (feof(Pcm_fp))
		{
            total_duration = 0;
            last_printed_second = -1;

            //如果循环播放没打开
            Megaphone_param(JZ_FLAGCODE_GET, MEGAPHONE_LOOP, &loop);
            Megaphone_param(JZ_FLAGCODE_GET, MEGAPHONE_LOOP_INTERVAL, &loop_interval);

            if (loop == JZ_FLAGCODE_OFF)
            {
                timeNum = 0;
                
                // //播放结束延迟
                // while ((timeNum <=3000) && (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_ON))
                // {
                //     delayMs(10);
                //     timeNum +=10;
                // }

                break;
            }
            //如果循环播放打开
            else if (loop == JZ_FLAGCODE_ON)
            {
                timeNum = 0;
                JZSDK_LOG_INFO("循环播放pcm");
                
                // //播放结束延迟
                // while ((loop == 1) && (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_ON))
                // {
                //     delayMs(10);
                //     timeNum +=10;
                // }

                //重置文件光标 继续播放
                fseek(Pcm_fp, 0, SEEK_SET);

                //循环播放延时
                while (loop_interval > 0 && (loop == JZ_FLAGCODE_ON) && (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_ON))
                {
                    delayMs(50);
                    loop_interval -= 50;
                }
                
                continue;
            }    
        }
    }
    
    fclose(Pcm_fp);

    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}

/*
*
*      播放固定位置pcm线程
*
*/
static void *Pcm_Play_task(void *arg)
{
    Megaphone_MegDataGenFlag(JZ_FLAGCODE_SET, JZ_FLAGCODE_ON);
    Megaphone_MegDataGenFinshFlag(JZ_FLAGCODE_SET, JZ_FLAGCODE_ON);
    
    //广播开始
    Megaphone_status_Broadcast(AUDIO_PLAY_STATUS_PCM_LIST);

    int amplifier = JZ_FLAGCODE_ON;
    Megaphone_Amplifier_param(JZ_FLAGCODE_SET, &amplifier);
     
    t_PcmParam *PcmParam = (t_PcmParam *)arg;
	PcmPlay_Interface(PcmParam);

    amplifier = JZ_FLAGCODE_OFF;
    Megaphone_Amplifier_param(JZ_FLAGCODE_SET, &amplifier);

    Megaphone_MegDataGenFlag(JZ_FLAGCODE_SET, JZ_FLAGCODE_OFF);
    Megaphone_MegDataGenFinshFlag(JZ_FLAGCODE_SET, JZ_FLAGCODE_OFF);

    //广播关闭
	Megaphone_status_Broadcast(JZ_FLAGCODE_OFF);
}


T_JZsdkReturnCode PcmAudioPlay_Play(unsigned char *str, unsigned int str_len)
{
    T_JZsdkOsalHandler *OsalHandler = JZsdk_Platform_GetOsalHandler();

    T_JZsdkReturnCode ret;

    ret = Megaphone_PcmFile_IsExistInList(str, str_len);
    if (ret != JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS)
    {
        JZSDK_LOG_ERROR("PcmAudioPlay_Play: Megaphone_PcmFile_IsExistInList failed, ret = %d", ret);
        return ret;
    }

    t_PcmParam *PcmParam = (t_PcmParam *)malloc(sizeof(t_PcmParam));
    PcmParam->FileName = str;
    PcmParam->FileSize = str_len;
    
    //播放
    OsalHandler->TaskCreate("PiayPcmFile", Pcm_Play_task, 8192, PcmParam, &g_pcmplay_task);

    return JZ_ERROR_SYSTEM_MODULE_CODE_SUCCESS;
}