对于RTTY 45.45波特,您还将拥有不是整数样本数量的符号,因此您需要一个可以被称为每个样本的函数,然后在该符号结束时发出其返回值的信号。而且,您需要一个相位累加器,使正弦波的相位保持一致。
要发送长度不是采样率整数倍的符号,您需要此功能...
int millisecondTimer(double milliseconds, double samplerate, int resettime)
{
static int fracsample=0;
static int counter=0;
static int retvalue=0;
static int first=1;
static double oldmilliseconds=1.0;
static int whole_samples=0;
static int samerror=32768;
if(resettime==1)
{
samerror=0;
counter=0;
retvalue=1;
first=1;
}
if(first==1 || milliseconds !=oldmilliseconds)
{
double samplesneeded=1;
double wholesamples=0;
samplesneeded=(samplerate) * (milliseconds /1000.0);
samerror=(modf(samplesneeded, &wholesamples)) * 32768.0;
whole_samples=wholesamples;
first=0;
}
if(counter<=whole_samples)
{
retvalue=2;
counter++;
}
else
{
counter-=whole_samples;
retvalue=1;
fracsample+=samerror;
oldmilliseconds=milliseconds;
if(fracsample>=32768)
{
fracsample-=32768;
counter--;
}
}
return retvalue;
}
要使用它,请生成下一个正弦波样本并调用此函数,然后检查返回值是否不等于2。如果它不等于2,则前进到下一个符号并确定是否要发送空格标记,然后在发现返回值不等于2时执行的代码块中再次调用此函数。
这是Rockbox固件的相位累加器,进行了更改以允许幅度变化(全音量为32767,异相全相位为180度为-32768)。
signed short lerpsin(float frequency,signed short amplitude,unsigned long samplerate)
{
/* 128 sixteen bit sine samples + guard point */
static unsigned long phase=0;
unsigned int pos =0;
unsigned short frac=0;
static unsigned long step=0;
static float old_frequency=0;
signed short diff=0;
static const signed short sinetab[129] =
{
0, 1607, 3211, 4807, 6392, 7961, 9511, 11038,
12539, 14009, 15446, 16845, 18204, 19519, 20787, 22004,
23169, 24278, 25329, 26318, 27244, 28105, 28897, 29621,
30272, 30851, 31356, 31785, 32137, 32412, 32609, 32727,
32767, 32727, 32609, 32412, 32137, 31785, 31356, 30851,
30272, 29621, 28897, 28105, 27244, 26318, 25329, 24278,
23169, 22004, 20787, 19519, 18204, 16845, 15446, 14009,
12539, 11038, 9511, 7961, 6392, 4807, 3211, 1607,
0, -1607, -3211, -4807, -6392, -7961, -9511, -11038,
-12539, -14009, -15446, -16845, -18204, -19519, -20787, -22004,
-23169, -24278, -25329, -26318, -27244, -28105, -28897, -29621,
-30272, -30851, -31356, -31785, -32137, -32412, -32609, -32727,
-32767, -32727, -32609, -32412, -32137, -31785, -31356, -30851,
-30272, -29621, -28897, -28105, -27244, -26318, -25329, -24278,
-23169, -22004, -20787, -19519, -18204, -16845, -15446, -14009,
-12539, -11038, -9511, -7961, -6392, -4807, -3211, -1607,
0,
};
if(frequency!=old_frequency)
{
step = 0x100000000ull*frequency / samplerate;
}
phase+=step;
pos = phase >> 25;
frac = (phase & 0x01ffffff) >> 9;
diff = sinetab[pos + 1] - sinetab[pos];
old_frequency=frequency;
return ((-((sinetab[pos] + (frac*diff >> 16)))) * amplitude) >> 15;
}