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

📄 dtmftesc.c

📁 arm ads1.2 with crack.rar
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Dual-Tone Multi-Frequency Tone Detect/Generate test harness
 * Copyright (C) ARM Limited 1998-1999. All rights reserved.
 */

#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "mtmfc.h"

#include "dtmftesc.h"

#include "bitutilc.h"
#include "custredc.h"
#include "definesc.h"
#include "fileutlc.h"
#include "optionsc.h"

#define	DTMF_OPTIONS	2

/* define the DTMF tones */
static const unsigned int DTMFTones[ 8 ] =	{
										697, /*   1	   2	 3	   A	*/
										770, /*   4	   5	 6	   B	*/
										852, /*   7	   8	 9	   C	*/
										941, /*   *	   0	 #	   D	*/
												1209, 1336, 1447, 1633
									} ;

/* define the DTMF values */
static const unsigned char DTMFValues[16] = 	{	
											'1', '2', '3', 'A',
											'4', '5', '6', 'B',
											'7', '8', '9', 'C',
											'*', '0', '#', 'D' 
										} ;

/* initialise memory for cosine and sines of DTMF tones */
static int DTMFCosines[ 9 ] ;
static int DTMFSines[ 9 ] ;

#define	NOISEFACTOR		( 1 << 11 )		/* maximum noise value used to scale random number to 0..NOISEFACTOR */
#define	SAMPLINGRATE	8000			/* the sampling rate in Hertz */
#define	SHIFT			15				/* the shift of cosine and sine values */
#define	TONEDISTINCTION	1				/* the distinction between valid tones and noise */
#define	MINMS			8				/* minimum number of milliseconds duration for tone, frequency or frame */
#define	FRAMESIZE		( SAMPLINGRATE/1000 )*MINMS		/* the default frame size in ms for sampling rate and min duration */

/* define tone generation structure to passing several pieces of information */
typedef struct	DTMFToneGenStruct	DTMFToneGenStruct ;
typedef			DTMFToneGenStruct	*DTMFToneGenStructPtr ;

struct DTMFToneGenStruct {
	unsigned int	toneperiod ;
	unsigned int	silenceperiod ;
	unsigned int	period ;
	unsigned int	hitonelevel ;
	unsigned int	lotonelevel ;
	unsigned int	framesize ;
} ;

/* define a type to identify whether to detect a tone or silence */
typedef enum{ TONE, SILENCE } ToneSilence ;

static Boolean DTMFTableGen( int table[ ], unsigned int samplingRate, unsigned int shift, double( *trig )( double ) ) ;
static Boolean DTMFValid( unsigned char dtmfValues[ ], unsigned int nValues ) ;
static short *GenerateDTMFSamples( unsigned char values[ ], unsigned int nValues, DTMFToneGenStructPtr dtmfToneGenStructPtr, Boolean noise, short samples[ ], unsigned int *nSamples ) ;
static void Menu( unsigned int numberOptions ) ;
static void PrintNumberPad( void ) ;
static ToneState *SetDTMFTones( ToneState toneStates[ ], unsigned char value, unsigned int lotonelevel, unsigned int hitonelevel, Boolean noise ) ;

/**** DetectDTMFTone ****************************************************************
 *
 * Version & Date
 * -------   ----
 * 1.0.0, 30/06/1998
 *
 * Description
 * -----------
 * detect the next DTMF tone or silence in the given set of samples
 *
 * Inputs
 * ------
 *   samples
 *   - the set of samples to detect tone or silence in
 *   nSamples
 *   - the number of samples in the set to detect tone or silence in
 *   toneSilence
 *   - TONE    : detect a DTMF tone 0-9, a-d (or A-D), * and #
 *     SILENCE : detect silence
 *   toneDistinction
 *   - the number of bits to right shift the energies to distinguish a tone from
 *     background noise
 * Return Values
 * ------ ------
 *     if TONE
 *      unsigned char - the tone detected 0-9, A-D, * or #
 *      0             - no tone was detected
 *     if SILENCE
 *      1             - silence detected
 *      0             - no silence period detected
 *
 * History (with dates)
 * -------  ---- -----
 * 1.0.0, 30/06/1998    first release
 *
 ************************************************************************************/
static unsigned char DetectDTMFTone( short samples[ ], unsigned int nSamples, ToneSilence toneSilence, unsigned int toneDistinction )
{
	unsigned int	loMax = 0 ;
	unsigned int	hiMax = 0 ;
	int				loTone = -1 ;
	int				hiTone = -1 ;
	ToneState		toneStates[ 8 ] ;
	unsigned int	energies[ 8 ] ;
	unsigned int	i ;
	unsigned char	tone = 0 ;
	
	if( ( !samples ) || ( nSamples == 0 ) ) {
		fprintf( stderr, "[DetectDTMFTone] Error in input arguments, aborting.\n\n" ) ;
		return 0 ;
	}
	
	ToneDetectSetup( toneStates, ( int * )DTMFCosines, 8 ) ;
	ToneDetect( samples, nSamples, toneStates, 8 ) ;
	ToneDetectResults( energies, 2, toneStates, 8 ) ;
	
	for( i = 0 ; i < 4 ; i += 1 ) {
		if( ( energies[ i ] >> toneDistinction ) > loMax ) {		/* tone must be (1<<toneDistinction) greater than any other tone */
			loMax = energies[ i ] ;
			loTone = i ;
		}
		else if( ( loMax >> toneDistinction ) < energies[ i ] ) {	/* energy is within (1<<toneDistinction), previous max tone is not valid tone */
			loTone = -1 ;
			if( loMax < energies[ i ] ) {
				loMax = energies[ i ] ;
			}
		}
		if( ( energies[ i + 4 ] >> toneDistinction ) > hiMax ) {
			hiMax = energies[ i + 4 ] ;
			hiTone = i ;
		}
		else if( ( hiMax >> toneDistinction ) < energies[ i + 4 ] ) {
			hiTone = -1 ;
			if( hiMax < energies[ i + 4 ] ) {
				hiMax = energies[ i + 4 ] ;
			}
		}
	}
		
	/* ensure that both tones are close to each other */
	if( ( loMax < ( hiMax >> 1 ) ) || ( hiMax < ( loMax >> 1 ) ) ) {
		loTone = hiTone = -1 ;
	}
	
	tone = 0 ;
	if( ( loTone != -1 ) && ( hiTone != -1 ) ) {
		if( toneSilence == TONE ) {
			tone = DTMFValues[ hiTone + ( loTone << 2 ) ] ;
		}
	}
	else if( toneSilence == SILENCE ) {
		tone = 1 ;
	}
	
	return tone ;
}

/**** DetectDTMFTones ***************************************************************
 *
 * Version & Date
 * -------   ----
 * 1.0.0, 30/06/1998
 *
 * Description
 * -----------
 * detect all the tones and silences in the given set of samples
 *
 * Inputs
 * ------
 *   samples
 *   - the set of samples to detect tones and silence in
 *   nSamples
 *   - the number of samples in the set to detect tones and silence in
 *   framesize
 *   - the size of the frame to detect tones in
 *     must be of sufficient size to allow energies to be accumulated and
 *     small enough to allow short duration of tone or silence to be detected
 *   toneDistinction
 *   - the number of bits to right shift the energies to distinguish a tone from
 *     background noise
 *   fulldetails
 *   - 1 : give samples where tone detected, silence detected or nothing detected
 *     0 : only give tones and silence detected and now by which samples or if nothing detected
 *   dtmfTones
 *   - an array to hold the tones detected
 *   maxTones
 *   - the maximum number of tones that can be detected before array exhausted
 * Outputs
 * -------
 *   dtmfTones
 *   - the tones detected if non-NULL returned
 *   maxTones
 *   - the number of tones detected if non-NULL returned
 * Return Values
 * ------ ------
 *     unsigned char * - a pointer to dtmfTones if tones detected
 *     NULL			   - some error occurred
 *
 * History (with dates)
 * -------  ---- -----
 * 1.0.0, 30/06/1998    first release
 *
 ************************************************************************************/
static unsigned char *DetectDTMFTones( short samples[ ], unsigned int nSamples, unsigned int framesize, unsigned int toneDistinction, unsigned int fulldetails, unsigned char dtmfTones[ ], unsigned int *maxTones )
{
	ToneSilence		toneSilence = TONE ;
	unsigned char	tone ;
	unsigned int	i ;
	unsigned int	j ;
	
	if( ( !samples ) || ( nSamples == 0 ) || ( framesize == 0 ) || ( !dtmfTones ) || ( !maxTones ) || ( *maxTones == 0 ) ) {
		fprintf( stderr, "[DetectDTMFTones] Error in input arguments, aborting.\n\n" ) ;
		return NULL ;
	}
	
	printf( "Using a %ums framesize, the DTMF values detected are :\n\n", ( framesize*1000 )/SAMPLINGRATE ) ;
	
	j = 0 ;
	for( i = 0 ; i < nSamples ; i += framesize ) {
		if( ( tone = DetectDTMFTone( samples + i, framesize, toneSilence, toneDistinction ) ) != 0 ) {
			printf( "\t" ) ;
			if( toneSilence == TONE ) {
				printf( "'%c' ", tone ) ;
				dtmfTones[ j++ ] = tone ;
				if( j == *maxTones ) {
					break ;
				}
				toneSilence = SILENCE ;
			}
			else {
				printf( "silence " ) ;
				toneSilence = TONE ;
			}
			if( fulldetails ) {
				printf( "in samples %u to %u.\n", i, i + framesize ) ;
			}
			else {
				printf( "\n" ) ;
			}
		}
	}
	printf( "\n" ) ;
	*maxTones = j ;
	
	return dtmfTones ;
}

/**** DTMF **************************************************************************
 *
 * Version & Date
 * -------   ----
 * 1.0.0, 30/06/1998
 *
 * Description
 * -----------
 * perform a DTMF generation or detection
 *
 * generation:
 * get user information for DTMF values to generate waveform for, framesize to use
 * duration of tones and silence and peak values, generate discrete waveform samples
 * and save to a file given by the user
 *
 * detection:
 * read a file given by the user and using the framesize given by the user try to
 * detect DTMF values and silence
 *
 * Inputs
 * ------
 *   option
 *   - a value that should be between 1 and 2 and returned from a call to NextTask
 *     the value corresponds to a menu choice and determines whether generating or detecting
 *     (respectively)
 * Return Values
 * ------ ------
 *     TRUE  - the process was successful
 *     FALSE - some error occurred during process (memory problems?)
 *
 * History (with dates)
 * -------  ---- -----
 * 1.0.0, 30/06/1998    first release
 *
 ************************************************************************************/
static Boolean DTMF( unsigned int option )
{	
	DTMFToneGenStruct	dtmfToneGenStruct ;
	unsigned char		dtmfTones[ LIMIT ] ;
	unsigned int		nTones = LIMIT ;
	short				*samples = NULL ;
	unsigned int		framesize = FRAMESIZE ;
	unsigned int		nSamples ;
	unsigned int		is2 ;
	Boolean				noise ;
	unsigned int		i ;
	
	printf( "Perform DTMF...\n\n" ) ;
	
	if( option == 666 ) {
		printf( "Instigating hidden option: generate & detect DTMF.\n\n" ) ;
	}
	
	switch( option ) {
		case 1 :
		case 666 :
			do {
				printf( "Please give the DTMF values to generate.\n\n" ) ;
				PrintNumberPad( ) ;
				printf( "Values (0-9, A-D, *, #) : " ) ;
				ReadInString( stdin, ( char * )dtmfTones, LIMIT ) ;
				printf( "\n" ) ;
			} while( !DTMFValid( dtmfTones, strlen( ( char * )dtmfTones ) ) ) ;
			break ;
		case 2 :
			if( ( samples = ( short * )GetData( HWORDBYTES, "DTMF detection", &nSamples ) ) == NULL ) {
				return FALSE ;
			}
			break ;
		default :
			return TRUE ;
	}
	
	switch( option ) {
		case 1 :
		case 666 :
			/* define an example framesize to show multiple calls to generate the samples */
			dtmfToneGenStruct.framesize = FRAMESIZE ;
			
			/* get values as power of 2 to ease complexity in detector */
			printf( "Please give the duration of the tones.\n\n" ) ;
			do {
				printf( "Duration of tones (milliseconds, minimum %ums, power of 2) : ", MINMS ) ;
				dtmfToneGenStruct.toneperiod = ( int )ReadDouble( ) ;
				ISPOWEROF2( dtmfToneGenStruct.toneperiod, is2 ) ;
				if( !is2 ) {
					fprintf( stderr, "Value '%u' is not a power of 2.\n\n", dtmfToneGenStruct.toneperiod ) ;
				}
				else if( dtmfToneGenStruct.toneperiod < MINMS ) {
					fprintf( stderr, "Value '%u' is less than %u.\n\n", dtmfToneGenStruct.toneperiod, MINMS ) ;
				}
				else {
					break ;
				}
			} while( 1 ) ;
			dtmfToneGenStruct.toneperiod = ( int )( ( ( double )dtmfToneGenStruct.toneperiod/1000.0 )*( double )SAMPLINGRATE + 0.5 ) ;
			
			printf( "Please give the duration of silence between tones.\n\n" ) ;
			do {
				printf( "Duration of silence (milliseconds, minimum %ums, power of 2) : ", MINMS ) ;
				dtmfToneGenStruct.silenceperiod = ( int )ReadDouble( ) ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -