📄 dtmftesc.c
字号:
* Inputs
* ------
* value
* - a character value from the set 0-9, a-d (or A-D), * and # to generate DTMF samples for
* or 0 if silence should be generated
* dtmfToneGenStructPtr
* - a pointer to an initialised DTMFToneGenStruct that contains values to use
* noise
* - TRUE : add random noise to generated samples
* FALSE : do not add noise to generated samples
* samples
* - an array to hold the discrete samples of the waveform generated
* Outputs
* -------
* samples
* - the discrete samples generated if non-NULL returned
* Return Values
* ------ ------
* short * - a pointer to the next location in the array 'samples' after the last generated sample
* NULL - some error occurred
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
static short *GenerateDTMFForValue( unsigned char value, DTMFToneGenStructPtr dtmfToneGenStructPtr, Boolean noise, short samples[ ] )
{
short *outputs = samples ;
unsigned int nSGenerate = 0 ;
ToneState toneStates[ 2 ] ;
unsigned int samplesRemaining = 0 ;
unsigned int period ;
if( ( !dtmfToneGenStructPtr ) || ( dtmfToneGenStructPtr->framesize == 0 ) || ( !samples ) ) {
fprintf( stderr, "[GenerateDTMFForTone] Error in input arguments, aborting.\n\n" ) ;
return NULL ;
}
value = ( unsigned char )toupper( value ) ;
printf( "\t" ) ;
if( value ) {
printf( "'%c'", value ) ;
}
else {
printf( "silence" ) ;
}
printf( "\n" ) ;
period = dtmfToneGenStructPtr->period ;
SetDTMFTones( toneStates, value, dtmfToneGenStructPtr->lotonelevel, dtmfToneGenStructPtr->hitonelevel, noise ) ;
while( period ) {
if( samplesRemaining == 0 ) {
samplesRemaining = dtmfToneGenStructPtr->framesize ;
}
if( period < samplesRemaining ) {
nSGenerate = period ;
}
else {
nSGenerate = samplesRemaining ;
}
if( ( outputs = ToneGenerate( outputs, nSGenerate, toneStates, 2 ) ) == NULL ) {
return NULL ;
}
samplesRemaining -= nSGenerate ;
period -= nSGenerate ;
}
return outputs ;
}
/**** GenerateDTMFSamples ***********************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* generate a set of discrete samples from the waveforms to represent the DTMF tones for
* given values and silence between each DTMF tone
*
* Inputs
* ------
* values
* - an array of character values from the set 0-9, a-d (or A-D), * and # to generate DTMF samples for
* silence will be generated after each tone
* nValues
* - the number of values to generate DTMF tones from
* dtmfToneGenStructPtr
* - a pointer to an initialised DTMFToneGenStruct that contains values to use
* noise
* - TRUE : add random noise to generated samples
* FALSE : do not add noise to generated samples
* samples
* - an array to hold the discrete samples of the waveforms generated
* nSamples
* - a pointer to integer to hold the number of samples generated
* Outputs
* -------
* samples
* - the discrete samples generated if non-NULL returned
* nSamples
* - a pointer to the number of samples generated if non-NULL generated
* Return Values
* ------ ------
* short * - a pointer to the next location in the array 'samples' after the last generated sample
* NULL - some error occurred
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
static short *GenerateDTMFSamples( unsigned char values[ ], unsigned int nValues, DTMFToneGenStructPtr dtmfToneGenStructPtr, Boolean noise, short samples[ ], unsigned int *nSamples )
{
short *outputs = samples ;
unsigned int i ;
if( ( !dtmfToneGenStructPtr ) ||
( ( dtmfToneGenStructPtr->toneperiod == 0 ) && ( dtmfToneGenStructPtr->silenceperiod == 0 ) ) ||
( !nSamples )
) {
fprintf( stderr, "[GenDTMFSamples] Error in input arguments, aborting.\n\n" ) ;
return NULL ;
}
printf( "Generating DTMF samples " ) ;
if( noise ) {
printf( "(with noise) " ) ;
}
printf( "for :\n\n" ) ;
*nSamples = 0 ;
for( i = 0 ; i < nValues ; i += 1 ) { /* for each value, generate tone followed by silence */
dtmfToneGenStructPtr->period = dtmfToneGenStructPtr->toneperiod ;
if( ( outputs = GenerateDTMFForValue( values[ i ], dtmfToneGenStructPtr, noise, outputs ) ) == NULL ) {
return NULL ;
}
dtmfToneGenStructPtr->period = dtmfToneGenStructPtr->silenceperiod ;
if( ( outputs = GenerateDTMFForValue( 0, dtmfToneGenStructPtr, noise, outputs ) ) == NULL ) {
return NULL ;
}
*nSamples += dtmfToneGenStructPtr->toneperiod + dtmfToneGenStructPtr->silenceperiod ;
}
printf( "\nDTMF samples generated.\n\n" ) ;
return outputs ;
}
/**** Menu **************************************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* print the menu of options to the screen (defined in standard way for NextTask
* function and will be called by NextTask)
*
* Inputs
* ------
* numberOptions
* - the number of menu options that should be printed
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
static void Menu( unsigned int numberOptions )
{
if( numberOptions == DTMF_OPTIONS ) {
printf( " 1. Generate DTMF.\n" ) ;
printf( " 2. Detect DTMF.\n" ) ;
}
else {
fprintf( stderr, "[Menu] Error in arguments, aborting.\n\n" ) ;
/* function name given since intended as internal error for programmer */
}
}
/**** PrintNumberPad ****************************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* print the DTMF value number pad to the screen
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
static void PrintNumberPad( void )
{
printf( "\t ___ \t ___ \t ___ \t ___\n" ) ;
printf( "\t| 1 |\t| 2 |\t| 3 |\t| A |\n" ) ;
printf( "\n" ) ;
printf( "\t ___ \t ___ \t ___ \t ___\n" ) ;
printf( "\t| 4 |\t| 5 |\t| 6 |\t| B |\n" ) ;
printf( "\n" ) ;
printf( "\t ___ \t ___ \t ___ \t ___\n" ) ;
printf( "\t| 7 |\t| 8 |\t| 9 |\t| C |\n" ) ;
printf( "\n" ) ;
printf( "\t ___ \t ___ \t ___ \t ___\n" ) ;
printf( "\t| * |\t| 0 |\t| # |\t| D |\n" ) ;
printf( "\n" ) ;
printf( "\n" ) ;
}
/**** SetDTMFTones ******************************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* generate a set of discrete samples from the waveforms to represent the DTMF tones for
* given values and silence between each DTMF tone
*
* Inputs
* ------
* toneStates
* - an array of two ToneState structures to initialise for the two tones of the DTMF value
* value
* - a character value from the set 0-9, a-d (or A-D), * and # to generate DTMF samples for
* or 0 if silence should be generated
* lotonelevel
* - the peak value for the low tone of the DTMF value
* hitonelevel
* - the peak value for the high tone of the DTMF value
* noise
* - TRUE : add random noise to tones
* FALSE : do not add noise to tones
* Outputs
* -------
* toneStates
* - an array of two initialised ToneState structures for the DTMF tones of the given value
* if non-NULL returned
* Return Values
* ------ ------
* ToneState * - a pointer to the initialised ToneStates
* NULL - some error occurred
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
static ToneState *SetDTMFTones( ToneState toneStates[ ], unsigned char value, unsigned int lotonelevel, unsigned int hitonelevel, Boolean noise )
{
unsigned int max = ( 1 << SHIFT ) - 1 ;
unsigned int lotone ;
unsigned int hitone ;
unsigned int random ;
int cosine ;
int sine ;
if( !toneStates ) {
fprintf( stderr, "[SetDTMFTones] Error in input arguments, aborting.\n\n" ) ;
return NULL ;
}
switch( value ) {
case '#' :
lotone = 3 ; /* 941 */
hitone = 6 ; /* 1447 */
break ;
case '*' :
lotone = 3 ; /* 941 */
hitone = 4 ; /* 1209 */
break ;
case '0' :
lotone = 3 ; /* 941 */
hitone = 5 ; /* 1336 */
break ;
case '1' :
case '2' :
case '3' :
lotone = 0 ; /* 697 */
hitone = value - '1' + 4 ;
break ;
case '4' :
case '5' :
case '6' :
lotone = 1 ; /* 770 */
hitone = value - '4' + 4 ;
break ;
case '7' :
case '8' :
case '9' :
lotone = 2 ; /* 852 */
hitone = value - '7' + 4 ;
break ;
case 'A' :
case 'B' :
case 'C' :
case 'D' :
case 'a' :
case 'b' :
case 'c' :
case 'd' :
lotone = ( value & 0x5F ) - 'A' ;
hitone = 7 ; /* 1633 */
break ;
default : /* silence */
lotone = 8 ;
hitone = 8 ;
break ;
}
random = rand( )%NOISEFACTOR ;
if( noise ) {
cosine = DTMFCosines[ lotone ] + random ;
if( cosine > max ) {
cosine = max ;
}
sine = DTMFSines[ lotone ] + random ;
if( sine > max ) {
sine = max ;
}
}
else {
cosine = DTMFCosines[ lotone ] ;
sine = DTMFSines[ lotone ] ;
}
ToneGenerateSetup( toneStates, cosine, sine, lotonelevel ) ;
if( noise ) {
cosine = DTMFCosines[ hitone ] + random ;
if( cosine > max ) {
cosine = max ;
}
sine = DTMFSines[ hitone ] + random ;
if( sine > max ) {
sine = max ;
}
}
else {
cosine = DTMFCosines[ hitone ] ;
sine = DTMFSines[ hitone ] ;
}
ToneGenerateSetup( toneStates + 1, cosine, sine, hitonelevel ) ;
return toneStates ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -