DTMF.java (4402B)
1 /* 2 * _______ _____ _____ _____ 3 * |__ __| | __ \ / ____| __ \ 4 * | | __ _ _ __ ___ ___ ___| | | | (___ | |__) | 5 * | |/ _` | '__/ __|/ _ \/ __| | | |\___ \| ___/ 6 * | | (_| | | \__ \ (_) \__ \ |__| |____) | | 7 * |_|\__,_|_| |___/\___/|___/_____/|_____/|_| 8 * 9 * ------------------------------------------------------------- 10 * 11 * TarsosDSP is developed by Joren Six at IPEM, University Ghent 12 * 13 * ------------------------------------------------------------- 14 * 15 * Info: http://0110.be/tag/TarsosDSP 16 * Github: https://github.com/JorenSix/TarsosDSP 17 * Releases: http://0110.be/releases/TarsosDSP/ 18 * 19 * TarsosDSP includes modified source code by various authors, 20 * for credits and info, see README. 21 * 22 */ 23 24 25 package be.tarsos.dsp.pitch; 26 27 /** 28 * Utility class to generate Dual-tone multi-frequency (DTMF) signaling tones. 29 * This class also contains a list of valid DTMF frequencies and characters. 30 * 31 * See the <a href="http://en.wikipedia.org/wiki/Dual-tone_multi-frequency_signaling" 32 * >WikiPedia article on DTMF</a>. 33 * 34 * @author Joren Six 35 */ 36 public class DTMF { 37 38 /** 39 * The list of valid DTMF frequencies. See the <a 40 * href="http://en.wikipedia.org/wiki/Dual-tone_multi-frequency_signaling" 41 * >WikiPedia article on DTMF</a>. 42 */ 43 public static final double[] DTMF_FREQUENCIES = { 697, 770, 852, 941, 1209, 44 1336, 1477, 1633 }; 45 46 /** 47 * The list of valid DTMF characters. See the <a 48 * href="http://en.wikipedia.org/wiki/Dual-tone_multi-frequency_signaling" 49 * >WikiPedia article on DTMF</a> for the relation between the characters 50 * and frequencies. 51 */ 52 public static final char[][] DTMF_CHARACTERS = { { '1', '2', '3', 'A' }, 53 { '4', '5', '6', 'B' }, { '7', '8', '9', 'C' }, 54 { '*', '0', '#', 'D' } }; 55 56 /** 57 * Generate a DTMF - tone for a valid DTMF character. 58 * @param character a valid DTMF character (present in DTMF_CHARACTERS} 59 * @return a float buffer of predefined length (7168 samples) with the correct DTMF tone representing the character. 60 */ 61 public static float[] generateDTMFTone(char character){ 62 double firstFrequency = -1; 63 double secondFrequency = -1; 64 for(int row = 0 ; row < DTMF_CHARACTERS.length ; row++){ 65 for(int col = 0 ; col < DTMF_CHARACTERS[row].length ; col++){ 66 if(DTMF_CHARACTERS[row][col] == character){ 67 firstFrequency = DTMF_FREQUENCIES[row]; 68 secondFrequency = DTMF_FREQUENCIES[col + 4]; 69 } 70 } 71 } 72 return DTMF.audioBufferDTMF(firstFrequency,secondFrequency,512*2*10); 73 } 74 75 /** 76 * Checks if the given character is present in DTMF_CHARACTERS. 77 * 78 * @param character 79 * the character to check. 80 * @return True if the given character is present in 81 * DTMF_CHARACTERS, false otherwise. 82 */ 83 public static boolean isDTMFCharacter(char character){ 84 double firstFrequency = -1; 85 double secondFrequency = -1; 86 for(int row = 0 ; row < DTMF_CHARACTERS.length ; row++){ 87 for(int col = 0 ; col < DTMF_CHARACTERS[row].length ; col++){ 88 if(DTMF_CHARACTERS[row][col] == character){ 89 firstFrequency = DTMF_FREQUENCIES[row]; 90 secondFrequency = DTMF_FREQUENCIES[col + 4]; 91 } 92 } 93 } 94 return (firstFrequency!=-1 && secondFrequency!=-1); 95 } 96 97 /** 98 * Creates an audio buffer in a float array of the defined size. The sample 99 * rate is 44100Hz by default. It mixes the two given frequencies with an 100 * amplitude of 0.5. 101 * 102 * @param f0 103 * The first fundamental frequency. 104 * @param f1 105 * The second fundamental frequency. 106 * @param size 107 * The size of the float array (sample rate is 44.1kHz). 108 * @return An array of the defined size. 109 */ 110 public static float[] audioBufferDTMF(final double f0, final double f1, 111 int size) { 112 final double sampleRate = 44100.0; 113 final double amplitudeF0 = 0.4; 114 final double amplitudeF1 = 0.4; 115 final double twoPiF0 = 2 * Math.PI * f0; 116 final double twoPiF1 = 2 * Math.PI * f1; 117 final float[] buffer = new float[size]; 118 for (int sample = 0; sample < buffer.length; sample++) { 119 final double time = sample / sampleRate; 120 double f0Component = amplitudeF0 * Math.sin(twoPiF0 * time); 121 double f1Component = amplitudeF1 * Math.sin(twoPiF1 * time); 122 buffer[sample] = (float) (f0Component + f1Component); 123 } 124 return buffer; 125 } 126 }