📄 audio.c
字号:
/****************************************************************
** *
** 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 + -