0 Daumen
858 Aufrufe

Aufgabe:

Mit Hilfe von sinusförmigen Funktionen

x(n) = A cos(2πfnT + φ) (1)

Signale erzeugt und ausgegeben. Hierbei ist T =1/fs das Abtastintervall mit der Abtastfrequenz fs = 8000 Hz, n ist der Zeitindex des Signals, f die gewünschte Frequenz, φ eine zufällige Phase im Bereich von 0 bis 2π und A die Amplitude.

a) Erstellen Sie eine Funktion, die ein Sinussignal gegebener Frequenz frequency, Abtastfrequenz fs, zeitlicher Dauer in Sekunden duration und Amplitude A erzeugt.

Benutzen Sie [sinusoid] = createWaveform(frequency,fs,duration,A) als Funktionskopf. Schreiben Sie das Skript welches Ihre Funktion testet, indem zwei Signale mit den Frequenzen f1 = 440 Hz und f2 = 1000 Hz und einer Dauer
von 2 Sekunden erzeugt und mittels der Funktion sound augegeben werden.

b) In der Musik ist der Grundton A4 mit 440 Hz festgelegt. Eine Oktave höher bedeutet eine Verdopplung der Frequenz und eine Oktave tiefer eine Halbierung der Frequenz. Eine Oktave beinhaltet 12 Töne, so dass das Frequenzverhältnis zwischen zwei benachbarten Tönen r =12√2 (2) beträgt.

So hat zum Beispiel das C4, welches 9 Töne unter A4 liegt, eine Frequenz von etwa 261,6 Hz.

Eine Note im Notenblatt definiert zusätzlich zur Tonhöhe auch die Tondauer in den relativen Längen von 1, 1/2, 1/4 und so weiter.

Schreiben Sie die Funktion

[tone] = note(keynum,relDuration,fullDuration,fs)

die ein Signal zu einer Note generiert. Hierbei ist keynum die Tastennummer gemäß Abbildung 1, relDuration die Notenlänge und fullDuration die vorgegebene Dauer einer ganzen Note in Sekunden.

c) Ein Signal, welches mehrere Töne hintereinander beinhaltet, kann erzeugt werden, indem die Signale der einzelnen Noten zu einem Vektor konkateniert werden. Schreiben Sie das Skript AufgabeC.m, in dem die Tonleiter (weiße Tasten einer Oktave) vorwärts und rückwärts abgespielt wird.

d) Eine so erzeugt Tonfolge klingt sehr künstlich. Ein natürlicher Klang kann erreicht werden, indem die Amplitude über die Zeit variiert wird. Ein einfaches Modell ist dabei die ADSRKurve aus Abbildung 3. Sie definiert 4 Phasen, die die Intensität des Tastenanschlags und das Ausschwingen grob beschreiben. Die vier Phasen sind: A – attack, D – delay, S – sustain und R – release.

Abbildung 3: ADSR-Kurve.

Schreiben Sie eine Funktion, die eine solche Hüllkurve für eine gegebene Notenlänge generiert. Benutzen Sie den Funktionskopf

[E] = envel(relDuration,fullDuration,fs)

Finden Sie sinnvolle Parameter für die ADSR-Kurve (Hinweis: Passen Sie die Länge von S an die Länge des Tons an). Modifizieren Sie Ihre Funktion note so, dass die Hüllkurve mit dem generierten Signal punktweise multipliziert wird.

e) Schreiben Sie das Skript AufgabeE.m, welches das Musikstück „Für Elise “von Beethoven aus Abbildung 4 abspielt. Dazu muss zunächst für jede Melodielinie ein separater Signalvektor erzeugt werden. Die beiden Stimmen können dann durch Vektoraddition kombiniert werden. Achten Sie dabei auf Synchronität der beiden Melodielinien, indem für vorgegebene Pausen entsprechende Nullen in den Signalvektoren eingefügt werden.

Abbildung 4: Auszug aus Beethovens „Für Eli"


Mein Problem ist nun, dass mein Skript keine Töne abspielt, die auch nur ähnlich zu denen eines Pianos sind.

sound(createWaveform(440,8000,2,5));

sound(createWaveform(1000,8000,2,5));


sound(note(40,2,2,8000));
sound(note(42,2,2,8000));
sound(note(44,2,2,8000));
sound(note(45,2,2,8000));
sound(note(47,2,2,8000));
sound(note(49,2,2,8000));
sound(note(51,2,2,8000));
sound(note(49,2,2,8000));
sound(note(47,2,2,8000));
sound(note(45,2,2,8000));
sound(note(44,2,2,8000));
sound(note(42,2,2,8000));
disp(note(40,2,2,8000));


function [sinusoid] = createWaveform(frequency,fs,duration,A)
    n = linspace(0,duration-1/fs,duration*fs);
    [sinusoid] = A*cos(2*pi*frequency*n*(1/fs)+(2*pi).*rand(1,1));
end

%12. Wurzel von 2 * Diff + wenn größer als Grundton
%12. Wurzel von 2 * Diff - wenn kleiner als Grundton
%nthroot(x,n)
function [tone] = note(keynum,relDuration,fullDuration,fs)
  basetone = 440;
  frequency = basetone * nthroot(2,12)^(keynum-49);
[tone]=createWaveform(frequency,fs,relDuration*fullDuration,1);
end

Das ganze hört sich an wie verzerrte Signale, die sich egal auf welcher Frequenz, alle gleich anhören.

Woran könnte es liegen und wo liegt mein Fehler?

Avatar von

1 Antwort

0 Daumen

Antwort mit KI erzeugt

Analyse des Problems

Basierend auf Ihrer Beschreibung und dem bereitgestellten Skript scheinen verschiedene Faktoren für das Problem verantwortlich zu sein, dass die erzeugten Töne nicht wie erwartet klingen. Hier einige mögliche Gründe und Lösungsvorschläge:

1. Mathematische Repräsentation des Sinussignals: Ihr Code für createWaveform scheint korrekt zu sein, indem eine zufällige Phase hinzugefügt wird. Dies könnte jedoch zu unnatürlich klingenden Tönen führen, da jedes Mal, wenn ein Ton generiert wird, eine unterschiedliche Phase verwendet wird. Für eine stabilere Klangqualität könnte eine feste Phase (z.B. \(\phi = 0\)) verwendet werden.

2. ADS(Hüllkurven)-Implementierung Fehlt:
- Sie haben erwähnt, dass eine Anpassung der Amplitude über die Zeit notwendig ist, um ein realistischeres Klangbild zu erzeugen, aber es scheint, als wäre die Implementierung der ADSR-Hüllkurve (Attack, Decay, Sustain, Release) in Ihrem Code nicht vorhanden. Ohne diese Hüllkurvenmodulation klingen die erzeugten Töne wahrscheinlich zu mechanisch und nicht wie ein echtes Piano.

3. Parameter für Notenlänge: Es sieht so aus, als ob in Ihrer note-Funktion die relDuration (relative Dauer) direkt mit fullDuration (Dauer einer ganzen Note) multipliziert wird, was potenziell die Intention hinter den unterschiedlichen Notenwerten (z.B. ganze Note, halbe Note) verwässert.

4. Frequenzberechnung:
- Die Berechnung der Frequenz basierend auf der Taste (keynum) und dem Referenzton A4 = 440 Hz erscheint korrekt. Das Problem scheint nicht hier zu liegen, vorausgesetzt die Werte für keynum sind korrekt zugeordnet.

Lösungen und Verbesserungen

Um die Genauigkeit und Qualität der erzeugten Töne zu verbessern, beachten Sie folgende Punkte:

- Feste Phase in createWaveform:
Verwenden Sie eine feste Phase, z.B. \( \phi = 0 \), um die Konsistenz der Töne zu verbessern.

- Implementierung der ADSR-Hüllkurve:
Fügen Sie die Logik für die ADSR-Hüllkurve hinzu und wenden Sie diese auf jedes generierte Signal an, bevor Sie es ausgeben. Dies simuliert die natürliche Art und Weise, wie Töne auf einem echten Instrument beginnen und enden.

- Überprüfung der Notendauer:
Stellen Sie sicher, dass die Berechnung der Notendauer beabsichtigt ist und im Einklang mit dem steht, was musikalisch ausgedrückt werden soll. Die relDuration sollte korrekt in die Gesamtzeit des Signals übersetzt werden.

Hier ist ein beispielhafter Ansatz zur Implementierung der ADSR-Hüllkurve:

matlab
function [E] = envel(relDuration, fullDuration, fs)
    % Beispielhafte ADSR-Parameter
    A_time = 0.1; % Anstiegszeit (Attack)
    D_time = 0.2; % Abklingzeit (Decay)
    S_level = 0.7; % Sustain-Niveau
    R_time = 0.2; % Ausschwingzeit (Release)
    
    % Berechnung der Länge jeder Phase in Samples
    A_samples = floor(A_time * fs);
    D_samples = floor(D_time * fs);
    R_samples = floor(R_time * fs);
    S_samples = max(floor(relDuration * fullDuration * fs) - A_samples - D_samples - R_samples, 0); % Sustain so anpassen, dass Gesamtlänge passt
    
    % Generierung der ADSR-Kurve
    A_curve = linspace(0, 1, A_samples);
    D_curve = linspace(1, S_level, D_samples);
    S_curve = S_level * ones(1, S_samples);
    R_curve = linspace(S_level, 0, R_samples);
    
    E = [A_curve, D_curve, S_curve, R_curve];
end


Beachten Sie, dass die tatsächlichen Parameter der ADSR-Kurve (Attack, Decay, Sustain Level und Release) je nach Wunsch geändert werden sollten, um verschiedene Arten von Klangdynamiken zu simulieren. Anschließend sollten Sie diese Hüllkurve mit Ihrem erzeugten Sinussignal multiplizieren, um den Klang natürlicher zu gestalten.

Durch die Anwendung dieser Korrekturen und Verbesserungen sollten Sie in der Lage sein, deutlich realistischer klingende Pianotöne zu erzeugen.
Avatar von 2,9 k

Ein anderes Problem?

Stell deine Frage

Willkommen bei der Stacklounge! Stell deine Frage einfach und kostenlos

x
Made by a lovely community