Einen Akkord programmieren
-
;fricky schrieb:
DEvent schrieb:
Und bei einem Akkord von 3 Frequenzen?
versuch doch mal die samples für jede frequenz einzeln auszurechnen und berechne dann das kleinste gemeinsame vielfache. das dürfte der erste gemeinsame nulldurchgang nach dem start sein. was gescheiteres fällt mir jetzt auch nicht ein.
Das ist korrekt. Wenn es kein gemeinsames vielfaches außer 0 gibt (wie bei eigentlich jedem akkord in einer wohltemperierten stimmung) gibt es auch keine minimale samplezahl. in anderen stimmungen, in denen die verhältnisse der frequenzen immer rationale zahlen sind, geht das. Das ausrechnen der Schwebungsfrequenz reicht nicht aus, da die schwingung nicht zwingend translationsinvariant mit der periode der schwebungsfrequenz ist. (es mag aber eine gute näherung sein... )
-
Danke, ich denk ich habe es nun. Fuer die, die es interessiert:
public getSinus(frequencies) { int samples = sampleRate / ggt(frequencies) float[] data = new float[samples] float period for (int x = 0; x < samples; x++) { float f = 0; for (def freq : frequencies) { f = f + (Math.sin(2.0f * x * Math.PI / sampleRate * freq)); } data[x] = f / frequencies.size(); } return data }
Wobei
ggt(frequencies)
den groesten gemeinsamen Teiler aus den uebgebenen Frequenzen liefert. Dies stammt aus dem Dokument, den fricky lieferte. Wenn sich jemand fuer den ggT interessiert, ich berechne ihn so:/** * Berechnung des ggT aus einer Liste aus Zahlen. */ private static int ggt(values) { if (values.size() > 2) { return ggt(values[0], values[1..<values.size()]) } else { return values[0] } } /** * Berechnung des ggT aus einer Liste von Zahlen, wobei <code>value</code> * das erste Element aus der Liste der Zahlen ist. */ private static int ggt(value, values) { if (values.size() == 1) { return ggt(value, values[0]) } def t = ggt(values[0], values[1..<values.size()]) return t } /** * Berechnung des ggT zweier Zahlen * nach dem Euklidischen Algorithmus */ private static int ggt(int zahl1, int zahl2) { while (zahl2 != 0) { if (zahl1 > zahl2) { zahl1 = zahl1 - zahl2; } else { zahl2 = zahl2 - zahl1; } } return zahl1; }
Ich wuerde noch gerne wissen wie man die Wellen einer Eckzahn-, Vierecks-, und Saegezahnfunktion addiert, so das ich auch da einen Akkord habe.
-
DEvent schrieb:
Danke, ich denk ich habe es nun. Fuer die, die es interessiert:
//... for (def freq : frequencies) { f = f + (Math.sin(2.0f * x * Math.PI / sampleRate * freq)); } data[x] = f / frequencies.size(); //...
(...)
Ich wuerde noch gerne wissen wie man die Wellen einer Eckzahn-, Vierecks-, und Saegezahnfunktion addiert, so das ich auch da einen Akkord habe.
Indem man statt Math.sin eine andere Funktion einsetzt, und sonst alles gleich lässt.
Addieren bleibt Addieren, was soll sich da ändern?