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

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.