問題の説明

問題の説明

問題の説明

基本的には、次の画像を 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軸はミリ秒を表す必要があります
  • エンベロープの合計持続時間は約 500 ミリ秒である必要がありますが、次のようになります。
  • ユーザーが次のパラメータを設定できれば便利です。
    • 合計時間 T=A+D+S+R
    • 攻撃時間A
    • 減衰時間D
    • リリース時間R
    • サステインレベルL
  • 持続時間Sは、S = T-(A+D+R)として自動的に導出されます。

答え1

区間をチェックする条件を各部分に掛け合わせて加算することで、区分線形関数を定義できます。その後、正弦関数と区分線形関数を掛け合わせるだけです。

あなたの解決策の問題点は何ですか? 実際には、欠けている文字は 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}

関連情報