{"id":214,"date":"2019-10-22T18:44:50","date_gmt":"2019-10-22T18:44:50","guid":{"rendered":"https:\/\/synthnotes.ucsd.edu\/wp4\/?p=214"},"modified":"2019-10-22T18:44:50","modified_gmt":"2019-10-22T18:44:50","slug":"clipping-methods","status":"publish","type":"post","link":"https:\/\/synthnotes.ucsd.edu\/wp4\/index.php\/2019\/10\/22\/clipping-methods\/","title":{"rendered":"Clipping Methods"},"content":{"rendered":"\n<p><span style=\"color: #23282d; font-size: 1.6em; font-weight: 600;\">What if the peak amplitude exceeds 1?<\/span><\/p>\n\n\n\n<p>If the peak amplitude exceeds 1, the result is distortion of the signal in the form of clipping. This can damage certain hardware and is best avoided.<\/p>\n\n\n\n<p>If the level above 1 is known, one can simply multiply the signal by 1 minus that value.<\/p>\n\n\n\n<p>More likely, however, whether or not the amplitude will exceed 1 is unknown. In this case there are several options: hard clipping. soft clipping, limiters, or compressors.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Hard Clipping<\/h4>\n\n\n\n<p>Hard clipping is done by limiting the maximum and minimum sample values. When a signal exceeds the limit, a hard edge is created that creates high frequency harmonics (distortion).<\/p>\n\n\n\n<pre class=\"wp-block-preformatted editor-colors lang-text\"><span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">HardClip(float *input, float *output, long samples, float limit) <\/span><\/span>\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">{<\/span><\/span>\n<span class=\"\"><span class=\"syntax--text syntax--plain\">  <span class=\"syntax--meta syntax--paragraph syntax--text\">\/\/ iterate through the samples in the block<\/span><\/span><\/span>\n  <span class=\"syntax--meta syntax--paragraph syntax--text\"><span class=\"syntax--meta syntax--paragraph syntax--text\">for(int sample = 0; sample&lt;samples; sample++) <\/span><\/span>\n  <span class=\"syntax--meta syntax--paragraph syntax--text\"><span class=\"syntax--meta syntax--paragraph syntax--text\">{<\/span><\/span>\n <span class=\"syntax--text syntax--plain\">   <span class=\"syntax--meta syntax--paragraph syntax--text\">\/\/ check if it's greater<\/span><\/span> than limit or less than -limit\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">    if(<\/span><\/span>*(input+sample)<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\"> &gt; limit)<\/span><\/span>\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--bullet-point syntax--star syntax--text\">      <span class=\"syntax--punctuation syntax--definition syntax--item syntax--text\">*<\/span>(output+sample) = limit;<\/span><\/span>\n<span class=\"syntax--text syntax--plain\">    <span class=\"syntax--meta syntax--paragraph syntax--text\">else<\/span><\/span> if(*(input+sample) &lt; -1.0 * limit)\n      *(output+sample) = -1.0 * limit;\n    else\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--bullet-point syntax--star syntax--text\">      <span class=\"syntax--punctuation syntax--definition syntax--item syntax--text\">*<\/span>(output+sample) = <\/span><\/span>*(input+sample)<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--bullet-point syntax--star syntax--text\">;<\/span><\/span>\n  }\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">}<\/span><\/span><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"633\" src=\"https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/sine_clippedSine-1024x633.png\" alt=\"\" class=\"wp-image-216\" srcset=\"https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/sine_clippedSine-1024x633.png 1024w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/sine_clippedSine-300x185.png 300w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/sine_clippedSine-768x475.png 768w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/sine_clippedSine-624x386.png 624w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/sine_clippedSine.png 1301w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>In this image, the purple line is a sine that is unclipped with a maximum amplitude of 1. The green line is a sine that is clipped at -3 dB (approx. 0.707 linear amplitude). Notice the hard edge at the clipping limit.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Soft Clipping<\/h4>\n\n\n\n<p>Soft clipping is another method of clipping that softens the edges of the clipped boundary using non-linear functions. This can be done several ways; most often, however, you\u2019ll see the use of the tangent function or quadratic functions.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Cubic Equation<\/strong> Soft Clipping<\/h4>\n\n\n\n<p>By calculating the coefficients beforehand, creating a soft clipper with the cubic equation can be relatively fast. This method, however, does not allow scaling via a gain coefficient and thus acts to shield the output from being driven too hard.<\/p>\n\n\n\n<span class=\"wp-katex-eq\" data-display=\"false\"> y = -0.5x^3 + 0x^2 + 1.5x + 0 <\/span>\n\n\n\n<p><\/p>\n\n\n\n<p>Simplified<\/p>\n\n\n\n<p><span class=\"wp-katex-eq\" data-display=\"false\">y = -0.5x^3 + 1.5x<\/span><span class=\"math\"><script type=\"math\/tex; mode=display\">y = -0.5x^3 + 1.5x <\/script><\/span><\/p>\n\n\n\n<pre class=\"wp-block-preformatted editor-colors lang-text\"><span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">QuadraticSoftClip(float *input, float *output, long samples, float limit, float gain) <\/span><\/span>\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">{<\/span><\/span>\n<span class=\"\"><span class=\"syntax--text syntax--plain\">  <span class=\"syntax--meta syntax--paragraph syntax--text\">int samplenumber = 0;<\/span><\/span><\/span>\n<span class=\"syntax--text syntax--plain\">  <span class=\"syntax--meta syntax--paragraph syntax--text\">float a = -0.5f;<\/span><\/span>\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">  float b = 0.0;<\/span><\/span>\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">  float c = 1.5f;<\/span><\/span>\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">  float d = 0.0;<\/span><\/span>\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">  float ingain;<\/span><\/span>\n \n<span class=\"syntax--text syntax--plain\">  <span class=\"syntax--meta syntax--paragraph syntax--text\">\/\/ iterate through the samples in the block<\/span><\/span>\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">  for(sample = 0; sample&lt;samples; sample++) <\/span><\/span>\n  <span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">{<\/span><\/span>\n<span class=\"syntax--text syntax--plain\">    <span class=\"syntax--meta syntax--paragraph syntax--text\">ingain = gain * *(input+sample); \/\/ get the input<\/span><\/span>\n \n<span class=\"syntax--text syntax--plain\">    <span class=\"syntax--meta syntax--paragraph syntax--text\">\/\/ if it's greater than 1, hard clip<\/span><\/span>\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">    if(ingain &gt; 1.0)<\/span><\/span>\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--bullet-point syntax--star syntax--text\">      <span class=\"syntax--punctuation syntax--definition syntax--item syntax--text\">*<\/span>(output+sample) = 1.0;<\/span><\/span>\n<span class=\"syntax--text syntax--plain\">    <span class=\"syntax--meta syntax--paragraph syntax--text\">\/\/ if it's less than -1, hardclip<\/span><\/span>\n<span class=\"syntax--text syntax--plain\">    <span class=\"syntax--meta syntax--paragraph syntax--text\">else if(ingain &lt; -1.0)<\/span><\/span>\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--bullet-point syntax--star syntax--text\">      <span class=\"syntax--punctuation syntax--definition syntax--item syntax--text\">*<\/span>(<\/span><\/span>output<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--bullet-point syntax--star syntax--text\">+sample) = -1.0;<\/span><\/span>\n<span class=\"syntax--text syntax--plain\">    <span class=\"syntax--meta syntax--paragraph syntax--text\">\/\/ else, do the softclipping<\/span><\/span>\n<span class=\"syntax--text syntax--plain\">    <span class=\"syntax--meta syntax--paragraph syntax--text\">else<\/span><\/span>\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--bullet-point syntax--star syntax--text\">      <span class=\"syntax--punctuation syntax--definition syntax--item syntax--text\">*<\/span>(<\/span><\/span>output<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--bullet-point syntax--star syntax--text\">+sample) = a * ingain * ingain * ingain<\/span><\/span>\n<span class=\"syntax--text syntax--plain\">        <span class=\"syntax--meta syntax--paragraph syntax--text\">+ b * ingain * ingain<\/span><\/span>\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">        + c * ingain<\/span><\/span>\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">        + d;<\/span><\/span>\n<span class=\"syntax--text syntax--plain\">  <span class=\"syntax--meta syntax--paragraph syntax--text\">}<\/span><\/span>\n<span class=\"syntax--text syntax--plain\"><span class=\"syntax--meta syntax--paragraph syntax--text\">}<\/span><\/span><\/pre>\n\n\n\n<p>Here is a plot of a sine wave run through this function when the input gain is 1 (0dB, purple) and 1.412 (+3dB, green). When this function is ran, you can see the distortion occur as the steepening of the angle as the waveform ascends and descends. Notice, however, that when the input gain is above unity, the function prevents it from going above 1.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"625\" src=\"https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/quadradicSoftClip-1024x625.png\" alt=\"\" class=\"wp-image-220\" srcset=\"https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/quadradicSoftClip-1024x625.png 1024w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/quadradicSoftClip-300x183.png 300w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/quadradicSoftClip-768x469.png 768w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/quadradicSoftClip-624x381.png 624w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/quadradicSoftClip.png 1364w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Cubic<\/strong> Soft Clipping Simplified<\/h4>\n\n\n\n<span class=\"wp-katex-eq\" data-display=\"false\">y = x - \\bigg( \\alpha \\cdot x^3 \\bigg )<\/span>\n\n\n\n<p><span class=\"math\"><script type=\"math\/tex; mode=display\">y = x - \\bigg( \\alpha \\cdot x^3 \\bigg ) <\/script><\/span><\/p>\n\n\n\n<p>In this function, alpha is the <em>scaling coefficient<\/em> and can vary between <code style=\"font-family: Menlo, Consolas, 'DejaVu Sans Mono', monospace;\">0<\/code> and the limit. It is typically 1\/3 and produces a clipped level of about -3dB. When the scaling coefficient is 0, the signal is passed unaffected (no clipping, no distortion) but as alpha is increased, the waveform is clipped softly.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"625\" src=\"https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/cubicSoftClip-1024x625.png\" alt=\"\" class=\"wp-image-222\" srcset=\"https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/cubicSoftClip-1024x625.png 1024w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/cubicSoftClip-300x183.png 300w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/cubicSoftClip-768x469.png 768w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/cubicSoftClip-624x381.png 624w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/cubicSoftClip.png 1364w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>Tangent Function<\/strong> Soft Clipping<\/h4>\n\n\n\n<span class=\"wp-katex-eq\" data-display=\"false\">y = \\frac{2}{\\pi} \\text{ } arctan(\\alpha \\cdot x)<\/span>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"625\" src=\"https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/atanSoftClip-1024x625.png\" alt=\"\" class=\"wp-image-224\" srcset=\"https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/atanSoftClip-1024x625.png 1024w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/atanSoftClip-300x183.png 300w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/atanSoftClip-768x469.png 768w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/atanSoftClip-624x381.png 624w, https:\/\/synthnotes.ucsd.edu\/wp4\/wp-content\/uploads\/2019\/10\/atanSoftClip.png 1364w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><span class=\"math\"><script type=\"math\/tex; mode=display\">y = \\frac{2}{\\pi} \\text{ } arctan(\\alpha \\cdot x) <\/script><\/span><\/p>\n\n\n\n<p>Notice that when <code style=\"font-family: Menlo, Consolas, 'DejaVu Sans Mono', monospace;\">alpha &gt;&gt; 10<\/code>, the function approaches infinite clipping distortion; i.e. approaches a square wave with soft edges.<\/p>\n\n\n\n<p><strong>Thoughts<\/strong><\/p>\n\n\n\n<p>Although both of these methods can produce soft clipping, the cubic functions are generally more efficient since trigonometric calculations must be performed on every sample in the tangent function.<\/p>\n\n\n\n<p>By cascading multiple softclippers, one can crudely approximate analog distortion.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What if the peak amplitude exceeds 1? If the peak amplitude exceeds 1, the result is distortion of the signal in the form of clipping. This can damage certain hardware and is best avoided. If the level above 1 is known, one can simply multiply the signal by 1 minus that value. More likely, however, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-214","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/synthnotes.ucsd.edu\/wp4\/index.php\/wp-json\/wp\/v2\/posts\/214","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/synthnotes.ucsd.edu\/wp4\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/synthnotes.ucsd.edu\/wp4\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/synthnotes.ucsd.edu\/wp4\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/synthnotes.ucsd.edu\/wp4\/index.php\/wp-json\/wp\/v2\/comments?post=214"}],"version-history":[{"count":9,"href":"https:\/\/synthnotes.ucsd.edu\/wp4\/index.php\/wp-json\/wp\/v2\/posts\/214\/revisions"}],"predecessor-version":[{"id":383,"href":"https:\/\/synthnotes.ucsd.edu\/wp4\/index.php\/wp-json\/wp\/v2\/posts\/214\/revisions\/383"}],"wp:attachment":[{"href":"https:\/\/synthnotes.ucsd.edu\/wp4\/index.php\/wp-json\/wp\/v2\/media?parent=214"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/synthnotes.ucsd.edu\/wp4\/index.php\/wp-json\/wp\/v2\/categories?post=214"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/synthnotes.ucsd.edu\/wp4\/index.php\/wp-json\/wp\/v2\/tags?post=214"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}