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

📄 soundgen.c

📁 dspic开发控制程序,有助开发pic单片机程序
💻 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 + -