2016-03-16 16 views
1

ich bin eine Sinuswelle mit dem folgende Verfahren zu erzeugen -Sinuswellenerzeugungsphase unter Verwendung

sampling rate = 22050; 
theta = 0; 

for (i = 0; i < N; i++) 
{ 
theta = phase * 2 * PI; 
signal[i] = amplitude * sin(theta); 
phase = phase + frequency/sampling rate; 
} 

Wenn I ein Signal mit einer Frequenz von 8000 Hz zu erzeugen, wird eine Verzerrung in der Ausgabe. Frequenzen darunter (z. B. 6000 Hz) werden korrekt erzeugt. Das 8000-Hz-Signal korrekt erzeugt, wenn ich eine Überprüfung der Phase platzieren wie so -

if (phase > 1) 
{ 
    float temp = phase - 1; 
    phase = temp; 
} 

Ich denke, es ist etwas zu tun mit der Sinusfunktion in Xcode hat, wahrscheinlich eine Reihe von Werten kann es annehmen? Derselbe Code mit und ohne Phasenumbruch hat keinen Unterschied in Matlab. Kann mir jemand erklären, was hier passiert?

+0

Wenn Sie an XCode interessiert sind, müssen Sie uns sagen, welche Typen die verschiedenen Variablen sind. Das könnte etwas zeigen. So wie es ist, kann ich nur den Typ von 'temp' sehen. –

+0

Hallo Peter, PI ist wie ein Doppel erklärt, und Theta in float. Ich habe Theta auf Double umgestellt und der Code erzeugt das 8K-Signal ohne Verzerrung. Vielen Dank! – Naveen

+0

Gut zu hören. Ich werde diese Frage jedoch als off-topic schließen und nach SO migrieren. –

Antwort

0

Ich glaube, die Berechnung sein sollte (2.0 * PI) * Frequenz/Sample

Dies gibt Ihnen die nächste Phaseninkrement in Radiant. Dieser Wert kann dann in die Sin-Funktion eingegeben werden, um die Phase zu berechnen. Beachten Sie, dass Sie die Radiantenwerte akkumulieren müssen.

Technisch ist Ihre erste Aussage falsch, wie es formuliert wird. FS/2 ist der Nyquist-Wert. Sie können darüber hinaus Frequenzen erzeugen, diese werden jedoch als Alias ​​bezeichnet.

In Bezug auf Phasenumbruch gibt es verschiedene Möglichkeiten, dies zu verwalten.

Mein Verständnis von Radianten ist, dass es "lineare" Darstellung der Phase ist, die nicht wiederholt, während sich die Phase um 2 Pi-Werte dreht. Sie haben also möglicherweise kein Wrapper-Problem, wenn Sie die Phase verwalten, indem Sie die Bogenmaße verwalten.

Glücklich durch sachkundigere Leute zu korrigieren.

0

Ich bin nicht sicher, aber ich glaube, das Problem sein könnte:

theta = phase * 2 * PI; 

Ich denke, Xcode wird das Ergebnis auf eine ganze Zahl ändern. Sie könnten versuchen wollen:

theta = phase * 2.0 * PI; 

statt, und stellen Sie sicher, dass Ihre PI Variable ein double ist.

All das macht dieses Off-Thema für DSP.SE. :-)

0

@cixelsyd hat die richtige Formel ... hier ist der Code eine Reihe von Proben einer bestimmten Frequenz auf der Grundlage einer Abtastrate

incr_theta := (2.0 * math.Pi * given_freq)/samples_per_second 

phase := -1.74 // given phase ... typically 0 note its a constant 
theta := 0.0 

for curr_sample := 0; curr_sample < number_of_samples; curr_sample++ { 

    source_buffer[curr_sample] = math.Sin(theta + phase) 

    theta += incr_theta 
} 

für Effizienz seiner besten Seite zu erstellen, die Berechnung zu bewegen von Delta Theta außerhalb der Schleife ... Hinweis Phase ist eine Konstante, da es uns nur einen anfänglichen Offset gibt