C-Kurs/DTMF-Encoder/Musterlösung: Unterschied zwischen den Versionen
< C-Kurs | DTMF-Encoder
(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...“) |
(kein Unterschied)
|
Version vom 20. September 2010, 10:22 Uhr
#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);
}