문제 설명

문제 설명

문제 설명

기본적으로 TikZ에서 다음 이미지를 다시 만들고 싶습니다.

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

이는 다음과 같은 질문으로 귀결됩니다.TikZ/pgf에서 조각별 선형 함수로 사인파를 곱하는 방법.

제한과 자유

  • 원본 이미지의 색상을 재현할 필요는 없습니다 :)
  • 외부 파일에 데이터를 저장하지 않고 이 문제를 해결하고 싶습니다.
  • 사용하게 되어 기쁩니다 pgfplots및/또는pgfmath

최소한의 (비) 작동 예

나는 TikZ/pgf에서 이 문제를 공격하는 적절한 메커니즘이 함수 선언 메커니즘이라는 느낌을 받고 있습니다(그러나 내가 옳은지 확실하지 않습니다).

아래 예에서는 조각 선형 함수의 첫 번째 부분만 구현하여 사인 함수와 곱해 보았습니다. 그러나 그렇게 하면 전체 줄거리가 사라집니다. ( TODO확인하려면 아래 예에 표시된 줄을 주석 처리하세요.)

\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}

구현을 위한 보너스 아이디어

  • 조각별 선형 함수의 신호 최대값은 항상 +1이어야 합니다.
  • x축은 밀리초를 나타내야 합니다.
  • 봉투의 총 지속 시간은 약 500ms여야 하지만:
  • 사용자가 다음 매개변수를 설정할 수 있다면 좋을 것입니다.
    • 총 시간 T=A+D+S+R
    • 공격 시간 A
    • 감쇠 시간 D
    • 출시 시간 R
    • 서스테인 레벨 L
  • 지속 시간 S는 S = T-(A+D+R)로 자동 도출됩니다.

답변1

구간을 확인하는 조건을 조각에 곱하고 이를 추가하여 조각별 선형 함수를 정의할 수 있습니다. 그런 다음 사인 함수에 조각별 선형 함수를 곱하면 됩니다.

솔루션에 어떤 문제가 있나요? 실제로 누락된 문자는 단 하나뿐입니다. 표현식 뒤에 백분율 기호를 추가하십시오 \pgfmathparse.

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

이것이 없으면 함수를 호출할 때마다 플롯 왼쪽에 공백이 추가되므로 플롯이 페이지에서 오른쪽으로 이동합니다.

여기에 이미지 설명을 입력하세요

\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}

관련 정보