Mercurial > hg > audiostuff
view intercom/sinuston.cpp @ 5:f762bf195c4b
import spandsp-0.0.3
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 16:00:21 +0200 |
parents | 13be24d74cd2 |
children |
line wrap: on
line source
/* sinuston.cpp * erzeuget Sinustabelle für Frequenz * Author: Christian Dorge, Andre Adrian * * Compile: c++ -DMODULTEST -g -O0 -o sinuston sinuston.cpp * * debug: ddd sinuston & * * Quelltext Formatierung: indent -kr -i2 -nlp -ci2 -l72 -lc72 -nut sinuston.cpp * */ #include <stdio.h> #include <math.h> #include <string.h> /* fuer syslog */ #include <syslog.h> #include "sinuston.h" float dB2faktor(float dB) { /* Dezibel nach Faktor */ return powf(10.0f, dB / 20.0f); } float faktor2dB(float q) { /* Faktor nach Dezibel */ return 20.0f * log10f(q); } int kgv(int a, int b) { int r = a; int q = b; int rest; while ((rest = r % q)) { r = q; q = rest; } int kgv = a * b / q; // fprintf(stderr, "%d \n", kgv); return kgv; } SINUSTON::SINUSTON() { // init auf 0 j = 0; cnt = 0; memset(sinustab, 0, sizeof(sinustab)); } short SINUSTON::frequenz(int f1, int fs, float pegel) { if (f1 < 0) { syslog(LOG_WARNING, "Tonfrequenz < 0 \n"); return -1; } if (fs < 0) { syslog(LOG_WARNING, "Abtastfrequenz < 0 \n"); return -1; } if (pegel > 0.0f) { syslog(LOG_WARNING, "Pegel > 0 \n"); return -1; } if (2 * f1 > fs) { syslog(LOG_WARNING, "Tonfrequenz > 1/2 Abtastfrequenz"); return -1; } cnt = kgv(fs, f1) / f1; if (cnt > SINUSTONLEN) // Prüfung, ob Samplewert nicht Größer als Max.wert der Sinustabelle { cnt = SINUSTONLEN; } float winkelschritt = (float)f1 / (float)fs * 2 * M_PI; // Berechnung Winkelschritt float pegelwert = 32767 * dB2faktor(pegel); //Umrechnung Dezibel in Faktor (16bit PCM) for (int i = 0; i < cnt; i++) { sinustab[i] = (short) (pegelwert * sinf(i * winkelschritt)); // printf("%f, %f, %f \n", f1, fs, sinustab[i]); } return cnt; } short SINUSTON::mischen(short ein_sprache) { // Schleifenende if (j >= cnt) { j = 0; } long sum = (long) ein_sprache + (long) sinustab[j]; // Werte limitieren auf 16bit Wertebereich if (sum > 32767) { sum = 32767; } else if (sum < -32767) { sum = -32767; } // Schleifeninkrement j++; return (short) sum; } #ifdef MODULTEST int main(int argc, char *argv[]) { int f1 = 2040; // Frequenz Ton int fs = 8000; // Abtastfrequenz float pegel = -24; // minus Dezibel short ein_sprache[80000]; short aus_sprache_signal[80000]; SINUSTON s; /* init syslog (Fehler Logging) * syslog Fehlermeldungen auch nach /var/log/warn */ openlog(NULL, LOG_PERROR, LOG_WARNING); /* printf("Bitte Frequenz eingeben: "); scanf("%f", &f1); printf("Bitte Samplerate eingeben: "); scanf("%f", &fs); printf("Bitte Pegel eingeben: "); scanf("%f", &pegel); */ // Eingabe fread(ein_sprache, sizeof(short), 80000, stdin); // Verarbeitung short cnt = s.frequenz(f1, fs, pegel); // fprintf(stderr, "Die Anzahl der Elemente ist %f \n", cnt); int j; for (int i = 0; i < 80000; i++) { aus_sprache_signal[i] = s.mischen(ein_sprache[i]); } // Ausgabe /* (short) wg. Ausgabe in RAW-Datei * (1 Sample = 16bit Signed Int Wert) * fwrite(pointer auf Daten, Datengröße des Typs, Anzahl zu lesender Elemente, Ausgabe) */ fwrite(aus_sprache_signal, sizeof(short), 80000, stdout); } #endif