/* SigLib - DTMF Generation Example Freq. (Hz) 1209 1336 1477 1633 697 1 2 3 A 770 4 5 6 B 852 7 8 9 C 941 * 0 # D */ #include #include #include #include #include "nhl.h" /* Define constants */ #define MAX_SAMPLE_LENGTH ((SLArrayIndex_t)4000) #define SAMPLE_RATE ((SLData_t)8000.0) #define SAMPLES_PER_MS ((SLArrayIndex_t)(SAMPLE_RATE / 1000.0)) #define DETECTION_THRESHOLD ((SLData_t)1000.0) #define DTMF_SAMPLE_LENGTH 102L /* Declare arrays and variables */ SLData_t *pData; /* DTMF data */ SLData_t *pDTMFDetectState; /* DTMF detector state */ SLData_t *pDTMFGenCoeffs; /* DTMF generator frequency look up table */ WAV_FILE_INFO WavInfo; char TextSrcFilename[] = "dtmf.txt"; FILE *pInputFile; char WavDstFilename[] = "dtmf.wav"; FILE *pOutputFile; void main(void); int read_dtmf_key (char *pTone, SLFixData_t *pPeriod, SLData_t *pMagnitude); void main (void) { char Tone; SLFixData_t Period; SLData_t Magnitude; long FileLength = 0; SLStatus_t KeyCode; SLFixData_t SampleCount; SLStatus_t PreviousKeyCode = SIGLIB_NO_DTMF_SIGNAL; /* Initialise to no DTMF key detected */ SLFixData_t KeyCodeLength = 0; /* Length of key code stream */ SLFixData_t KeyCodeRegistered = SIGLIB_FALSE; /* A key code has not been registered */ SLFixData_t PreviousKeyCodeLength = 0L; SLData_t LinearDTMFMagnitude; SLData_t Max = SIGLIB_ZERO; SLData_t NewMax = SIGLIB_ZERO; pData = SUF_VectorArrayAllocate (MAX_SAMPLE_LENGTH); pDTMFDetectState = SUF_VectorArrayAllocate (SIGLIB_GOERTZEL_DELAY_LENGTH); pDTMFGenCoeffs = SUF_VectorArrayAllocate (SIGLIB_DTMF_FTABLE_LENGTH); if ((pInputFile = fopen(TextSrcFilename, "r")) == NULL) { printf ("Can not open input data file %s\n", TextSrcFilename); exit (0); } if ((pOutputFile = fopen(WavDstFilename, "wb")) == NULL) { printf ("Can not open output data file %s\n", WavDstFilename); exit (0); } WavInfo = wav_set_info ((long)8000, (long)FileLength, (short)1, (short)16, (short)2, (short)1); wav_write_header (pOutputFile, WavInfo); SIF_DtmfGenerate (pDTMFGenCoeffs, /* Generator coefficient look up table pointer */ SAMPLE_RATE); /* Sample rate */ while (read_dtmf_key (&Tone, &Period, &Magnitude) == 0) /* While there are key codes */ { LinearDTMFMagnitude = SDS_dBmToLinear (Magnitude, (SLData_t)32767.0) / SIGLIB_TWO; /* Note divide by two necessary for SDA_DtmfGenerate () */ printf ("Tone = %c, Period = %ld (ms), Magn. = %lf (dB), Lin. Magn. = %lf\n", Tone, Period, Magnitude, LinearDTMFMagnitude); if (Tone == 'S') { SDA_Clear (pData, /* Pointer to destination array */ Period*SAMPLES_PER_MS); /* Array length */ } else { SDA_DtmfGenerate (pData, /* Destination array pointer */ SUF_AsciiToKeyCode (Tone), /* Key code */ LinearDTMFMagnitude, /* Signal magnitude */ pDTMFGenCoeffs, /* Generator coefficient look up table pointer */ Period*SAMPLES_PER_MS); /* Array length */ } wav_write_data (pData, pOutputFile, WavInfo, Period*SAMPLES_PER_MS); FileLength += Period*SAMPLES_PER_MS; } printf ("DTMF signal has been generated\nPlease hit to decode . . .\n"); getchar(); /* Now update the header to indicate the filelength */ WavInfo = wav_set_info ((long)8000, (long)FileLength, (short)1, (short)16, (short)2, (short)1); rewind (pOutputFile); wav_write_header (pOutputFile, WavInfo); fclose (pInputFile); fclose (pOutputFile); /* We have generated the DTMF file now we will detect the contents */ if ((pInputFile = fopen(WavDstFilename, "rb")) == NULL) /* Note this file is binary */ { printf ("Error opening input .WAV file\n"); exit (1); } WavInfo = wav_read_header (pInputFile); if (WavInfo.NumberOfChannels == 0) /* Check how many channels */ { printf ("Error reading .WAV file header\n"); exit (1); } wav_display_info (WavInfo); printf ("\n.WAV file data. '.' indicates no tone present\n"); printf (" '-' indicates signal present but not DTMF\n\n"); SIF_DtmfDetect (pDTMFDetectState, /* Pointer to filter state array */ ((SLData_t)WavInfo.SampleRate), /* Sample rate */ DTMF_SAMPLE_LENGTH); /* Array length */ while ((SampleCount = wav_read_data (pData, pInputFile, WavInfo, DTMF_SAMPLE_LENGTH)) == DTMF_SAMPLE_LENGTH) { NewMax = SDA_Max (pData, DTMF_SAMPLE_LENGTH); /* Detect the peak value of the DTMF signal */ if (NewMax > Max) Max = NewMax; KeyCode = SDA_DtmfDetectAndValidate (pData, /* Source array pointer */ pDTMFDetectState, /* Pointer to filter state array */ DETECTION_THRESHOLD, /* Threshold for signal energy */ &PreviousKeyCode, /* Pointer to previous key code */ &KeyCodeLength, /* Pointer to key code run length */ &KeyCodeRegistered, /* Pointer to storage for key code registration flag */ DTMF_SAMPLE_LENGTH); /* Array length */ #if COMMENT printf ("Keycode = %ld, %lx\n", KeyCode, KeyCode); SUF_Debugfprintf ("Keycode = %ld, %lx\n", KeyCode, KeyCode); KeyCode = SDA_DtmfDetect (pData, /* Source array pointer */ pDTMFDetectState, /* Pointer to filter state array */ DTMF_SAMPLE_LENGTH); /* Array length */ #endif if (KeyCode == SIGLIB_NO_SIGNAL_PRESENT) { printf ("(Length %d)\n", (short)PreviousKeyCodeLength); printf (". "); } else if (KeyCode == SIGLIB_NO_DTMF_SIGNAL) { printf ("(Length %d)\n", (short)PreviousKeyCodeLength); printf ("- "); } else if (KeyCode != SIGLIB_DTMF_CONTINUATION) { printf ("(Length %d)\n", (short)PreviousKeyCodeLength); printf ("%c ", SUF_KeyCodeToAscii (KeyCode)); } else /* KeyCode == SIGLIB_DTMF_CONTINUATION */ { PreviousKeyCodeLength = KeyCodeLength; } } printf ("\n\n\n"); printf ("DTMF signal peak magnitude = %lf\n", Max); printf ("\n\n\n"); SUF_MemoryFree (pData); /* Free memory */ SUF_MemoryFree (pDTMFDetectState); SUF_MemoryFree (pDTMFGenCoeffs); } /* Function : read_dtmf_key () Read a set of dtmf keys Return codes : 0 - success 1 - end of file 2 - [START] not found */ int read_dtmf_key (char *pTone, SLFixData_t *pPeriod, SLData_t *pMagnitude) { static int FirstTimeFlag = 1; static int StartFound = 0; char InputString[80]; char *InputStringPtr; char ch; InputStringPtr = InputString; if (FirstTimeFlag == 1) /* Read past header */ { while (((ch = (char)getc(pInputFile)) != EOF) && !StartFound) /* Get next character in source file */ { if (ch != ((char)0x0a)) *InputStringPtr++ = ch; /* Store character in word array */ else /* End of line */ { *InputStringPtr = '\0'; /* Store end of string in word array */ InputStringPtr = InputString; } if (!strcmp (InputString, "[START]")) StartFound = 1; } FirstTimeFlag = 0; ungetc (ch, pInputFile); /* Unget the last character */ if (!StartFound) { return(2); /* We have not found the start of the data */ } } if (fscanf (pInputFile, "%c, %ld, %lf\n", pTone, pPeriod, pMagnitude) != EOF) { if (*pPeriod > 500L) *pPeriod = 500L; if (*pMagnitude > SIGLIB_ZERO) *pMagnitude = -*pMagnitude; return(0); } else return(1); /* Failure */ }