Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

26.02.2012, 18:10

Sounds Sinuswelle

Hallo alle zusammen,
Ich hab da ein kleines Problem. Ich versuche gerade ein kleines Programm zu schreiben, das ganz simple Sounds erstellt. Genauer gesagt Sinuswellen und Rechteckwellen. Bis jetzt hat alles ganz gut funktioniert. Nur ein Sache ist falsch. Die Outputdatei ist nicht ganz wie ichs erwartet hab. Sie hört sich zwar richtig an, aber wenn ich sie mit einem Programm wie Audacity öffne und meine Datei dann mit der Sinuswelle von Audacity vergleiche, habe ich gemerkt, dass mein Sound eine Wellenlänge zu kurz ist. (Gleiches gilt für die Rechteckwelle) Ich weiß nicht so richtig wie es dazu kommt. Ich vermute mal, das es irgendwie ein Rundungsfehler ist... Kann mir jemand helfen und mir sagen was falsch ist?
Vielen Dank schonmal,
Foaly

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <iostream>
#include <vector>
#include <math.h>

#define sin_d(x) (sin((x)*M_PI/180))

int main()
{
    int SampleRate = 44100; // 44100 = CD-Quality
    int Frequency = 440; // 440 = A
    float Duration = 1; // in Seconds
    int LengthInSamples = SampleRate * Duration;


    sf::Int16 Samples[LengthInSamples];

    float dist = SampleRate / Frequency;
    int dist2 = dist / 2;
    int count = LengthInSamples / dist +1;

    for(int a = 0; a < count; a++)
    {
        for(int b = 0; b < dist; b++)
        {
            if(a * dist + b >= LengthInSamples)
            {
                break;
            }

//            //Sine Wave
//            Samples[a*int(dist)+b] = sin_d(b / dist * 360.f) * 32767;

//            // Square Wave
//            if(b < dist2)
//            {
//                Samples[a*int(dist) + b] = 32767;
//            }
//            else
//            {
//                Samples[a*int(dist) + b] = -32767;
//            }
        }
    }

    sf::SoundBuffer FinalBuffer;
    FinalBuffer.LoadFromSamples(Samples, LengthInSamples, 1, SampleRate);
    FinalBuffer.SaveToFile("output.wav");

    return 0;
}

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

26.02.2012, 18:14

Bei dem Code da ist es ohnehin fraglich, wie da überhaupt Werte in die Datei kommen ;)

Ob Zeile 22 aber wirklich das machen soll, was da steht, oder ob da nicht vielleicht eine Klammer fehlt, das weiß ich aber nicht.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

3

26.02.2012, 20:47

Ja das der Code so wie er da steht nichts tut war mir schon klar. Ich wollte nur sowohl den Code für die Sinuswelle und als auch den für die Rechteckwelle posten. Man kann dann je nach Art ausklammern ;)

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

26.02.2012, 21:28

Und Zeile 21? Welchen Zweck hat die in diesem Kontext?
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

5

27.02.2012, 10:40

Also in Zeile 20 wird die "Länge" für eine komplette Schwingung berechnet. In Zeile 21 wird die "Länge" des positiven Teils einer Schwingung berechnet. Eine Schwingung besteht ja immer aus einer positiven und einer negativen Amplitude. (also bei einer Rechteckwelle wie dieser, für die Sinuswelle wird die Zeile nicht benötigt). Zeile 22 soll die Anzahl der Wellen berechnen. Der Code für die Rechteckwelle stammt aus einem Buch über Spieleprogrammierung. Ich dachte die +1 ist dafür da um Rundungsfehler zu vermeiden.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

27.02.2012, 12:01

Mir ist schon klar, was in Zeile 21 passiert. Aber wofür? Die Variable wird nie wieder benutzt.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

7

27.02.2012, 12:10

doch, in der Zeile 37, die derzeit auskommentiert ist (man soll sich ja entweder die Sinuswelle oder die "quadratische" Welle(?) einkommentieren)
allerdings könnte an dieser Stelle auch die Rechnung selbst eingesetzt werden, da es (im Moment) keinen nennenswerten Gewinn durch die Variable gibt
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

27.02.2012, 12:14

Ach, die Zeile habe ich in der Tat übersehen.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

9

27.02.2012, 12:44

Natürlich ist es sinnvoller eine Variable einzusetzten, anstatt jedes mal eine Division auszuführen. Aber darum gehts ja garnicht. Das Problem ist, das die Anzahl der Schwingungen falsch berechnet wird. Wie mach ich das korrekt? Das Grundproblem liegt ja darin, dass dist (also die Länge einer kompletten Schwingung) eine float zahl ist (in Fall oben 100,2272727...), aber der index für das Soundarray ein int sein muss. Wie caste ich das am besten, so das ich am wenigsten Rundungsfehler hab? Oder soll ich das mit round(dist) machen?

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

10

27.02.2012, 14:12

ok, die Schleifen habe ich wiederum übersehen

ein Hinweis:
die Anzahl der Wellen über die gesammte Länge erhälst du auch, indem du die Frequenz mit der Länge multiplizierst ;)

vielleicht solltest du die Wellen nicht Sampleweise durchgehen (sie sind je nach Frequenz auch keine exakte Anzahl an Samples lang), sondern die Samples durchgehen (du müsstest also keine verschachtelten Schleifen, sondern nur 1 Schleife verwenden)
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Werbeanzeige