C-Kurs/DTMF-Encoder/Musterlösung
< C-Kurs | DTMF-Encoder
Version vom 20. September 2010, 10:22 Uhr von Alexander Kührmann (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „<pre> #include <stdlib.h> #include <stdio.h> #include <math.h> unsigned char* generateSine(int ms, int freq, float amplitude, int *numSamples) { /* calculate...“)
#include <stdlib.h> #include <stdio.h> #include <math.h> unsigned char* generateSine(int ms, int freq, float amplitude, int *numSamples) { /* calculate number of samples and factor for the sine function */ *numSamples = ms * 8; // 8000 Hz sampling rate means 8 samples per millisecond double numPeriodic = 8000.0 / freq; double sinFac = 2 * M_PI / numPeriodic; unsigned char *sine = malloc(*numSamples * sizeof(unsigned char)); /* generate samples */ int i; for (i = 0; i < *numSamples; i++) { double sineVal = sin(i * sinFac); // between -1 and 1 unsigned char sample = (unsigned char) ((amplitude * sineVal + 1) * 0x7f); sine[i] = sample; } return sine; } unsigned char* mixPcm(unsigned char *a, unsigned char *b, int numSamples) { unsigned char *result = malloc(numSamples * sizeof(unsigned char)); int i; for (i = 0; i < numSamples; i++) { int aVal = a[i] - 127; int bVal = b[i] - 127; int rVal = aVal + bVal; result[i] = (unsigned char)(rVal + 127); } return result; } unsigned char* generateDtmfTone(int number, int ms, int *numSamples) { unsigned char *a; unsigned char *b; unsigned char *result; switch (number) { case 0: a = generateSine(ms, 941, 0.45, numSamples); b = generateSine(ms, 1336, 0.45, numSamples); break; case 1: a = generateSine(ms, 697, 0.45, numSamples); b = generateSine(ms, 1209, 0.45, numSamples); break; case 2: a = generateSine(ms, 697, 0.45, numSamples); b = generateSine(ms, 1336, 0.45, numSamples); break; case 3: a = generateSine(ms, 697, 0.45, numSamples); b = generateSine(ms, 1477, 0.45, numSamples); break; case 4: a = generateSine(ms, 770, 0.45, numSamples); b = generateSine(ms, 1209, 0.45, numSamples); break; case 5: a = generateSine(ms, 770, 0.45, numSamples); b = generateSine(ms, 1336, 0.45, numSamples); break; case 6: a = generateSine(ms, 770, 0.45, numSamples); b = generateSine(ms, 1477, 0.45, numSamples); break; case 7: a = generateSine(ms, 852, 0.45, numSamples); b = generateSine(ms, 1209, 0.45, numSamples); break; case 8: a = generateSine(ms, 852, 0.45, numSamples); b = generateSine(ms, 1336, 0.45, numSamples); break; case 9: a = generateSine(ms, 852, 0.45, numSamples); b = generateSine(ms, 1477, 0.45, numSamples); break; } result = mixPcm(a, b, *numSamples); free(a); free(b); return result; } unsigned char *generateSilence(int ms, int *numSamples) { *numSamples = ms * 8; // 8000 Hz sampling rate means 8 samples per millisecond unsigned char *result = malloc(*numSamples * sizeof(unsigned char)); int i; for (i = 0; i < *numSamples; i++) { result[i] = 127; } return result; } int main(int argc, char **argv) { if (argc != 2) { fprintf(stderr, "no number given\n"); return 0; } int number; if (1 != sscanf(argv[1], "%u", &number)) { fprintf(stderr, "given argument is not a number\n"); return 0; } FILE *f = fopen(argv[1], "w"); char *curNum = argv[1]; while (*curNum != '\0') { int digit = *curNum++ - '0'; int numSamples; unsigned char *tone = generateDtmfTone(digit, 800, &numSamples); fwrite(tone, sizeof(unsigned char), numSamples, f); free(tone); tone = generateSilence(300, &numSamples); fwrite(tone, sizeof(unsigned char), numSamples, f); free(tone); } fclose(f); }