📄 soundgen.c
字号:
#include <p30f6014.h>
#include <dsp.h>
#include "common.h"
#include "timers.h"
#include "soundgen.h"
#include "procsignal.h"
#include "lcd.h"
#include "gettime.h"
#include "soundtable.h"
#define STATE_TICK 0
#define STATE_TOCK 1
#define STATE_MIN15 2
#define STATE_MIN30 3
#define STATE_MIN45 4
#define STATE_PREHOUR 5
#define STATE_HOURCHIMES 6
#define STATE_SILENCE1 7
#define STATE_SILENCE2 8
static unsigned int SamplePos;
static unsigned int DataPos;
static unsigned char LastSec;
static unsigned char LastMin;
static unsigned char LastHr;
static unsigned char ChimeCount;
static unsigned char SoundState;
static unsigned char SilenceNextState;
static FMGenStruct Generators[3];
static FMDataStruct* pFMData;
void ServiceSound( fractional* pOutData );
void InitSoundGen( void);
static fractional CreateNextSample( FMDataStruct* pDataStruct );
static void StartGens( FMInitStruct* pInitStruct , FMDataStruct* pdata);
static void SoundStateMachine( void );
//初始化语音产生
void InitSoundGen(void)
{
LastSec = SecondsCount;
LastMin = MinutesCount;
LastHr = LocalHoursCount;
ChimeCount = 3; //设置每小时的报时数值
SoundState = STATE_TICK; //开始每小时一次的报时
SemB.SoundInhibit = FALSE;
}
//初始化并开始3种语音生成器
static void StartGens( FMInitStruct* pInitStruct , FMDataStruct* pdata)
{
pFMData = pdata;
Generators[0].mphzinc = pInitStruct->minc0;
Generators[0].mphzacc = 0;
Generators[0].mindex = pInitStruct->mindx0;
Generators[0].cphzinc = pInitStruct->cinc0;
Generators[0].cphzacc = 0;
Generators[0].camp = pInitStruct->camp0;
Generators[1].mphzinc = pInitStruct->minc1;
Generators[1].mphzacc = 0;
Generators[1].mindex = pInitStruct->mindx1;
Generators[1].cphzinc = pInitStruct->cinc1;
Generators[1].cphzacc = 0;
Generators[1].camp = pInitStruct->camp1;
Generators[2].mphzinc = pInitStruct->minc2;
Generators[2].mphzacc = 0;
Generators[2].mindex = pInitStruct->mindx2;
Generators[2].cphzinc = pInitStruct->cinc2;
Generators[2].cphzacc = 0;
Generators[2].camp = pInitStruct->camp2;
SamplePos = 0;
DataPos = 0;
SemA.SoundAct = TRUE;
}
//管理语音系统并产生语音采样
void ServiceSound( fractional* pOutData )
{
int i;
if(SemA.SoundAct && !SemB.SoundInhibit)
{
LED4_ON
for(i=0; i<PROC_BLOCK_SIZE; i++)
pOutData[i] = CreateNextSample( pFMData );
}
else
{
VectorScale(PROC_BLOCK_SIZE, pOutData, pOutData, 0);
LED4_OFF
}
if( SecondsCount != LastSec )
{
LastSec = SecondsCount;
SoundStateMachine();
if( 0 == (SecondsCount & 0x03) ) //每4秒钟同步钟摆
PendPos = 0;
}
else if( MinutesCount != LastMin )
{
LastMin = MinutesCount;
if(15 == MinutesCount)
SoundState = STATE_MIN15;
else if(30 == MinutesCount)
SoundState = STATE_MIN30;
else if(45 == MinutesCount)
SoundState = STATE_MIN45;
}
else if( LocalHoursCount != LastHr )
{
LastHr = LocalHoursCount;
ChimeCount = 3; //设置每小时的报时数值
SoundState = STATE_PREHOUR; //开始每小时一次的报时
}
}
//产生不同时间的报时声
static void SoundStateMachine( void )
{
switch(SoundState)
{
case STATE_TICK:
if(SemB.TicTock)
StartGens( (FMInitStruct*)&TICK_INI, (FMDataStruct*)TICK_DATA);
SoundState = STATE_TOCK;
break;
case STATE_TOCK:
if(SemB.TicTock)
StartGens( (FMInitStruct*)&TOCK_INI, (FMDataStruct*)TOCK_DATA);
SoundState = STATE_TICK;
break;
case STATE_MIN15:
StartGens( (FMInitStruct*)&BELL1_INI, (FMDataStruct*)BELL1_DATA);
SoundState = STATE_SILENCE1;
SilenceNextState = STATE_TICK;
break;
case STATE_MIN30:
StartGens( (FMInitStruct*)&BELL2_INI, (FMDataStruct*)BELL2_DATA);
SoundState = STATE_SILENCE1;
SilenceNextState = STATE_TICK;
break;
case STATE_MIN45:
StartGens( (FMInitStruct*)&BELL3_INI, (FMDataStruct*)BELL3_DATA);
SoundState = STATE_SILENCE1;
SilenceNextState = STATE_TICK;
break;
case STATE_PREHOUR:
ChimeCount--;
if(2 == ChimeCount)
{
StartGens( (FMInitStruct*)&GONG_E_INI, (FMDataStruct*)GONG_E_DATA);
}
else if(1 == ChimeCount)
{
StartGens( (FMInitStruct*)&GONG_A_INI, (FMDataStruct*)GONG_A_DATA);
}
else if(0 == ChimeCount)
{
StartGens( (FMInitStruct*)&GONG_F_INI, (FMDataStruct*)GONG_F_DATA);
ChimeCount = LocalHoursCount;
SilenceNextState = STATE_HOURCHIMES;
SoundState = STATE_SILENCE2;
}
break;
case STATE_HOURCHIMES:
if(ChimeCount-- > 0)
{
if(SemB.Cuckoo)
{
StartGens( (FMInitStruct*)&CUCKOO_INI, (FMDataStruct*)CUCKOO_DATA);
}
else
{
StartGens( (FMInitStruct*)&GONG_C_INI, (FMDataStruct*)GONG_C_DATA);
SilenceNextState = STATE_HOURCHIMES;
SoundState = STATE_SILENCE1;
}
}
else
{
SilenceNextState = STATE_TICK;
SoundState = STATE_SILENCE2;
}
break;
case STATE_SILENCE2:
SoundState = STATE_SILENCE1;
break;
case STATE_SILENCE1:
SoundState = SilenceNextState;
break;
}
}
//产生新的语音采样输出
static fractional CreateNextSample( FMDataStruct* pDataStruct )
{
fractional sample;
fractional tmp1;
fractional tmp2;
static fractional test;
tmp1 = (pDataStruct+DataPos)->changepos;
if(0 == tmp1 )
{
SemA.SoundAct = FALSE;
return 0;
}
else if(SamplePos >= tmp1 )
{
DataPos++;
}
SamplePos++;
//计算波形产生器0
tmp1 = SIN_TBL[(unsigned int)(Generators[0].mphzacc)>>8];
Generators[0].mphzacc += Generators[0].mphzinc;
tmp1 = (long)( (long)Generators[0].mindex * (long)tmp1)>>16;
Generators[0].mindex += (pDataStruct+DataPos)->mslope0;
tmp1 += Generators[0].cphzacc;
Generators[0].cphzacc += Generators[0].cphzinc;
tmp2 = SIN_TBL[(unsigned int)tmp1>>8];
Generators[0].camp += (pDataStruct+DataPos)->caslope0;
test = (pDataStruct+DataPos)->caslope0;
sample = (long)( (long)tmp2 * (long)Generators[0].camp )>>16;
//计算波形产生器1
tmp1 = SIN_TBL[(unsigned int)(Generators[1].mphzacc)>>8];
Generators[1].mphzacc += Generators[1].mphzinc;
tmp1 = (long)( (long)Generators[1].mindex * (long)tmp1)>>16;
Generators[1].mindex += (pDataStruct+DataPos)->mslope1;
tmp1 += Generators[1].cphzacc;
Generators[1].cphzacc += Generators[1].cphzinc;
tmp2 = SIN_TBL[(unsigned int)tmp1>>8];
Generators[1].camp += (pDataStruct+DataPos)->caslope1;
tmp1 = (long)( (long)tmp2 * (long)Generators[1].camp )>>16;
sample += tmp1;
//计算波形产生器2
tmp1 = SIN_TBL[(unsigned int)(Generators[2].mphzacc)>>8];
Generators[2].mphzacc += Generators[2].mphzinc;
tmp1 = (long)( (long)Generators[2].mindex * (long)tmp1)>>16;
Generators[2].mindex += (pDataStruct+DataPos)->mslope2;
tmp1 += Generators[2].cphzacc;
Generators[2].cphzacc += Generators[2].cphzinc;
tmp2 = SIN_TBL[(unsigned int)tmp1>>8];
Generators[2].camp += (pDataStruct+DataPos)->caslope2;
tmp1 = (long)( (long)tmp2 * (long)Generators[2].camp )>>16;
sample += tmp1;
return sample;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -