Mercurial > hg > audiostuff
diff intercom/sinuston.cpp @ 2:13be24d74cd2
import intercom-0.4.1
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 09:57:52 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/intercom/sinuston.cpp Fri Jun 25 09:57:52 2010 +0200 @@ -0,0 +1,172 @@ +/* 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