<?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[Wav Files]]></title><description><![CDATA[<p>Hallo alle zusammen!<br />
Ich hab mich seit ein paar Tagen mal mit wav files, Tönen und der gleichen befasst und bisher hat auch alles relativ gut funktioniert. Aber irgendwie haben sich ein paar für mich unerklärliche Fehler eingeschlichen.<br />
Meine Fehler sehen wie folgt aus: Wenn ich einen Sound mit 16 bit und 2 Kanälen erstelle, verdoppelt sich die Frequenz. Wenn ich einen sound mit 8 Bit Mono haben ist die Frequenz halbiert. Ausserdem ist bei 16 Bit der Sound immer nur Halb so lange wie per Parameter erwünscht. (Diese &quot;Erkenntnisse&quot; habe ich über audacity nachgeprüft)<br />
Die Fehler sind ja vermutlich miteinander verbunden, aber ich finde einfach nicht wie... Ich glaube, das das Erstellen der Rechteckwelle einen Probleme beinhaltet. Ich tippe darauf, das der Fehler bei allocieren der Variable data entsteht, oder bei der Art wie sie in die Datei geschrieben wird.<br />
Ich hoffe einer von euch kann mir helfen! Vielen Dank schonmal im Vorraus.<br />
Foaly</p>
<p>Hier noch Code:<br />
sample.h</p>
<pre><code class="language-cpp">#ifndef SAMPLE_H
#define SAMPLE_H

#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;math.h&gt;

typedef class SAMPLE                  /* a sample */
{
private:
    int pack_iputw(int w, FILE *f);

public:
    unsigned short channels;           /* channels 1 or 2*/
    unsigned long sampleRate;          /* sample Rate (frequency)*/
    unsigned long bytesPerSecond;      /* bytes per second*/
    unsigned long len;                 /* length*/
    unsigned short bitsPerChannel;     /* bits*/
    void *data;                        /* sample data */

    SAMPLE(int bits, int stereo, int freq, int length);
    ~SAMPLE();

    void createSinWave(int freq);
    void createRectWave(int freq);
    void saveWav(const char* filename);
} SAMPLE;

#endif // SAMPLE_H
</code></pre>
<p>sample.cpp</p>
<pre><code class="language-cpp">#include &quot;sample.h&quot;

SAMPLE::SAMPLE(int bits, int stereo, int freq, int length)
{
//    printf(&quot;2. Bits: %d, Channels: %d, Freq: %d, Len: %d\n&quot;, bitsPerChannel, channels, sampleRate, len);
    bitsPerChannel = bits;
    channels = stereo;
    sampleRate = freq;
    len = length;

    data = malloc(len * 2/*((bits == 8) ? 1 : sizeof(short))*/ * stereo);
    if (!data) {
       delete this;
    }

    //printf(&quot;2. Bits: %d, Channels: %d, Freq: %d, Len: %d, Data: %d\n&quot;, bitsPerChannel, channels, sampleRate, len, (len * (bits/8) * stereo));
    printf(&quot;Done creating sample!\n&quot;);
}

SAMPLE::~SAMPLE()
{
    if(data)
    {
        free(data);
    }
}

// creates a rectagular wave
void SAMPLE::createRectWave(int freq)
{
    printf(&quot;Start creating RectWav!\n&quot;);

    memset(data, 0x8000, len *2 );

    if (freq == 0) {
        return;
    }
    int dist  = sampleRate / freq;
    int dist2 = dist/2;
    int count = len / dist +1;

    for (int a=0; a &lt; count; a++) {
        for (int b=0; b &lt; dist; b++) {
            if ( (unsigned) (a*dist+b) &gt;= len)
            {
                printf(&quot;Done creating RectWav!\n&quot;);
                return;
            }
            if (b &lt; dist2)
            {
                ((signed short*)data)[a*dist+b] = 0xffff;
            }
            else
            {
                ((signed short*)data)[a*dist+b] = 0x0000;
            }

        }
    }
}

// to be ignored for now
// creates a sin wave
//void SAMPLE::createSinWave(int freq)
//{
//    for (unsigned int i=0; i&lt;len; i++)
//        ((signed short*)data)[i] = 1 * sin(2*M_PI*freq*i);
//}

// writes the SAMPLE data into a .WAV file
void SAMPLE::saveWav(const char *filename)
{
    if (!data)
    {
        printf(&quot;Could not save data to %s, nothing passed.\n&quot;, filename);
        return;
    }

    FILE* file = fopen(filename, &quot;wb&quot;);

    if (file)
    {
        // initialize wave header
        unsigned short formatType = 1;
        unsigned short numChannels = channels;
        unsigned long sampleRate = this-&gt;sampleRate;
        unsigned short bitsPerChannel = this-&gt;bitsPerChannel;
        unsigned short bytesPerSample = numChannels * (bitsPerChannel / 8);
        unsigned long bytesPerSecond = sampleRate * bytesPerSample;
        unsigned long dataLen = len*bytesPerSample;

        const int fmtChunkLen = 16;
        const int waveHeaderLen = 4 + 8 + fmtChunkLen + 8;

        unsigned long totalLen = waveHeaderLen + dataLen;

        // write wave header
        fwrite(&quot;RIFF&quot;, 4, 1, file);
        fwrite(&amp;totalLen, 4, 1, file);
        fwrite(&quot;WAVE&quot;, 4, 1, file);
        fwrite(&quot;fmt &quot;, 4, 1, file);
        fwrite(&amp;fmtChunkLen, 4, 1, file);
        fwrite(&amp;formatType, 2, 1, file);
        fwrite(&amp;numChannels, 2, 1, file);
        fwrite(&amp;sampleRate, 4, 1, file);
        fwrite(&amp;bytesPerSecond, 4, 1, file);
        fwrite(&amp;bytesPerSample, 2, 1, file);
        fwrite(&amp;bitsPerChannel, 2, 1, file);

        // write data
        fwrite(&quot;data&quot;, 4, 1, file);
        fwrite(&amp;dataLen, 4, 1, file);
        //fwrite(data, dataLen, 1, file);

        /* write the data */
        if (bitsPerChannel == 8) {
            fwrite(data, dataLen, 1, file);
        } else {
            signed short s;
            for (int i=0; i &lt; (int)len * numChannels; i++) {
                s = ((signed short *)data)[i];
                pack_iputw(s^0x8000, file);
            }
        }

        // finish
        printf(&quot;Saved audio as %s\n&quot;, filename);
        fclose(file);
    }
}

/* pack_iputw:
 *  Writes a 16 bit int to a file, using intel byte ordering.
 */
int SAMPLE::pack_iputw(int w, FILE *f)
{
   int b1, b2;

   b1 = (w &amp; 0xFF00) &gt;&gt; 8;
   b2 = w &amp; 0x00FF;

   if (fputc(b2,f)==b2)
      if (fputc(b1,f)==b1)
         return w;

   return EOF;
}
</code></pre>
<p>aufgerufen wir das ganze so:</p>
<pre><code class="language-cpp">SAMPLE *sample = new SAMPLE(16, 2, 44100, 44100);
    if(sample)
    {
        sample-&gt;createRectWave(440);
        sample-&gt;saveWav(&quot;test.wav&quot;);
    }

    delete sample;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/276840/wav-files</link><generator>RSS for Node</generator><lastBuildDate>Wed, 26 Aug 2026 06:06:33 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/276840.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 09 Nov 2010 08:14:58 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Wav Files on Tue, 09 Nov 2010 08:15:40 GMT]]></title><description><![CDATA[<p>Hallo alle zusammen!<br />
Ich hab mich seit ein paar Tagen mal mit wav files, Tönen und der gleichen befasst und bisher hat auch alles relativ gut funktioniert. Aber irgendwie haben sich ein paar für mich unerklärliche Fehler eingeschlichen.<br />
Meine Fehler sehen wie folgt aus: Wenn ich einen Sound mit 16 bit und 2 Kanälen erstelle, verdoppelt sich die Frequenz. Wenn ich einen sound mit 8 Bit Mono haben ist die Frequenz halbiert. Ausserdem ist bei 16 Bit der Sound immer nur Halb so lange wie per Parameter erwünscht. (Diese &quot;Erkenntnisse&quot; habe ich über audacity nachgeprüft)<br />
Die Fehler sind ja vermutlich miteinander verbunden, aber ich finde einfach nicht wie... Ich glaube, das das Erstellen der Rechteckwelle einen Probleme beinhaltet. Ich tippe darauf, das der Fehler bei allocieren der Variable data entsteht, oder bei der Art wie sie in die Datei geschrieben wird.<br />
Ich hoffe einer von euch kann mir helfen! Vielen Dank schonmal im Vorraus.<br />
Foaly</p>
<p>Hier noch Code:<br />
sample.h</p>
<pre><code class="language-cpp">#ifndef SAMPLE_H
#define SAMPLE_H

#include &lt;stdlib.h&gt;
#include &lt;stdio.h&gt;
#include &lt;string.h&gt;
#include &lt;math.h&gt;

typedef class SAMPLE                  /* a sample */
{
private:
    int pack_iputw(int w, FILE *f);

public:
    unsigned short channels;           /* channels 1 or 2*/
    unsigned long sampleRate;          /* sample Rate (frequency)*/
    unsigned long bytesPerSecond;      /* bytes per second*/
    unsigned long len;                 /* length*/
    unsigned short bitsPerChannel;     /* bits*/
    void *data;                        /* sample data */

    SAMPLE(int bits, int stereo, int freq, int length);
    ~SAMPLE();

    void createSinWave(int freq);
    void createRectWave(int freq);
    void saveWav(const char* filename);
} SAMPLE;

#endif // SAMPLE_H
</code></pre>
<p>sample.cpp</p>
<pre><code class="language-cpp">#include &quot;sample.h&quot;

SAMPLE::SAMPLE(int bits, int stereo, int freq, int length)
{
//    printf(&quot;2. Bits: %d, Channels: %d, Freq: %d, Len: %d\n&quot;, bitsPerChannel, channels, sampleRate, len);
    bitsPerChannel = bits;
    channels = stereo;
    sampleRate = freq;
    len = length;

    data = malloc(len * 2/*((bits == 8) ? 1 : sizeof(short))*/ * stereo);
    if (!data) {
       delete this;
    }

    //printf(&quot;2. Bits: %d, Channels: %d, Freq: %d, Len: %d, Data: %d\n&quot;, bitsPerChannel, channels, sampleRate, len, (len * (bits/8) * stereo));
    printf(&quot;Done creating sample!\n&quot;);
}

SAMPLE::~SAMPLE()
{
    if(data)
    {
        free(data);
    }
}

// creates a rectagular wave
void SAMPLE::createRectWave(int freq)
{
    printf(&quot;Start creating RectWav!\n&quot;);

    memset(data, 0x8000, len *2 );

    if (freq == 0) {
        return;
    }
    int dist  = sampleRate / freq;
    int dist2 = dist/2;
    int count = len / dist +1;

    for (int a=0; a &lt; count; a++) {
        for (int b=0; b &lt; dist; b++) {
            if ( (unsigned) (a*dist+b) &gt;= len)
            {
                printf(&quot;Done creating RectWav!\n&quot;);
                return;
            }
            if (b &lt; dist2)
            {
                ((signed short*)data)[a*dist+b] = 0xffff;
            }
            else
            {
                ((signed short*)data)[a*dist+b] = 0x0000;
            }

        }
    }
}

// to be ignored for now
// creates a sin wave
//void SAMPLE::createSinWave(int freq)
//{
//    for (unsigned int i=0; i&lt;len; i++)
//        ((signed short*)data)[i] = 1 * sin(2*M_PI*freq*i);
//}

// writes the SAMPLE data into a .WAV file
void SAMPLE::saveWav(const char *filename)
{
    if (!data)
    {
        printf(&quot;Could not save data to %s, nothing passed.\n&quot;, filename);
        return;
    }

    FILE* file = fopen(filename, &quot;wb&quot;);

    if (file)
    {
        // initialize wave header
        unsigned short formatType = 1;
        unsigned short numChannels = channels;
        unsigned long sampleRate = this-&gt;sampleRate;
        unsigned short bitsPerChannel = this-&gt;bitsPerChannel;
        unsigned short bytesPerSample = numChannels * (bitsPerChannel / 8);
        unsigned long bytesPerSecond = sampleRate * bytesPerSample;
        unsigned long dataLen = len*bytesPerSample;

        const int fmtChunkLen = 16;
        const int waveHeaderLen = 4 + 8 + fmtChunkLen + 8;

        unsigned long totalLen = waveHeaderLen + dataLen;

        // write wave header
        fwrite(&quot;RIFF&quot;, 4, 1, file);
        fwrite(&amp;totalLen, 4, 1, file);
        fwrite(&quot;WAVE&quot;, 4, 1, file);
        fwrite(&quot;fmt &quot;, 4, 1, file);
        fwrite(&amp;fmtChunkLen, 4, 1, file);
        fwrite(&amp;formatType, 2, 1, file);
        fwrite(&amp;numChannels, 2, 1, file);
        fwrite(&amp;sampleRate, 4, 1, file);
        fwrite(&amp;bytesPerSecond, 4, 1, file);
        fwrite(&amp;bytesPerSample, 2, 1, file);
        fwrite(&amp;bitsPerChannel, 2, 1, file);

        // write data
        fwrite(&quot;data&quot;, 4, 1, file);
        fwrite(&amp;dataLen, 4, 1, file);
        //fwrite(data, dataLen, 1, file);

        /* write the data */
        if (bitsPerChannel == 8) {
            fwrite(data, dataLen, 1, file);
        } else {
            signed short s;
            for (int i=0; i &lt; (int)len * numChannels; i++) {
                s = ((signed short *)data)[i];
                pack_iputw(s^0x8000, file);
            }
        }

        // finish
        printf(&quot;Saved audio as %s\n&quot;, filename);
        fclose(file);
    }
}

/* pack_iputw:
 *  Writes a 16 bit int to a file, using intel byte ordering.
 */
int SAMPLE::pack_iputw(int w, FILE *f)
{
   int b1, b2;

   b1 = (w &amp; 0xFF00) &gt;&gt; 8;
   b2 = w &amp; 0x00FF;

   if (fputc(b2,f)==b2)
      if (fputc(b1,f)==b1)
         return w;

   return EOF;
}
</code></pre>
<p>aufgerufen wir das ganze so:</p>
<pre><code class="language-cpp">SAMPLE *sample = new SAMPLE(16, 2, 44100, 44100);
    if(sample)
    {
        sample-&gt;createRectWave(440);
        sample-&gt;saveWav(&quot;test.wav&quot;);
    }

    delete sample;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1977641</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1977641</guid><dc:creator><![CDATA[Foaly]]></dc:creator><pubDate>Tue, 09 Nov 2010 08:15:40 GMT</pubDate></item><item><title><![CDATA[Reply to Wav Files on Tue, 09 Nov 2010 11:03:20 GMT]]></title><description><![CDATA[<p>Bist Du sicher, dass das Programm nicht einfach abschmiert? Da sind unzählige Fehler drin.<br />
Womit hast Du C++ gelernt? Mit einem Tutorial, oder einem Buch? Hast Du vorher irgendwie mal Java programmiert?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1977705</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1977705</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Tue, 09 Nov 2010 11:03:20 GMT</pubDate></item><item><title><![CDATA[Reply to Wav Files on Tue, 09 Nov 2010 16:09:16 GMT]]></title><description><![CDATA[<p>Vielen Dank erstmal für die schnelle Antwort.<br />
Ich programmiere schon relativ lange in C und C++. Ursprünglich gelernt hab ich es aus einem Internet Tutorial, habe mittlerweile aber schon 4 Bücher übers die Sprachen und Programmieren im Allgemeinen gelesen. Außerdem hab ich schon an einigen großen Projekten mitgearbeitet und ein paar kleinere Spiele geschrieben.<br />
Java hab ich zwar eineinhalb Jahre in der Schule gelernt, aber ich hab nie wirklich Anwendungen programmiert.<br />
Ich weiß ja nicht ob du es ausprobiert hast, aber bei mir compiliert der Code einwandfrei.<br />
Ich weiß das der Code nicht vor Schönheit strotzt (zum Beispiel keine private Variablen etc.), aber ganz so schlimm find ich ihn auch nicht.<br />
Teile des Codes hab ich aus einem Buch übernommen (das Erstellen der Rechteckwelle). Aber ich finde auch einige Teile noch stark Verbesserungswürdig, zum Beispiel das Speichern von data mit 16 bits.<br />
Aber genau aus diesen Gründen hab ich mich ja hier gemeldet. Um mir hier Hilfe zu holen.<br />
Also nenn mir doch bitte die Fehler die ich gemacht hab.<br />
Danke, Foaly</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1977891</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1977891</guid><dc:creator><![CDATA[Foaly]]></dc:creator><pubDate>Tue, 09 Nov 2010 16:09:16 GMT</pubDate></item><item><title><![CDATA[Reply to Wav Files on Tue, 09 Nov 2010 16:18:50 GMT]]></title><description><![CDATA[<blockquote>
<p>typedef class SAMPLE</p>
</blockquote>
<p>Vielleicht mag mir jemand diese Zeile erklaeren ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1977895</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1977895</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Tue, 09 Nov 2010 16:18:50 GMT</pubDate></item><item><title><![CDATA[Reply to Wav Files on Tue, 09 Nov 2010 16:19:27 GMT]]></title><description><![CDATA[<p>Ich würde bei Einbindung von <code>&lt;irgendwas.h&gt;</code> Headern, Benutzung von <code>malloc/free, sprintf, memset, FILE</code> und <code>typedef class SAMPLE { /* whatever */ } SAMPLE;</code> eher auf C (das ich nicht so recht kann) schließen. Vielleicht Forum verfehlt?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1977897</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1977897</guid><dc:creator><![CDATA[padreigh]]></dc:creator><pubDate>Tue, 09 Nov 2010 16:19:27 GMT</pubDate></item><item><title><![CDATA[Reply to Wav Files on Tue, 09 Nov 2010 16:35:04 GMT]]></title><description><![CDATA[<p>padreigh schrieb:</p>
<blockquote>
<p>Ich würde bei Einbindung von <code>&lt;irgendwas.h&gt;</code> Headern, Benutzung von <code>malloc/free, sprintf, memset, FILE</code> und <code>typedef class SAMPLE { /* whatever */ } SAMPLE;</code> eher auf C (das ich nicht so recht kann) schließen. Vielleicht Forum verfehlt?</p>
</blockquote>
<p>Das dachte ich auch und ich hätte es auch ohne zu zögern verschoben, aber dann ist mein Blick doch kurz an der sample.h hängengeblieben, wo er doch so etwas macht was man als C++ bezeichnen könnte. Es ist jedenfalls die ungewöhnlichste C/C++-Mischung die ich je gesehen habe. RAII mit malloc/free ist mal was ganz Neues.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1977916</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1977916</guid><dc:creator><![CDATA[SeppJ]]></dc:creator><pubDate>Tue, 09 Nov 2010 16:35:04 GMT</pubDate></item><item><title><![CDATA[Reply to Wav Files on Tue, 09 Nov 2010 16:53:40 GMT]]></title><description><![CDATA[<p>Foaly schrieb:</p>
<blockquote>
<p>...</p>
</blockquote>
<p>Wenn es Dir um das bloße erstellen einer WAV-Datei geht:<br />
Ich würde die Samples erstmal in eine Floatingpointformat erstellen, und erst vor dem Speichern in die Datei quantisieren.</p>
<p>Das sich bei 8 Bit die Frequenz halbiert liegt daran, dass Du sie als <code>short int</code> (16 Bit) erzeugst und dann weg schreibst. Du speicherst also doppelt so viele Samples weg wie vorhanden. Dass das so überhaupt noch ein brauchbares ergebnis liefert liegt daran, dass Du ein Rechtecksignal mit <code>0xFFFF</code> als max. Amplitude hast.</p>
<p>Bei Stereo hingegen legst Du zwar (soweit ich das blicke) einen ausreichend großen Puffer an, jedoch befüllst Du nur die Hälfte davon und schreibst auch nur die Hälfte in die Datei. Irgendwie so. <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f921.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--clown_face"
      title=":clown:"
      alt="🤡"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1977942</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1977942</guid><dc:creator><![CDATA[Tachyon]]></dc:creator><pubDate>Tue, 09 Nov 2010 16:53:40 GMT</pubDate></item><item><title><![CDATA[Reply to Wav Files on Tue, 09 Nov 2010 17:17:24 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/21632">@knivil</a>: Vielen Dank! Da ist mir tatsächlich ein grober Fehler unterlaufen. Muss wohl daher stammen, das ich in C angefangen hab und dann auf C++ umgestellt hab. (SAMPLE war vorher ne struct)</p>
<p>Ich kann den Code auch gerne in das C Forum posten, ich dacht nur dann würde ich doch wegen doppelpostens angekreidet werden. Außerdem will ich ja die Klassen etc. behalten. Auf malloc, free und memset würde ich am liebsten verzichten, nur weiß ich nicht so genau wie ich das mit new hinkriege. Also wenn ihr mir da helfen könnt wär echt super. Eine Alternative zu memset kenn ich auch nicht. Das mit dem printf benutze ich ja nur für debug ausgaben und das auch nur weil ich das noch so gewöhnt bin... FILE hab ich deshalb benutzt, weil ich mit C++ noch keine Erfahrung im Filehandeln hab und deshalb erst mal das gewohnte von C nehmen wollte. Das mit dem typedef seh ich jetzt auch, das das bescheuert war <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 />
Vielen Dank, Foaly</p>
<p>Edit 1: Oh da war ja noch ein Post. Ja also ich hab ja verstanden, das ich die Daten falsch allokiere. Könntet ihr mir sagen wie ich das am besten mache, das ich ein Floatingpointtyp nehme und dann mit new erstelle?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1977955</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1977955</guid><dc:creator><![CDATA[Foaly]]></dc:creator><pubDate>Tue, 09 Nov 2010 17:17:24 GMT</pubDate></item></channel></rss>