Problembeschreibung

Problembeschreibung

Problembeschreibung

Ich möchte grundsätzlich folgendes Bild in TikZ nachbilden:

http://krashan.ppa.pl/articles/u1synth/adsr.png

Es läuft auf die Frage hinaus,So multiplizieren Sie eine Sinuswelle mit einer stückweise linearen Funktion in TikZ/pgf.

Einschränkungen und Freiheiten

  • Farben vom Originalbild müssen nicht reproduziert werden :)
  • Ich möchte dieses Problem lösen, ohne Daten in einer externen Datei speichern zu müssen
  • Gerne nutze ich pgfplotsund/oderpgfmath

Minimales (nicht) funktionierendes Beispiel

Ich habe das Gefühl, dass der geeignete Mechanismus zum Beheben dieses Problems in TikZ/pgf der Funktionsdeklarationsmechanismus ist (aber ich bin nicht sicher, ob ich Recht habe).

Im folgenden Beispiel habe ich nur den ersten Teil der stückweise linearen Funktion implementiert, um zu versuchen, sie mit einer Sinusfunktion zu multiplizieren. Wenn ich dies tue, verschwindet jedoch das gesamte Diagramm (kommentieren Sie TODOzur Bestätigung die im folgenden Beispiel markierte Zeile aus).

\documentclass{article}

\usepackage{pgfplots}

% Declare (first part of) piecewise linear function
\pgfmathdeclarefunction{p}{1}{%
  \pgfmathparse{ ((x>=0) && (x<=50))*x/50 }
}

\begin{document}

\begin{tikzpicture}[domain=0:500]

  \begin{axis}

    % Plot piecewise linear function
    \addplot[thick, blue]{p(x)};

    % Plot sine function
    \addplot[red, samples=500, smooth]{sin(20*x)};

    % Plot product of both. TODO: Makes entire plot disappear
    %\addplot[thick, green, samples=500, smooth]{sin(30*x)*p(x)};

  \end{axis}

\end{tikzpicture}

\end{document}

Bonusideen zur Umsetzung

  • Das Signalmaximum einer stückweise linearen Funktion sollte immer +1 sein.
  • Die x-Achse sollte Millisekunden darstellen
  • Die Gesamtdauer der Hüllkurve sollte etwa 500 ms betragen, aber:
  • Es wäre schön, wenn folgende Parameter vom Benutzer eingestellt werden könnten:
    • Gesamtzeit T=A+D+S+R
    • Angriffszeit A
    • Abklingzeit D
    • Freigabezeit R
    • Haltepegel L
  • Die Haltezeit S ergibt sich automatisch aus S = T-(A+D+R)

Antwort1

Eine stückweise lineare Funktion kann man definieren, indem man die Stücke mit den Bedingungen multipliziert, die das Intervall prüfen, und diese addiert. Anschließend muss man nur noch die Sinusfunktion mit der stückweise linearen Funktion multiplizieren.

Was ist das Problem mit Ihrer Lösung? Tatsächlich fehlt nur ein einziges Zeichen: Fügen Sie nach dem \pgfmathparseAusdruck ein Prozentzeichen hinzu:

\pgfmathdeclarefunction{p}{1}{%
  \pgfmathparse{ ((x>=0) && (x<=50))*x/50 }% <<<<<<<<
}

Ohne sie wird bei jedem Aufruf der Funktion links vom Diagramm ein Leerzeichen hinzugefügt, sodass das Diagramm nach rechts aus der Seite herausrutscht.

Bildbeschreibung hier eingeben

\documentclass[border=5pt]{standalone}
\usepackage{pgfplots}
\usetikzlibrary{calc}

\pgfmathdeclarefunction{ADSR}{1}{%
  \pgfmathparse
    {(                  #1<=\pA      )*(#1/\pA)                          +%
     (and(#1>\pA      , #1<=(\pA+\pD))*(#1*(-\pL)/\pD + 1 + \pA*\pL/\pD) +%
     (and(#1>(\pA+\pD), #1<=(\pT-\pR))*(1-\pL)                           +%
     (and(#1>(\pT-\pR), #1<=\pT      )*((1-\pL)/\pR*(-#1+\pT))
    }%
}

\begin{document}
\begin{tikzpicture}
\newcommand\pT{500} % total
\newcommand\pA{100} % attack
\newcommand\pD{100} % decay
\newcommand\pR{100} % release
\newcommand\pL{0.2} % sustain level
\newcommand\pF{50}  % frequency (not in Hz, but proportional)
  \begin{axis}[x=0.2mm,y=2cm]
    \addplot[domain=0:\pT, green, samples=5000] {ADSR(x)*sin(\pF*x)};
    \addplot[domain=0:\pT, red, samples=100] {ADSR(x)};
  \end{axis}
\end{tikzpicture}
\end{document}

verwandte Informationen