📄 dtmftesc.c
字号:
ISPOWEROF2( dtmfToneGenStruct.silenceperiod, is2 ) ;
if( !is2 ) {
fprintf( stderr, "Value '%u' is not a power of 2.\n\n", dtmfToneGenStruct.silenceperiod ) ;
}
else if( dtmfToneGenStruct.silenceperiod < MINMS ) {
fprintf( stderr, "Value '%u' is less than %u.\n\n", dtmfToneGenStruct.silenceperiod, MINMS ) ;
}
else {
break ;
}
} while( 1 ) ;
dtmfToneGenStruct.silenceperiod = ( int )( ( ( double )dtmfToneGenStruct.silenceperiod/1000.0 )*( double )SAMPLINGRATE + 0.5 ) ;
printf( "Please give the peak value for the DTMF tones.\n\n" ) ;
do {
printf( "Peak of DTMF tones (power of 2) : " ) ;
dtmfToneGenStruct.lotonelevel = ( int )ReadDouble( ) ;
ISPOWEROF2( dtmfToneGenStruct.lotonelevel, is2 ) ;
if( is2 ) {
break ;
}
fprintf( stderr, "Value '%d' is not a power of two.\n\n", dtmfToneGenStruct.lotonelevel ) ;
} while( 1 ) ;
dtmfToneGenStruct.hitonelevel = dtmfToneGenStruct.lotonelevel ;
printf( "Random noise can be added to the generated values but this may stop the DTMF tones from being detectable.\n\n" ) ;
if( YesNo( "Add noise to DTMF tones", "add noise", "don't add noise" ) ) {
noise = TRUE ;
}
else {
noise = FALSE ;
}
nSamples = strlen( ( char * )dtmfTones )*( dtmfToneGenStruct.toneperiod + dtmfToneGenStruct.silenceperiod ) ;
if( ( samples = ( short * )calloc( nSamples, sizeof( short ) ) ) == NULL ) {
fprintf( stderr, "Cannot allocate memory for data, aborting.\n\n" ) ;
return FALSE ;
}
if( !GenerateDTMFSamples( dtmfTones, strlen( ( char * )dtmfTones ), &dtmfToneGenStruct, noise, samples, &nSamples ) ) {
free( ( void * ) samples ) ;
return FALSE ;
}
break ;
default :
break ;
}
switch( option ) {
case 1 :
SaveData( samples, nSamples, HWORDBYTES, 0, "generated DTMF" ) ;
break ;
case 666 :
printf( "Please give the size of the frame that determines the number of samples to search for\n" ) ;
printf( "a tone or silence.\n\n" ) ;
printf( "The frame size must not be greater than the minimum of the duration of the tones and\n" ) ;
printf( "the duration of the silence.\n\n" ) ;
printf( "For example if tone duration = 32ms, silence = 16ms then 8ms <= frame size <= 16ms.\n\n" ) ;
do {
printf( "Size of frame (milliseconds, minimum %ums, power of 2) : ", MINMS ) ;
framesize = ( int )ReadDouble( ) ;
ISPOWEROF2( framesize, is2 ) ;
if( !is2 ) {
fprintf( stderr, "Value '%u' is not a power of 2.\n\n", framesize ) ;
}
else if( framesize < MINMS ) {
fprintf( stderr, "Value '%u' is less than %u.\n\n", framesize, MINMS ) ;
}
else {
break ;
}
} while( 1 ) ;
framesize = ( int )( ( ( double )framesize/1000.0 )*( double )SAMPLINGRATE + 0.5 ) ;
/* drop through to continue */
case 2 :
DetectDTMFTones( samples, nSamples, framesize, TONEDISTINCTION, option == 666, dtmfTones, &nTones ) ;
if( option == 666 ) {
printf( "Detected tones :\n\n" ) ;
for( i = 0 ; i < nTones ; i += 1 ) {
printf( "'%c' ", dtmfTones[ i ] ) ;
if( ( i > 0 ) && ( i%32 == 0 ) ) {
printf( "\n" ) ;
}
}
if( i%32 != 0 ) {
printf( "\n\n" ) ;
}
else {
printf( "\n" ) ;
}
}
break ;
default :
break ;
}
free( ( void * ) samples ) ;
if( option == 666 ) {
printf( "Finished hidden option.\n\n" ) ;
}
return TRUE ;
}
/**** dtmf_main *********************************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* initialise the application then loop whilst the user is still working
*
* Return Values
* ------ ------
* 0 - application terminated correctly
* 1 - some error occurred
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
int dtmf_main( int argc, char **argv )
{
unsigned int option = 0 ;
#ifdef __BIG_ENDIAN
char newStdIn[ ] = "stdinb" ;
char newStdOut[ ] = "stdoutb" ;
char newStdErr[ ] = "stderrb" ;
#else
char newStdIn[ ] = "stdinl" ;
char newStdOut[ ] = "stdoutl" ;
char newStdErr[ ] = "stderrl" ;
#endif
unsigned int stdio = 0 ;
if( ChangeStdIO( &argc, &argv, newStdIn, stdin ) == STDINID ) {
stdio |= ( 1 << STDINID ) ;
}
if( ChangeStdIO( &argc, &argv, newStdOut, stdout ) == STDOUTID ) {
stdio |= ( 1 << STDOUTID ) ;
}
if( ChangeStdIO( &argc, &argv, newStdErr, stderr ) == STDERRID ) {
stdio |= ( 1 << STDERRID ) ;
}
printf( "Program to test Multi-Tone Multi-Frequency (MTMF) generation and detection\n" ) ;
printf( "using Dual-Tone Multi-Frequency (DTMF) as an example.\n\n" ) ;
printf( "This application generates and detects 16-bit fixed-point DTMF data with the\n" ) ;
printf( "point between bits 14 and 15.\n\n" ) ;
DTMFTableGen( DTMFCosines, SAMPLINGRATE, SHIFT, &cos ) ;
DTMFTableGen( DTMFSines, SAMPLINGRATE, SHIFT, &sin ) ;
while( 1 ) {
if( ( option = NextTask( DTMF_OPTIONS, &Menu ) ) == 0 ) {
break ;
}
DTMF( option ) ;
}
/* redirection based on trying to open files that don't exist do using defaults */
if( stdio & ( 1 << STDINID ) ) {
ResetStdIO( stdin ) ;
}
if( stdio & ( 1 << STDOUTID ) ) {
ResetStdIO( stdout ) ;
}
if( stdio & ( 1 << STDERRID ) ) {
ResetStdIO( stderr ) ;
}
return 0 ;
}
/**** DTMFTableGen ******************************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* generate a constant table of DTMF trigonometric tones where
* tone is cosTheta or sinTheta (given by trig function) and
* Theta = 2 * pi * DTMFTone / sampling rate
*
* the resulting trig tone is shifted into fixed-point value
*
* a trig tone for silence as the last element is also created
*
* Inputs
* ------
* table
* - an array of 9 entries for the 8 DTMF tones and 1 for silence
* samplingRate
* - the sampling rate for the entries e.g. 8000 Hz
* shift
* - the fixed-point shift e.g. 15 to create 16-bit fixed-point values with the
* bit between bits 14 and 15
* trig
* - a pointer to either the C cosine or C sine functions
* Outputs
* -------
* table
* - a table of 8 trigonometric DTMF tones and 1 silence tone
* Return Values
* ------ ------
* TRUE - the DTMF trigonometric tones have been created, table is valid
* FALSE - table is invalid, some error occurred
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
static Boolean DTMFTableGen( int table[ ], unsigned int samplingRate, unsigned int shift, double( *trig )( double ) )
{
unsigned int i ;
double theta ;
if( ( !table ) || ( samplingRate == 0 ) || ( !trig ) ) {
fprintf( stderr, "[DTMFTableGen] Error in input arguments, aborting.\n\n" ) ;
return FALSE ;
}
for( i = 0 ; i < 8 ; i += 1 ) {
theta = ( 2.0 * PI * ( double )DTMFTones[ i ] )/( double )samplingRate ;
table[ i ] = ( int )( ( *trig )( theta )*( ( double )( ( int )( 1 << shift ) ) ) ) ;
}
table[ 8 ] = 0 ; /* add silence as last entry */
return TRUE ;
}
/**** DTMFValid *********************************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* determine if the given string of DTMF tones is valid in that it only contains
* 0-9, a-d (or A-D), * and #
*
* all other values are unacceptable and a list of any unacceptable values are given
* to the user
*
* Inputs
* ------
* dtmfValues
* - a string of DTMF values to check for validity
* nValues
* - the number of DTMF values to check in the string from starting address given
* Return Values
* ------ ------
* TRUE - the DTMF values are valid
* FALSE - some, or all, of the DTMF values are incorrect... reject the set
*
* History (with dates)
* ------- ---- -----
* 1.0.0, 30/06/1998 first release
*
************************************************************************************/
static Boolean DTMFValid( unsigned char dtmfValues[ ], unsigned int nValues )
{
Boolean valid = TRUE ;
unsigned char dataarea[ 256 ] = "" ;
unsigned char *invalids = dataarea ;
unsigned int nInvalids = 0 ;
unsigned int i ;
for( i = 0 ; i < nValues ; i += 1 ) {
switch( dtmfValues[ i ] ) {
case '#' :
case '*' :
case '0' :
case '1' :
case '2' :
case '3' :
case '4' :
case '5' :
case '6' :
case '7' :
case '8' :
case '9' :
case 'A' :
case 'B' :
case 'C' :
case 'D' :
case 'a' :
case 'b' :
case 'c' :
case 'd' :
break ;
default :
/* only include value once and alphabetically */
if( !invalids[ dtmfValues[ i ] ] ) {
nInvalids += 1 ;
invalids[ dtmfValues[ i ] ] = dtmfValues[ i ] ;
}
valid = FALSE ;
break ;
}
}
/* print all invalid DTMF values given in a "case sensitive" way */
if( !valid ) {
i = 0 ;
if( nInvalids > 1 ) {
while( i < nInvalids - 2 ) {
while( !*invalids ) {
invalids += 1 ;
}
printf( "'%c', ", *invalids++ ) ;
i += 1 ;
}
while( !*invalids ) {
invalids += 1 ;
}
printf( "'%c' and ", *invalids++ ) ;
}
while( !*invalids ) {
invalids += 1 ;
}
printf( "'%c' ", *invalids++ ) ;
if( nInvalids > 1 ) {
printf( "are not" ) ;
}
else {
printf( "is not a" ) ;
}
printf( " valid DTMF value" ) ;
if( nInvalids > 1 ) {
printf( "s" ) ;
}
printf( ".\n\n" ) ;
}
return valid ;
}
/**** GenerateDTMFForValue **********************************************************
*
* Version & Date
* ------- ----
* 1.0.0, 30/06/1998
*
* Description
* -----------
* generate a set of discrete samples from the waveform to represent the DTMF tone for
* given value or silence
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -