/// <summary> /// Determine the maximum frequency given the set of frequency bins /// </summary> /// <param name="frequencyBins">set of bins to find max freq in</param> /// <returns>the frequency of the bin with the highest energy</returns> static internal double FindMaxFrequency( FrequencyBin[] frequencyBins ) { double retval; double max; retval = 0.0; max = 0.0; for( int i = 0; i < frequencyBins.Length; ++i ) { if( frequencyBins[i].Energy > max ) { max = frequencyBins[i].Energy; retval = frequencyBins[i].Frequency; } } return retval; }
internal void Initialize() { mS = 0; toneDetectors = new List<IDetectTone>(); toneDetectors.Add( new FaxTone() ); toneDetectors.Add( new TriTone() ); toneDetectors.Add( new VoiceMail() ); //require 256 (a power of 2 for FFT). Note, this yields bins of 31.5hz frameBuffer = new FrameBuffer( AudioParameters.NumberSamples ); averageFrequencyBins = new FrequencyBin [AudioParameters.BinsToAnayze]; instantaneousFrequencyBins = new FrequencyBin[AudioParameters.BinsToAnayze]; for( int i = 0; i < AudioParameters.BinsToAnayze; ++i ) { averageFrequencyBins[i] = new FrequencyBin( i * AudioParameters.HertzPerBin, 0 ); instantaneousFrequencyBins[i] = new FrequencyBin( i * AudioParameters.HertzPerBin, 0 ); } }
public ToneDetected Detect( short[] samples, Complex[] cdata, FrequencyBin[] averageFrequencyBins, FrequencyBin[] instantaneousFrequencyBins, int mS, // the number of mS since the beginning of the data stream double maxFrequency // the frequency where the maximum energy occurs from fft ) { ToneDetected retval; retval = ToneDetected.NONE; if( cedState.IsFound( maxFrequency ) ) { retval = ToneDetected.FAX; } else if( othState.IsFound( maxFrequency ) ) { retval = ToneDetected.FAX; } return retval; }
public ToneDetected Detect( short [] samples, Complex [] cdata, FrequencyBin [] averageFrequencyBins, FrequencyBin [] instantenousFrequencyBins, int mS, // the number of mS since the beginning of the data stream double maxFrequency // the frequency where the maximum energy occurs from fft ) { ToneDetected retval; retval = ToneDetected.NONE; double energy; // in this method, we are assuming 20 % of the tone is enough to cause // a hit. Then, 8 or 11 hits are required based on the duration of the // particular portion of the tone we are detecting based on the specification of // the SIT (Special Information Tone). // note, 8000hz so we are doing 8 samples per mS switch( toneState ) { case TriToneState.WaitingForSignal: energy = 0; //for(int i = 0; i < 128; ++i) //{ // energy += cdata[i].Re; //} for( int i = 0; i < samples.Length; ++i ) { energy += Math.Abs( samples[i] ); } if(energy > 0) { // need to check the data we currently have for the // first part of the tri-tone signal. if( (maxFrequency >= TriToneConstants.startTone1) && (maxFrequency <= TriToneConstants.endTone1) ) { Console.WriteLine( "Moving to state 1: {0}", mS ); Log( "Moving to state1" ); missCount = 0; toneState = TriToneState.Tone1; hitCount = 1; } } break; case TriToneState.Tone1: streamName = "TriTone1"; if( ( maxFrequency >= TriToneConstants.startTone1 ) && ( maxFrequency <= TriToneConstants.endTone1 ) ) { missCount = 0; hitCount++; Log( string.Format( "Maxfreq={0} hits={1}", maxFrequency, hitCount ) ); if( hitCount == 7 ) { //Console.WriteLine( "Moving to state 2: {0}", mS ); //toneState = TriToneState.Tone2; //Log( "Moving to state2" ); //hitCount = 0; //missCount = 0; minHitsFound = true; missCount = 0; } } else { if( ( maxFrequency >= TriToneConstants.startTone2 ) && ( maxFrequency <= TriToneConstants.endTone2 ) ) { if( minHitsFound ) { Console.WriteLine( "Moving to state 2: {0}", mS ); Log( "Moving to state2" ); toneState = TriToneState.Tone2; hitCount = 1; missCount = 0; minHitsFound = false; } //else //{ // if( missCount < 1 ) // { // missCount++; // } //} } else { if( missCount < 1 ) { missCount++; } else { hitCount = 0; } } } break; case TriToneState.Tone2: streamName = "TriTone2"; if( ( maxFrequency >= TriToneConstants.startTone2 ) && ( maxFrequency <= TriToneConstants.endTone2 ) ) { missCount = 0; hitCount++; Log( string.Format( "Maxfreq={0} hits={1}", maxFrequency, hitCount ) ); if( hitCount == 7 ) { //toneState = TriToneState.Tone3; //Console.WriteLine( "Moving to state 3: {0}", mS ); //Log( "Moving to state3" ); //hitCount = 0; //missCount = 0; minHitsFound = true; missCount = 0; } } else { if( ( maxFrequency >= TriToneConstants.startTone3 ) && ( maxFrequency <= TriToneConstants.endTone3 ) ) { if( minHitsFound ) { Console.WriteLine( "Moving to state 3: {0}", mS ); Log( "Moving to state3" ); toneState = TriToneState.Tone3; hitCount = 1; missCount = 0; minHitsFound = false; } //else //{ // toneState = TriToneState.NoTriTone; //} } else { if( missCount < 1 ) { missCount++; } else { hitCount = 0; } } } break; case TriToneState.Tone3: streamName = "TriTone3"; if( ( maxFrequency >= TriToneConstants.startTone3 ) && ( maxFrequency <= TriToneConstants.endTone3 ) ) { missCount = 0; hitCount++; Log( string.Format( "Maxfreq={0} hits={1}", maxFrequency, hitCount ) ); if( hitCount == 7 ) { Console.WriteLine( "Found Tri: {0}", mS ); retval = ToneDetected.TRITONE; Log( "tone found" ); hitCount = 0; } } else { if( missCount < 1 ) { missCount++; } else { toneState = TriToneState.NoTriTone; } } break; // this case indicates there definately is not tritone in the signal. case TriToneState.NoTriTone: break; case TriToneState.Done: break; default: break; } return retval; }