<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Erzeugen von DTMF Tönen]]></title><description><![CDATA[<p>Hallo an alle,</p>
<p>ich versuche gerade DTMF Töne zu generieren.</p>
<p>Habe dazu dieses Array einer Struktur mit den High und Low Frequenzen.</p>
<pre><code class="language-cpp">#define FRAMESIZE 160
#define SAMPLERATE 8000

struct tNumbers
{
   char cLetter;
   double row, column;
} button[] =
{
   {'1', 697, 1209},
   {'2', 697, 1336},
   {'3', 697, 1477},
   {'A', 697, 1633},
   {'4', 770, 1209},
   {'5', 770, 1336},
   {'6', 770, 1477},
   {'B', 770, 1633},
   {'7', 852, 1209},
   {'8', 852, 1336},
   {'9', 852, 1477},
   {'C', 852, 1633},
   {'*', 941, 1209},
   {'0', 941, 1336},
   {'#', 941, 1477},
   {'D', 941, 1633},
};
</code></pre>
<p>Die Töne sollen als 8bit mit Abtastrate 8000 für 20ms erzeugt werden.</p>
<pre><code class="language-cpp">char cTone[FRAMESIZE];
double value = 0.0;
char cDial;
cin &lt;&lt; cDial; // Eingabe von 0-9, a-f, # und *
int nCount =  sizeof(button)/sizeof(*button);
for int i = 0; i &lt; nCount; i++)
{
   for(int t = 0; i &lt; FRAMESIZE; i++)
   {
       val = sin(2 * M_PI * button[i].row * t) + sin(2 * M_PI * button[i].column * t);
   }
}
</code></pre>
<p>Wie bekomme ich val jetzt zu einem 8bit Wert konvertiert?<br />
Ist die Erzeugung soweit korrekt?</p>
<p>Gruß<br />
Crazy</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/260451/erzeugen-von-dtmf-tönen</link><generator>RSS for Node</generator><lastBuildDate>Mon, 07 Sep 2026 23:40:30 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/260451.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 05 Feb 2010 10:20:32 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Erzeugen von DTMF Tönen on Fri, 05 Feb 2010 10:20:32 GMT]]></title><description><![CDATA[<p>Hallo an alle,</p>
<p>ich versuche gerade DTMF Töne zu generieren.</p>
<p>Habe dazu dieses Array einer Struktur mit den High und Low Frequenzen.</p>
<pre><code class="language-cpp">#define FRAMESIZE 160
#define SAMPLERATE 8000

struct tNumbers
{
   char cLetter;
   double row, column;
} button[] =
{
   {'1', 697, 1209},
   {'2', 697, 1336},
   {'3', 697, 1477},
   {'A', 697, 1633},
   {'4', 770, 1209},
   {'5', 770, 1336},
   {'6', 770, 1477},
   {'B', 770, 1633},
   {'7', 852, 1209},
   {'8', 852, 1336},
   {'9', 852, 1477},
   {'C', 852, 1633},
   {'*', 941, 1209},
   {'0', 941, 1336},
   {'#', 941, 1477},
   {'D', 941, 1633},
};
</code></pre>
<p>Die Töne sollen als 8bit mit Abtastrate 8000 für 20ms erzeugt werden.</p>
<pre><code class="language-cpp">char cTone[FRAMESIZE];
double value = 0.0;
char cDial;
cin &lt;&lt; cDial; // Eingabe von 0-9, a-f, # und *
int nCount =  sizeof(button)/sizeof(*button);
for int i = 0; i &lt; nCount; i++)
{
   for(int t = 0; i &lt; FRAMESIZE; i++)
   {
       val = sin(2 * M_PI * button[i].row * t) + sin(2 * M_PI * button[i].column * t);
   }
}
</code></pre>
<p>Wie bekomme ich val jetzt zu einem 8bit Wert konvertiert?<br />
Ist die Erzeugung soweit korrekt?</p>
<p>Gruß<br />
Crazy</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1850811</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1850811</guid><dc:creator><![CDATA[CrazyPlaya]]></dc:creator><pubDate>Fri, 05 Feb 2010 10:20:32 GMT</pubDate></item><item><title><![CDATA[Reply to Erzeugen von DTMF Tönen on Fri, 05 Feb 2010 13:39:45 GMT]]></title><description><![CDATA[<p>val ist ja zwischen -2 und 2. 8bit-Signale sind typischerweise unsigned, also im Bereich 0...255 wobei eine Folge von 128 &quot;digitale Stille&quot; repräsentiert. Du kannst das einfach so umrechnen:</p>
<p>unsigned char sample8bit = static_cast&lt;unsigned char&gt;(128+val*63);</p>
<p>Du kannst übrigens einen gleichmäßig abgetasteten Sinus generieren ohne für jedes Sample std::sin aufrufen zu müssen. Das geht auch sehr schnell mit einer Multiplikation und einer Addition pro Sample. Dazu benutzt man oft folgende lineare Rekurrenz:</p>
<p>y[n] = y[n-1] * C - y[n-2]</p>
<p>wobei y[i] das i-te Ausgabe-Sample ist und C = 2*cos(sin_freq*2*pi/sampling_freq) gilt.</p>
<p>Man muss dabei nur etwas auf Rundungsfehler aufpassen. Alternativ kann man sich einen einen 2D-Punkt -- mit X und Y Koordinate -- merken, den um den Ursprung rotieren und nach jedem Schritt seine Y-Koordinate ausgeben. Das ergibt auch einen Sinus. Ein Abdriften durch Rundungsfehler kann durch ein gelegentliches Normalisieren verhindert werden:</p>
<pre><code class="language-cpp">// falls x*x+y*y etwas von 1 abweicht,
// korrigiert die Funktion dies etwas
inline void quick_normalize(double &amp; x, double &amp; y)
{
  double t = x*x+y*y;
  double s = 1.5 - 0.5 * t;
  x *= s;
  y *= s;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1850930</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1850930</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Fri, 05 Feb 2010 13:39:45 GMT</pubDate></item><item><title><![CDATA[Reply to Erzeugen von DTMF Tönen on Fri, 05 Feb 2010 13:34:11 GMT]]></title><description><![CDATA[<p>Ah danke schön....warum *63?</p>
<p>sin_freq sehe ich das richtig wäre z.B. die freq für die z.B. 1 im low Bereich also 697?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1850947</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1850947</guid><dc:creator><![CDATA[CrazyPlaya]]></dc:creator><pubDate>Fri, 05 Feb 2010 13:34:11 GMT</pubDate></item><item><title><![CDATA[Reply to Erzeugen von DTMF Tönen on Fri, 05 Feb 2010 13:36:34 GMT]]></title><description><![CDATA[<p>CrazyPlaya schrieb:</p>
<blockquote>
<p>Ah danke schön....warum *63?</p>
<p>sin_freq sehe ich das richtig wäre z.B. die freq für die z.B. 1 im low Bereich also 697?</p>
</blockquote>
<p>damit 128-2*63 bis 128+2*63, also 2 bis 254<br />
mit 64 wärs nicht mehr gepaßt haben tun getan (0 bis 256).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1850950</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1850950</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Fri, 05 Feb 2010 13:36:34 GMT</pubDate></item><item><title><![CDATA[Reply to Erzeugen von DTMF Tönen on Sun, 07 Feb 2010 06:53:29 GMT]]></title><description><![CDATA[<p>CrazyPlaya schrieb:</p>
<blockquote>
<p>Ah danke schön....warum *63?</p>
</blockquote>
<p>kannst auch 63.75 nehmen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":-)"
      alt="🙂"
    /><br />
Damit landest Du zwischen 0.5 und 255.5, was dann durch das Abwärtsrunden von static_cast&lt;unsigned char&gt; den vollen 8bit-Bereich 0...255 ausnutzt.</p>
<p>CrazyPlaya schrieb:</p>
<blockquote>
<p>sin_freq sehe ich das richtig wäre z.B. die freq für die z.B. 1 im low Bereich also 697?</p>
</blockquote>
<p>Ja, wobei sampling_freq dann 8000 wäre.</p>
<p>Es hat mich etwas in den Fingern gejuckt: Habe mal einen schnellen Sinusgenerator geschrieben, der mit 2.2 FLOPS pro Sample auskommt und &quot;stabil&quot; läuft:</p>
<p>Edit: neue Version</p>
<p>sine.hpp</p>
<pre><code class="language-cpp">#ifndef SINE_GENERATOR_HPP_INCLUDED
#define SINE_GENERATOR_HPP_INCLUDED

#include &lt;cmath&gt;
#include &lt;complex&gt;

namespace sin_gen_details { // &quot;action&quot; functors ...

struct replace
{
	template&lt;typename Iter&gt;
	void operator()(Iter &amp; it, double sample) const
	{
		*it = sample;
		++it;
	}
};

template&lt;typename BinOp&gt;
struct binop_wrapper
{
	BinOp binop;

	binop_wrapper(BinOp const&amp; bo) : binop(bo) {}

	template&lt;typename Iter&gt;
	void operator()(Iter &amp; it, double sample) const
	{
		*it = binop(*it, sample);
		++it;
	}
};

} // namespace sine_gen_details

class sine_generator
{
	std::complex&lt;double&gt; phase;
	std::complex&lt;double&gt; rotation;

	template&lt;typename Iter, typename Action&gt;
	void internal_generate(int count, Iter begin, Action x);

public:
	sine_generator() : phase(1),rotation(1) {}

	void set_frequency(double rad)
	{ rotation = std::polar(double(1),rad); }

	void reset_phase(double rad)
	{ phase = std::polar(double(1),rad); }

	template&lt;typename OutputIter&gt;
	void generate(int count, OutputIter begin)
	{
		internal_generate(count,begin,sin_gen_details::replace());
	}

	template&lt;typename ForwardIter, typename BinOp&gt;
	void generate(int count, ForwardIter begin, BinOp binop)
	{
		internal_generate(count,begin,
			sin_gen_details::binop_wrapper&lt;BinOp&gt;(binop) );
	}
};

template&lt;typename Iter, typename Action&gt;
void sine_generator::internal_generate(int count, Iter begin, Action action)
{
	std::complex&lt;double&gt; rot_forx = pow(rotation,12);
	phase /= abs(phase); // prevent drifting off due to rounding errors
	// use linear recurrence for generating the samples
	double const fy = 2 * real(rotation);
	double const fx = 2 * real(rot_forx);
	double y0 = imag(phase);
	double x0 = real(phase);
	double y1 = imag(phase*conj(rotation));
	double x1 = real(phase*conj(rot_forx));
	double tt; // temporary variable
	while (count &gt;= 12) {
		// 4*3 = 12 samples in a row ...
		for (int k=0; k&lt;4; ++k) {
			// output       | compute next sample
			action(begin,y0); tt = fy*y0-y1;
			action(begin,tt); y1 = fy*tt-y0;
			action(begin,y1); y0 = fy*y1-tt;
		}
		// update x as well ...
		tt = fx*x0-x1; x1 = x0; x0 = tt;
		count -= 12;
	}
	phase = std::complex&lt;double&gt;(x0,y0);
	while (count-- &gt; 0) {
		action(begin,imag(phase));
		phase *= rotation;
	}
}

#endif // SINE_GENERATOR_HPP_INCLUDED
</code></pre>
<p>test.cpp</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;functional&gt;

#include &quot;sine.hpp&quot;

using std::vector;
using std::cout;
using std::plus;

int main()
{
	const int buffsize = 160;
	vector&lt;double&gt; buffer(buffsize);

	sine_generator sg;

	sg.set_frequency(440 * 2*3.141592653589793 / 8000);
	sg.reset_phase(0);
	// overwrite buffer with sine wave ...
	sg.generate(buffsize,buffer.begin());

	sg.set_frequency(880 * 2*3.141592653589793 / 8000);
	sg.reset_phase(0);
	// mix buffer with sine wave ...
	sg.generate(buffsize,buffer.begin(),plus&lt;double&gt;());

	for (int i=0; i&lt;buffsize; ++i) {
		cout &lt;&lt; buffer.at(i) &lt;&lt; '\n';
	}
}
</code></pre>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1850977</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1850977</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Sun, 07 Feb 2010 06:53:29 GMT</pubDate></item><item><title><![CDATA[Reply to Erzeugen von DTMF Tönen on Fri, 05 Feb 2010 14:01:06 GMT]]></title><description><![CDATA[<p>Wow...darf ich annehmen das du dich öfters mit sowas befasst?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1850980</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1850980</guid><dc:creator><![CDATA[CrazyPlaya]]></dc:creator><pubDate>Fri, 05 Feb 2010 14:01:06 GMT</pubDate></item><item><title><![CDATA[Reply to Erzeugen von DTMF Tönen on Fri, 05 Feb 2010 14:12:43 GMT]]></title><description><![CDATA[<p>CrazyPlaya schrieb:</p>
<blockquote>
<p>Wow...darf ich annehmen das du dich öfters mit sowas befasst?</p>
</blockquote>
<p>Das ist schon 'ne Weile her, aber ich habe mal Software-Synthesizer programmiert und bin recht fit, was digitale Signalverarbeitung angeht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1850988</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1850988</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Fri, 05 Feb 2010 14:12:43 GMT</pubDate></item><item><title><![CDATA[Reply to Erzeugen von DTMF Tönen on Fri, 05 Feb 2010 14:21:24 GMT]]></title><description><![CDATA[<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> Gut zu wissen, ich fang gerade damit an:)</p>
<p>Also mit DSV...und meine erste Ausgabe ist gleich aus nem Audiostream zu DTMF Töne herauszuerkennen aber um meinen Filter zu testen muss ich diese erstmal erzeugen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1850993</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1850993</guid><dc:creator><![CDATA[CrazyPlaya]]></dc:creator><pubDate>Fri, 05 Feb 2010 14:21:24 GMT</pubDate></item><item><title><![CDATA[Reply to Erzeugen von DTMF Tönen on Fri, 05 Feb 2010 15:32:47 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/36159">@Sebastian</a> Pizer<br />
Hab da mal ein paar Fragen zu dem Code.</p>
<p>Die Methode rotate_inplace, wozu ist das gut?</p>
<p>Kannst du die Methode generate etwas näher erklären was genau du machst?<br />
Wie gesagt, ich fang gerad erst an mit DSV und hab noch nicht so ganz den Überblick.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1851037</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1851037</guid><dc:creator><![CDATA[CrazyPlaya]]></dc:creator><pubDate>Fri, 05 Feb 2010 15:32:47 GMT</pubDate></item><item><title><![CDATA[Reply to Erzeugen von DTMF Tönen on Sat, 06 Feb 2010 15:28:00 GMT]]></title><description><![CDATA[<p>CrazyPlaya schrieb:</p>
<blockquote>
<p>Hab da mal ein paar Fragen zu dem Code.<br />
Die Methode rotate_inplace, wozu ist das gut?</p>
</blockquote>
<p>Rotiert einen Punkt (x;y) &quot;in-place&quot; (also auf der Stelle, verändert direkt x und y) über gegebenen Sinus (s) und Cosinus (c).</p>
<pre><code>| c -s |   | x |      | x |
|      | * |   |  --&gt; |   |
| s  c |   | y |      | y |
</code></pre>
<p>CrazyPlaya schrieb:</p>
<blockquote>
<p>Kannst du die Methode generate etwas näher erklären was genau du machst?</p>
</blockquote>
<p>Das ist eine Kombination aus der Rekurrenzformel und dem Rotieren eines Punktes in 2D. Im Zustand merke ich mir den letzten Punkt über x0/y0 und die y-Koordinate des Punktes davor, y1. c und s speichert Cosinus und Sinus des Drehwinkels, mit dem die Frequenz geregelt wird.</p>
<p><code>generate</code> berechnet 12 Samples (die y-Werte) über die Rekurrenzgleichung und wendet die Rekurrenzgleichung auch einmal an, für die 12fache Frequenz, um den letzten x-wert zu berechnen. Der x-Wert ist praktisch, wenn man die Frequenz ändern will, oder die Amplitude normalisieren will. Da die x-Werte aber sonst nicht benötigt werden, muss ich nicht so viele davon berechnen. Im Beispiel von oben tue ich das im Regelfall nur einmal pro 12 Samples -- den Schluss mal ignoriert.</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1851055</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1851055</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Sat, 06 Feb 2010 15:28:00 GMT</pubDate></item><item><title><![CDATA[Reply to Erzeugen von DTMF Tönen on Fri, 05 Feb 2010 20:23:19 GMT]]></title><description><![CDATA[<p>Ja...hm... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Ich muss noch ne Menge lernen in dem Bereich, ich merk das schon <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Aber besten Dank...ich werd mal versuchen das alles nachzuvollziehen</p>
<p>Gruß<br />
Karsten</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1851147</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1851147</guid><dc:creator><![CDATA[CrazyPlaya]]></dc:creator><pubDate>Fri, 05 Feb 2010 20:23:19 GMT</pubDate></item><item><title><![CDATA[Reply to Erzeugen von DTMF Tönen on Sat, 06 Feb 2010 15:30:00 GMT]]></title><description><![CDATA[<p>CrazyPlaya schrieb:</p>
<blockquote>
<p>Ja...hm... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /><br />
Ich muss noch ne Menge lernen in dem Bereich, ich merk das schon <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /><br />
Aber besten Dank...ich werd mal versuchen das alles nachzuvollziehen</p>
</blockquote>
<p>Ich habe die Version auf die Nutzung von std::complex umgestellt. Das ist nun etwas eleganter und wahrscheinlich auch leichter nachvollziehbar, wenn man komplexe Zahlen kennt. Als angehender DSVler muss man sich früher oder später sowieso mit komplexen Zahlen auseinandersetzen. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Grup,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1851478</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1851478</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Sat, 06 Feb 2010 15:30:00 GMT</pubDate></item><item><title><![CDATA[Reply to Erzeugen von DTMF Tönen on Mon, 08 Feb 2010 08:51:48 GMT]]></title><description><![CDATA[<p>Nicht Schlecht Herr Specht.<br />
Zu den komplexen Zahlen muss ich mich erst noch vorarbeiten...da wird noch eine Weile ins Land gehen bis ich da angelangt bin.</p>
<p>Mir graut jetzt schon davor <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> .</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1852242</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1852242</guid><dc:creator><![CDATA[CrazyPlaya]]></dc:creator><pubDate>Mon, 08 Feb 2010 08:51:48 GMT</pubDate></item></channel></rss>