1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/><meta content="Docutils 0.17.1: http://docutils.sourceforge.net/" name="generator"/>
<title>01-multi-rate-processing.py - Doing processing at very high sampling rate. — Pyo 1.0.5 documentation</title>
<link href="../../_static/pygments.css" rel="stylesheet" type="text/css"/>
<link href="../../_static/agogo.css" rel="stylesheet" type="text/css"/>
<link href="../../_static/sphinx-codeautolink.css" rel="stylesheet" type="text/css"/>
<link href="../../_static/autoclasstoc.css" rel="stylesheet" type="text/css"/>
<script data-url_root="../../" id="documentation_options" src="../../_static/documentation_options.js"></script>
<script src="../../_static/jquery.js"></script>
<script src="../../_static/underscore.js"></script>
<script src="../../_static/_sphinx_javascript_frameworks_compat.js"></script>
<script src="../../_static/doctools.js"></script>
<script src="../../_static/sphinx_highlight.js"></script>
<link href="../../_static/E-PyoIcon.ico" rel="shortcut icon"/>
<link href="../../about.html" rel="author" title="About these documents"/>
<link href="../../genindex.html" rel="index" title="Index"/>
<link href="../../search.html" rel="search" title="Search"/>
<link href="02-multi-rate-synthesis.html" rel="next" title="01-multi-rate-synthesis.py - Doing synthesis at very high sampling rate."/>
<link href="index.html" rel="prev" title="19-multirate"/>
</head><body>
<div class="header-wrapper" role="banner">
<div class="header">
<div class="headertitle"><a href="../../index.html">Pyo 1.0.5 documentation</a></div>
<div aria-label="related navigation" class="rel" role="navigation">
<a accesskey="P" href="index.html" title="19-multirate">previous</a> |
<a accesskey="N" href="02-multi-rate-synthesis.html" title="01-multi-rate-synthesis.py - Doing synthesis at very high sampling rate.">next</a> |
<a accesskey="I" href="../../genindex.html" title="General Index">index</a>
</div>
</div>
</div>
<div class="content-wrapper">
<div class="content">
<div class="sidebar">
<h3>Table of Contents</h3>
<ul>
<li class="toctree-l1"><a class="reference internal" href="../../about.html">About pyo</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../download.html">Installing pyo with pip</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../compiling.html">Compiling pyo from sources</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../structure.html">Structure of the library</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../gettingstarted.html">Getting started</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../winaudioinspect.html">Configuring the audio output (Windows)</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../perftips.html">Improve performance of pyo programs</a></li>
</ul>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../api/index.html">API documentation</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../index.html">Examples</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../01-intro/index.html">First steps</a></li>
<li class="toctree-l2"><a class="reference internal" href="../02-controls/index.html">Parameter control</a></li>
<li class="toctree-l2"><a class="reference internal" href="../03-generators/index.html">Synthesis generators</a></li>
<li class="toctree-l2"><a class="reference internal" href="../04-soundfiles/index.html">Playing with soundfiles</a></li>
<li class="toctree-l2"><a class="reference internal" href="../05-envelopes/index.html">Amplitude envelopes</a></li>
<li class="toctree-l2"><a class="reference internal" href="../06-filters/index.html">Filtering</a></li>
<li class="toctree-l2"><a class="reference internal" href="../07-effects/index.html">Creating sound effects</a></li>
<li class="toctree-l2"><a class="reference internal" href="../08-dynamics/index.html">Dynamic range of audio signals</a></li>
<li class="toctree-l2"><a class="reference internal" href="../09-callbacks/index.html">Calling python functions from audio objects</a></li>
<li class="toctree-l2"><a class="reference internal" href="../10-tables/index.html">Using tables</a></li>
<li class="toctree-l2"><a class="reference internal" href="../16-midi/index.html">How to use MIDI with pyo</a></li>
<li class="toctree-l2"><a class="reference internal" href="../17-osc/index.html">How to use OSC with pyo</a></li>
<li class="toctree-l2 current"><a class="reference internal" href="index.html">Multirate audio processing</a></li>
<li class="toctree-l2"><a class="reference internal" href="../20-multicore/index.html">Multicore audio programming</a></li>
<li class="toctree-l2"><a class="reference internal" href="../21-utilities/index.html">Utilities</a></li>
<li class="toctree-l2"><a class="reference internal" href="../22-events/index.html">Events framework</a></li>
<li class="toctree-l2"><a class="reference internal" href="../23-expression/index.html">Evaluating prefix expression</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../tutorials/index.html">Advanced tutorials</a></li>
</ul>
<div role="search">
<h3 style="margin-top: 1.5em;">Search</h3>
<form action="../../search.html" class="search" method="get">
<input name="q" type="text"/>
<input type="submit" value="Go"/>
</form>
</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="multi-rate-processing-py-doing-processing-at-very-high-sampling-rate">
<h1>01-multi-rate-processing.py - Doing processing at very high sampling rate.<a class="headerlink" href="#multi-rate-processing-py-doing-processing-at-very-high-sampling-rate" title="Permalink to this heading">¶</a></h1>
<p>In numerical audio computing, it is sometimes useful to be able to process
a signal with much more timing precision than what the usual sampling rates
offer. A typical case is when the effect applied to the sound adds a lot of
harmonics. Higher harmonics will quickly wrap around the Nyquist frequency,
producing aliasing in the output signal. The solution is to increase the
sampling rate, so the nyquist frequency, and to use anti-aliasing filters
when converting from one rate to another.</p>
<p>Pyo allows to compute chunks of code at different sampling rates than the
one with which the server was started. You should do this only for the objects
you need to process with a higher sampling rate, without changing the server’s
sampling rate, otherwise the program will be very CPU consuming.</p>
<p>You start a new resampling block with the method:</p>
<blockquote>
<div><p>Server.beginResamplingBlock(x)</p>
</div></blockquote>
<p>where <cite>x</cite>, a power-of-two, is the resampling factor. A negative power-of-two
will start a downsampling block of code.</p>
<p>To close the block, simply call:</p>
<blockquote>
<div><p>Server.endResamplingBlock()</p>
</div></blockquote>
<p>Everything between the two calls will be computed with the new sampling rate.</p>
<p>Audio signals must be resampled before used with a different sampling rate.
The Resample object does this. Inside a resampling block, it will convert the
signal to the new sampling rate, and outside the resampling block, it will
convert the signal back to the original sampling rate. Its <cite>mode</cite> argument lets
choose the quality of the interpolation/decimation filter used to resample the
signal.</p>
<div class="highlight-python notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <a class="sphinx-codeautolink-a" href="../../api/alphabetical.html#module-pyo" title="pyo"><span class="nn">pyo</span></a> <span class="kn">import</span> <span class="o">*</span>
<span class="c1"># We create a new class for our upsampled distortion effect.</span>
<span class="k">class</span> <span class="nc">UpSampDisto</span><span class="p">:</span>
<span class="sd">"""</span>
<span class="sd"> Upsampled distortion effect.</span>
<span class="sd"> :Args:</span>
<span class="sd"> input: PyoObject</span>
<span class="sd"> The signal to process.</span>
<span class="sd"> drive: float or PyoObject, optional</span>
<span class="sd"> Amount of distortion applied to the signal, between 0 and 1.</span>
<span class="sd"> upfactor: int (power-of-two), optional</span>
<span class="sd"> Resampling factor.</span>
<span class="sd"> filtmode: int, optional</span>
<span class="sd"> The interpolation/decimation mode. See Resample's man page</span>
<span class="sd"> for details.</span>
<span class="sd"> """</span>
<span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">input</span><span class="p">,</span> <span class="n">drive</span><span class="o">=</span><span class="mf">0.5</span><span class="p">,</span> <span class="n">upfactor</span><span class="o">=</span><span class="mi">8</span><span class="p">,</span> <span class="n">filtmode</span><span class="o">=</span><span class="mi">32</span><span class="p">):</span>
<span class="c1"># The InputFader object lets change its input signal without clicks.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">input</span> <span class="o">=</span> <a class="sphinx-codeautolink-a" href="../../api/classes/internals.html#pyo.InputFader" title="pyo.lib._core.InputFader"><span class="n">InputFader</span></a><span class="p">(</span><span class="nb">input</span><span class="p">)</span>
<span class="c1"># Convert the drive argument to audio signal.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">drive</span> <span class="o">=</span> <a class="sphinx-codeautolink-a" href="../../api/classes/controls.html#pyo.Sig" title="pyo.lib._core.Sig"><span class="n">Sig</span></a><span class="p">(</span><span class="n">drive</span><span class="p">)</span>
<span class="c1"># Get a reference to the audio server.</span>
<span class="n">server</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">drive</span><span class="o">.</span><span class="n">getServer</span><span class="p">()</span>
<span class="c1"># Start an upsampled block of code.</span>
<span class="n">server</span><span class="o">.</span><span class="n">beginResamplingBlock</span><span class="p">(</span><span class="n">upfactor</span><span class="p">)</span>
<span class="c1"># Resample the audio signals. Because the drive signal is only a</span>
<span class="c1"># control signal, a linear interpolation is enough. The input</span>
<span class="c1"># signal uses a much better filter to eliminate aliasing artifacts.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">inputUp</span> <span class="o">=</span> <a class="sphinx-codeautolink-a" href="../../api/classes/utils.html#pyo.Resample" title="pyo.lib.utils.Resample"><span class="n">Resample</span></a><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">input</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="n">filtmode</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">driveUp</span> <span class="o">=</span> <a class="sphinx-codeautolink-a" href="../../api/classes/utils.html#pyo.Resample" title="pyo.lib.utils.Resample"><span class="n">Resample</span></a><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">drive</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
<span class="c1"># Apply the distortion effect.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">disto</span> <span class="o">=</span> <a class="sphinx-codeautolink-a" href="../../api/classes/effects.html#pyo.Disto" title="pyo.lib.effects.Disto"><span class="n">Disto</span></a><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">inputUp</span><span class="p">,</span> <span class="n">drive</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">driveUp</span><span class="p">)</span>
<span class="c1"># Close the upsampled block.</span>
<span class="n">server</span><span class="o">.</span><span class="n">endResamplingBlock</span><span class="p">()</span>
<span class="c1"># Convert back the distorted signal to the current sampling rate.</span>
<span class="c1"># Again, we use a good decimination filter to eliminate aliasing.</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span> <span class="o">=</span> <a class="sphinx-codeautolink-a" href="../../api/classes/utils.html#pyo.Resample" title="pyo.lib.utils.Resample"><span class="n">Resample</span></a><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">disto</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="n">filtmode</span><span class="p">,</span> <span class="n">mul</span><span class="o">=</span><span class="mf">0.5</span><span class="p">)</span>
<span class="c1"># Define some useful methods.</span>
<span class="k">def</span> <span class="nf">setInput</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">fadetime</span><span class="o">=</span><span class="mf">0.05</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">input</span><span class="o">.</span><span class="n">setInput</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">fadetime</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">setDrive</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">drive</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">x</span>
<span class="k">def</span> <span class="nf">out</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">chnl</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<span class="bp">self</span><span class="o">.</span><span class="n">output</span><span class="o">.</span><span class="n">out</span><span class="p">(</span><span class="n">chnl</span><span class="p">)</span>
<span class="k">return</span> <span class="bp">self</span>
<span class="k">def</span> <span class="nf">sig</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">output</span>
<span class="c1">### Usage example ###</span>
<span class="n">s</span> <span class="o">=</span> <a class="sphinx-codeautolink-a" href="../../api/classes/server.html#pyo.Server" title="pyo.lib.server.Server"><span class="n">Server</span></a><span class="p">()</span><span class="o">.</span><span class="n">boot</span><span class="p">()</span>
<span class="c1"># Two different sources for testing, a sine wave and a flute melody.</span>
<a class="sphinx-codeautolink-a" href="../../api/classes/generators.html#pyo.Sine" title="pyo.lib.generators.Sine"><span class="n">src1</span></a> <span class="o">=</span> <a class="sphinx-codeautolink-a" href="../../api/classes/generators.html#pyo.Sine" title="pyo.lib.generators.Sine"><span class="n">Sine</span></a><span class="p">(</span><span class="n">freq</span><span class="o">=</span><span class="mi">722</span><span class="p">,</span> <span class="n">mul</span><span class="o">=</span><span class="mf">0.7</span><span class="p">)</span>
<span class="n">src1</span><span class="o">.</span><span class="n">ctrl</span><span class="p">([</span><a class="sphinx-codeautolink-a" href="../../api/classes/map.html#pyo.SLMapFreq" title="pyo.lib._maps.SLMapFreq"><span class="n">SLMapFreq</span></a><span class="p">(</span><span class="mi">722</span><span class="p">)],</span> <span class="n">title</span><span class="o">=</span><span class="s2">"Sine frequency"</span><span class="p">)</span>
<a class="sphinx-codeautolink-a" href="../../api/classes/players.html#pyo.SfPlayer" title="pyo.lib.players.SfPlayer"><span class="n">src2</span></a> <span class="o">=</span> <a class="sphinx-codeautolink-a" href="../../api/classes/players.html#pyo.SfPlayer" title="pyo.lib.players.SfPlayer"><span class="n">SfPlayer</span></a><span class="p">(</span><span class="s2">"../snds/flute.aif"</span><span class="p">,</span> <span class="n">loop</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="c1"># Input source interpolation.</span>
<a class="sphinx-codeautolink-a" href="../../api/classes/utils.html#pyo.Interp" title="pyo.lib.utils.Interp"><span class="n">src</span></a> <span class="o">=</span> <a class="sphinx-codeautolink-a" href="../../api/classes/utils.html#pyo.Interp" title="pyo.lib.utils.Interp"><span class="n">Interp</span></a><span class="p">(</span><a class="sphinx-codeautolink-a" href="../../api/classes/generators.html#pyo.Sine" title="pyo.lib.generators.Sine"><span class="n">src1</span></a><span class="p">,</span> <a class="sphinx-codeautolink-a" href="../../api/classes/players.html#pyo.SfPlayer" title="pyo.lib.players.SfPlayer"><span class="n">src2</span></a><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">src</span><span class="o">.</span><span class="n">ctrl</span><span class="p">([</span><a class="sphinx-codeautolink-a" href="../../api/classes/map.html#pyo.SLMap" title="pyo.lib._maps.SLMap"><span class="n">SLMap</span></a><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="s2">"lin"</span><span class="p">,</span> <span class="s2">"interp"</span><span class="p">,</span> <span class="mi">0</span><span class="p">)],</span> <span class="n">title</span><span class="o">=</span><span class="s2">"Source: sine <=> flute"</span><span class="p">)</span>
<span class="c1"># Control for the drive parameter of the distortion.</span>
<a class="sphinx-codeautolink-a" href="../../api/classes/controls.html#pyo.Sig" title="pyo.lib._core.Sig"><span class="n">drv</span></a> <span class="o">=</span> <a class="sphinx-codeautolink-a" href="../../api/classes/controls.html#pyo.Sig" title="pyo.lib._core.Sig"><span class="n">Sig</span></a><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="n">drv</span><span class="o">.</span><span class="n">ctrl</span><span class="p">(</span><span class="n">title</span><span class="o">=</span><span class="s2">"Drive"</span><span class="p">)</span>
<span class="c1"># Distortion at current sampling rate.</span>
<a class="sphinx-codeautolink-a" href="../../api/classes/effects.html#pyo.Disto" title="pyo.lib.effects.Disto"><span class="n">dist</span></a> <span class="o">=</span> <a class="sphinx-codeautolink-a" href="../../api/classes/effects.html#pyo.Disto" title="pyo.lib.effects.Disto"><span class="n">Disto</span></a><span class="p">(</span><a class="sphinx-codeautolink-a" href="../../api/classes/utils.html#pyo.Interp" title="pyo.lib.utils.Interp"><span class="n">src</span></a><span class="p">,</span> <span class="n">drive</span><span class="o">=</span><a class="sphinx-codeautolink-a" href="../../api/classes/controls.html#pyo.Sig" title="pyo.lib._core.Sig"><span class="n">drv</span></a><span class="p">,</span> <span class="n">mul</span><span class="o">=</span><span class="mf">0.5</span><span class="p">)</span>
<span class="c1"># Distortion with increased sampling rate.</span>
<span class="n">updist</span> <span class="o">=</span> <span class="n">UpSampDisto</span><span class="p">(</span><a class="sphinx-codeautolink-a" href="../../api/classes/utils.html#pyo.Interp" title="pyo.lib.utils.Interp"><span class="n">src</span></a><span class="p">,</span> <a class="sphinx-codeautolink-a" href="../../api/classes/controls.html#pyo.Sig" title="pyo.lib._core.Sig"><span class="n">drv</span></a><span class="p">)</span>
<span class="c1"># Interpolator to compare the two processes.</span>
<span class="n">output</span> <span class="o">=</span> <a class="sphinx-codeautolink-a" href="../../api/classes/utils.html#pyo.Interp" title="pyo.lib.utils.Interp"><span class="n">Interp</span></a><span class="p">(</span><a class="sphinx-codeautolink-a" href="../../api/classes/effects.html#pyo.Disto" title="pyo.lib.effects.Disto"><span class="n">dist</span></a><span class="p">,</span> <span class="n">updist</span><span class="o">.</span><span class="n">sig</span><span class="p">(),</span> <span class="mi">0</span><span class="p">,</span> <span class="n">mul</span><span class="o">=</span><span class="mf">0.5</span><span class="p">)</span><span class="o">.</span><span class="n">out</span><span class="p">()</span>
<span class="n">output</span><span class="o">.</span><span class="n">ctrl</span><span class="p">([</span><a class="sphinx-codeautolink-a" href="../../api/classes/map.html#pyo.SLMap" title="pyo.lib._maps.SLMap"><span class="n">SLMap</span></a><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="s2">"lin"</span><span class="p">,</span> <span class="s2">"interp"</span><span class="p">,</span> <span class="mi">0</span><span class="p">)],</span> <span class="n">title</span><span class="o">=</span><span class="s2">"Up Sampling: without <=> with"</span><span class="p">)</span>
<a class="sphinx-codeautolink-a" href="../../api/classes/analysis.html#pyo.Spectrum" title="pyo.lib.analysis.Spectrum"><span class="n">sp</span></a> <span class="o">=</span> <a class="sphinx-codeautolink-a" href="../../api/classes/analysis.html#pyo.Spectrum" title="pyo.lib.analysis.Spectrum"><span class="n">Spectrum</span></a><span class="p">(</span><span class="n">output</span><span class="p">)</span>
<span class="n">s</span><span class="o">.</span><span class="n">gui</span><span class="p">(</span><span class="nb">locals</span><span class="p">())</span>
</pre></div>
</div>
</section>
<div class="clearer"></div>
</div>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
</div>
<div class="footer-wrapper">
<div class="footer">
<div class="left">
<div aria-label="related navigaton" role="navigation">
<a href="index.html" title="19-multirate">previous</a> |
<a href="02-multi-rate-synthesis.html" title="01-multi-rate-synthesis.py - Doing synthesis at very high sampling rate.">next</a> |
<a href="../../genindex.html" title="General Index">index</a>
</div>
<div aria-label="source link" role="note">
</div>
</div>
<div class="right">
<div class="footer" role="contentinfo">
© Copyright 2021, Olivier Bélanger.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 5.3.0.
</div>
</div>
<div class="clearer"></div>
</div>
</div>
</body>
</html>
|