⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 audio.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************
**                                                              *
**  FILE         : audio.C                                    *
**                                                              *
**  By : Cyb 2006.11.21                                         *
****************************************************************/


#define  AUDIO_GLOBALS
#include "includes.h"
#include "poweramp.h"
#include "isd4002.h"
#include "roundbuf.h"
#include "tools.h"
#include "audio.h"
#include "timetask.h"
#include "systask.h"
#include "message.h"
#include "errcode.h"
#include "errtask.h"
#include "uart_drv.h"
#include "hardware.h"
#include "isddriv.h"
#include "almtask.h"
#include "portdrv.h"
#include "gpsrecer.h"
#include "Predictor.h"


#define   NOUSEASM               1
#define   LEDPARA_SCANAUDIO       PORT_LEDGREEN,   2, 2   
/*
*******************************************************************************
* define config parameters
*******************************************************************************
*/
#define SIZE_PRIORBUF                           50
#define SIZE_PLAYBUF                            512
#define MAX_SCAN                                3

#define PERIOD_WAIT                             MILTICK,   5
#define PERIOD_WAIT_READY                       SECOND,    15
#define PERIOD_WATCH                            SECOND,   120    /* 注意:允许一段语音段的时间最长为120秒 */
#define Period_Exameine                         MILTICK,   1
#define Period_WaitScan                         MILTICK,   5
/*
********************************************************************************
* define opcode
********************************************************************************
*/
#define OP_WAIT                                 0x00
#define OP_POWERUP                              0x04        /* 00100<xxxxxxxxxxx> */
#define OP_SETPLAY                              0x1c        /* 11100<A10-A0> */
#define OP_PLAY                                 0x1e        /* 11110<xxxxxxxxxxx> */
#define OP_SETREC                               0x14        /* 10100<A10-A0> */
#define OP_REC                                  0x16        /* 10110<xxxxxxxxxxx> */
#define OP_SETMC                                0x1d        /* 11101<A10-A0> */
#define OP_MC                                   0x1f        /* 11111<xxxxxxxxxxx> */
#define OP_STOP                                 0x06        /* 0x110<xxxxxxxxxxx> */
#define OP_STOPPWRDN                            0x02        /* 0x01x<xxxxxxxxxxx> */

/*
********************************************************************************
* define status
********************************************************************************
*/
#define _POWERDOWN                              0x00
#define _READY                                  0x01
#define _PLAY                                   0x02
#define _RECORD                                 0x03
#define _SCAN                                   0x04
#define _MASK                                   0x0f
#define _SCANSUCCESS                            0x40
#define _EXECUTE                                0x80
/*
********************************************************************************
* define module variants
********************************************************************************
*/
static BOOLEAN    WaitSignal;
static INT8U   Status, ChannelType;
static INT16U  CueSeg, RecSeg, RecPos;
static TMR_TSK   *WaitTmrID, *MonitorTmrID, *WatchTmrID;
static TMR_TSK  *WaitScanEndTmr;
static INT32U   RecTime;

static INT8U   PlayBuf[SIZE_PLAYBUF], PriorBuf[SIZE_PRIORBUF];
static ROUNDBUF_STRUCT PlayRound, PriorRound;

static  void  (*Informer)(void);

static INT16U  tbl_seg[1024];
static INT8U   ct_scan, ScanSeg;
static BOOLEAN ScanFinished;
static INT16U  AD_MAX;



static void SelectPlayChannel(void)
{
         
        OpenPowerAmp();
  
}

static INT16U Send_SETMC(void)
{
    WaitSignal = TRUE;
    StartTmr(WatchTmrID, PERIOD_WATCH);
#if NOUSEASM >0
    return SendISDOP(OP_SETMC, 0x00);
#else
    return _SendISDOP(OP_SETMC, 0x00);
#endif 
}

static INT16U Send_MC(void)
{
    WaitSignal = TRUE;
    StartTmr(WatchTmrID, PERIOD_WATCH);
#if NOUSEASM >0    
    return SendISDOP(OP_MC, 0x00);
#else
    return _SendISDOP(OP_MC, 0x00);
#endif 
}

static void Send_SETPLAY(INT16U seg)
{
    if(!ScanFinished)
    {
        return;
    }
    SelectPlayChannel();                             /* 选择播放通道 */
    WaitSignal = TRUE;
    StartTmr(WatchTmrID, PERIOD_WATCH);
#if NOUSEASM >0
    SendISDOP(OP_SETPLAY, seg);
#else
    _SendISDOP(OP_SETPLAY, seg);
#endif 
}

static void Send_REC(void)
{
#if NOUSEASM >0  
    SendISDOP(OP_REC, 0x00);
#else
    _SendISDOP(OP_REC, 0x00);
#endif
}

static void Send_SETREC(void)
{
#if NOUSEASM >0
    SendISDOP(OP_SETREC, 0x00);
#else
    _SendISDOP(OP_SETREC, 0x00);
#endif 
}

static void Turninto_READY(void)
{
    Status &= ~_MASK;
    Status |= _READY;
    WaitSignal = FALSE;
    StartTmr(MonitorTmrID, PERIOD_WAIT_READY);
}

static void StartPlay(void)
{
    INT32U seg;
    INT16U index;
    
    
    if ((Status & _MASK) != _PLAY) return;
  
    if ((seg = ReadRoundBuf(&PlayRound)) == -1) 
    {
         if ((Status & _MASK) == _PLAY) 
         {
             ClosePowerAmp();
             Turninto_READY();
         }
    } 
    else 
    {
         if ((seg & 0x60) == 0x60)                               /* 同时选择功放和MIC输出 */ 
         {                             
             ChannelType = 0;
         } 
         else if ((seg & 0x60) == 0x40)                          /* 选择功放输出 */
         {                      
             ChannelType = 1;
         } 
         else                                                    /* 选择mic输出 */
         {                                                
             ChannelType = 2;
         }
            
         seg   &= 0x1f;
         index  = seg << 8;
            
         if ((seg = ReadRoundBuf(&PlayRound)) == -1) 
         { 
            if ((Status & _MASK) == _PLAY) 
            {
                ClosePowerAmp();
                Turninto_READY();
            }
         }
        
         index |= seg;
         Send_SETPLAY(tbl_seg[index]);
            
   }

       
}

static void ScanAudio(void)
{
    INT16U addr;
    
    if ((Status & _MASK) != _SCAN) return;

     
    if (ScanSeg < AD_MAX) 
    {
        if (ScanSeg == 0) 
        {
          
            tbl_seg[0] = 0;                                         /* 记录0段地址 */
            Send_SETMC();                                           /* 快进到下一段 */
            
        } 
        else 
        {
           
#if NOUSEASM  >0           
            addr = SendISDOP(OP_STOP, 0);                           /* 获取当前段起始地址 */
#else
            addr = _SendISDOP(OP_STOP, 0); 
#endif                         
            if (ct_scan > 0)                                        /* 非第一次扫描 */
            {                                     
                if (addr != tbl_seg[ScanSeg])                       /* 新获取位置与之前扫描位置不一致 */
                {                     
                    ct_scan = 0;                                    /* 清除扫描计数器 */
                }
            }
            
            tbl_seg[ScanSeg] = addr;                                /* 记录当前段地址 */
                        
            if (ScanSeg < (AD_MAX - 1)) 
            {
                 Send_MC();                                          /* 快进到下一段 */
            }
        
       }
    }
    
    if (++ScanSeg >= AD_MAX)                                        /* 一次扫描循环结束 */
    {                                      
        if (++ct_scan >= MAX_SCAN)                                  /* 已连续扫描3次 */
        {                               
            Status |= _SCANSUCCESS;                                 /* 置扫描成功标志 */
            ScanFinished = TRUE;
            
            RemovePermnentPort(PORT_LEDGREEN);
            
            if(GpsDataValid())
            {
                InstallPermnentPort(PORT_LEDGREEN,10,10);
               
            }
            
           PowerDownAudio();                                       /* 进入省电状态 */
             
            
        } 
        else 
        {
            ScanSeg = 0;
                                                                         /* 清除扫描段计数器 */
            if ( OSQPost(SysTaskMsgQue, MSG_AUDIO_TSK, 0, 0)!=OS_NO_ERR) /* 发送消息启动一次新的扫描过程 */ 
            {          
                ErrExit(ERR_AUDIO_SENDMSG);
            }
        }
    }
}

static void StartRecord(void)
{
    if ((Status & _MASK) != _RECORD) return;
    
    if (CueSeg > 0) 
    {
        if (--CueSeg == 0) 
        {
            StartTmr(MonitorTmrID, SECOND, RecTime);
            Send_REC();
            RecPos++;
            RecSeg = 0xffff;
        } 
        else 
        {
            Send_MC();
            RecPos++;
        }
    } 
    else 
    {
        if (RecSeg != 0xffff) 
        {
            if (RecSeg == 0x00) 
            {
                StartTmr(MonitorTmrID,SECOND, RecTime);
                Send_SETREC();
                RecPos = 1;
                RecSeg = 0xffff;
            } 
            else 
            {
                if (RecSeg == RecPos) 
                {
                    StartTmr(MonitorTmrID,SECOND, RecTime);
                    Send_REC();
                    RecPos++;
                    RecSeg = 0xffff;
                } 
                else if (RecSeg > RecPos) 
                {
                    CueSeg = RecSeg - RecPos;
                    Send_MC();
                    RecPos++;
                } 
                else 
                {
                    CueSeg = RecSeg;
                    Send_SETMC();
                    RecPos++;
                }
           }
        }
        else 
        {
            StopAudioOP();
            if (Informer != 0) Informer();
        }
    }
}

static void StartPriorOP(void)
{
    INT16S opcode;
    
    for (;;) 
    {
        if (Status & _EXECUTE) return;
        
        if ((opcode = ReadRoundBuf(&PriorRound)) == -1) 
        {
            ScanAudio();
            StartPlay();
            StartRecord();
            return;
        }
        
        switch (opcode)
        {
            case OP_WAIT:
                StartTmr(WaitTmrID, PERIOD_WAIT);
                Status |= _EXECUTE;
                break;
            case OP_POWERUP:
#if  NOUSEASM  >0 
                SendISDOP(OP_POWERUP, 0x00);
#else       
                _SendISDOP(OP_POWERUP, 0x00);
#endif
                break;
            case OP_STOP:
#if  NOUSEASM  >0  
                SendISDOP(OP_STOP, 0x00);
#else
                _SendISDOP(OP_STOP, 0x00);
#endif 
                break;
            case OP_STOPPWRDN:
#if  NOUSEASM  >0           
                SendISDOP(OP_STOPPWRDN, 0x00);
#else 
                _SendISDOP(OP_STOPPWRDN, 0x00);
#endif 
                break;
            default:
                break;
        }
    }
}

static void WaitTmrProc(void)
{
    StopTmr(WaitTmrID);
    Status &= ~_EXECUTE;
    StartPriorOP();
}

static void MonitorTmrProc(void)
{
    StopTmr(MonitorTmrID);
    
    if ((Status & _MASK) == _READY) 
    {
        PowerDownAudio();
    } 
    else if ((Status & _MASK) == _RECORD) 
    {
        StartPriorOP();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -