Re: An idea for an entirely new effect -- warning, long post
Robert Hänggi <[email protected]> Mon, 17 May 2021 14:30:22 +0200
| Newsgroups | gmane.comp.audio.audacity.devel |
|---|---|
| Message-ID | <CAJhgUZ0W2Jmd1fO8RWR0D6eHRAvLTmYgUUGFNTt38rNj51JZxA@mail.gmail.com> |
Small correction: To get the same amplitude as the original, we have also to take the square root at the end. The correct last line is therefore: (s-sqrt (sum (s-square (h1 *track*)) (s-square (h2 *track*)))) Sorry for that. Robert On 17/05/2021, Robert Hänggi <[email protected]> wrote: > On 17/05/2021, Steve Fiddle <[email protected]> wrote: >> Interesting stuff. >> The final line of Robert's "squaring two signals and adding them >> together" >> assumes that the selected audio is a mono track. >> For a two channel track it needs to be: >> (sum (s-square (h1 (aref *track* 0))) (s-square (h2 (aref *track* 1)))) >> > We will use multichan-expand in the end so that it works with either > track type, unless the stereo track effect has some linked parameter > e.g. feeding L back in to R... > Robert > >> Steve >> >> On Mon, 17 May 2021 at 09:10, Robert Hänggi <[email protected]> >> wrote: >>> >>> Here is the plug-in: >>> >>> https://www.dropbox.com/t/AK66Xx2uxpvatEOH >>> It works only on stereo tracks. >>> The idea is to rotate the right channel by 90° at each application. >>> So, at the second time, you have basically inverted the right track >>> and at the forth, it will be back to the original state (although it >>> won't be exactly the original due to the nature of the IIR/HT with the >>> needed one sample delay). >>> In other words, the left and right channels represent the real and >>> imaginary part of the signal, especially if the track is dual-mono >>> (same content in both channels). >>> Let's look at the last line: >>> (vector (h1 (aref *track* 0)) (h2 (aref *track* 1))) >>> The signal that comes from the track is always *track*. >>> If it is mono, you can work with it as it is. >>> If it is stereo however, it is represented as an array with two >>> elements. Aref references the left (=0) and right (=1) channel. >>> The function h1 creates the original signal, the real part. Of course, >>> this would normally not be necessary but we need to adapt it for the >>> delay introduced through the IIR (ideally, the delay would be only >>> half a sample for h2). >>> the function vector creates again an array from the two sounds. >>> OK, let's assume that we work only with a mono track. >>> We could for instance use the Hilbert transform to return the >>> amplitude envelope of the signal. >>> This is done by squaring the two signals and adding them together. >>> First, create a mono track with e.g. a chirp or some other signal or >>> file. >>> >>> Copy all the text from the plug-in into the Nyquist prompt. >>> replace the line with '(vector...' with the following: >>> >>> (defun s-square (sig) >>> (mult sig sig)) >>> (sum (s-square (h1 *track*)) (s-square (h2 *track*))) >>> >>> (you can save this as a preset if you go to the manage button) >>> >>> Apply the effect. You should (almost) hear nothing because the track >>> represents now the amplitude instead of the signal, in other words, >>> just plenty of DC offset. >>> >>> HTH >>> Robert >>> >>> >>> >>> On 17/05/2021, Federico Miyara <[email protected]> wrote: >>> > >>> > Petr, >>> > >>> > There is a free program called SPEAR that you can download here: >>> > >>> > http://www.klingbeil.com/spear/downloads/ >>> > <http://www.klingbeil.com/spear/downloads/> >>> > >>> > It models a signal by detecting partials and representing their time >>> > evolution by sine waves >>> > >>> > I'm not sure it is sufficiently accessible, but it allows several >>> > types >>> > of edits such as the partial displacemente you mention. >>> > >>> > Regards, >>> > >>> > Federico Miyara >>> > >>> > >>> > >>> > On 16/05/2021 02:34, Petr Pařízek via audacity-devel wrote: >>> >> Hello to all of you, >>> >> >>> >> to introduce myself a bit, I'm a piano player and a music composer >>> >> and >>> >> a music theorist who is very interested in things regarding digital >>> >> audio effects. Many years ago, I wrote a lot of small programs for >>> >> the >>> >> old QBasic for DOS and currently I'm planning to start learning >>> >> Nyquist in some near future. >>> >> FYI, I'm blind and that's why, when manipulating with the contents of >>> >> a sound file, I often combine listening to the sound and converting >>> >> the sample values to text, if I want to know more about some tiny >>> >> details (where most people would probably zoom in the waveform). >>> >> >>> >> I'm thinking of a possible new effect which might one day be >>> >> implemented in Audacity. Currently, I'm absolutely unsure whether >>> >> this >>> >> kind of effect could be coded in Nyquist at all or whether the only >>> >> way is to write such complex stuff in C or whether there's yet >>> >> another >>> >> way of doing it which I don't happen to know about. But I'd be >>> >> super-happy if I were told that this thing could indeed be coded in >>> >> Nyquist. >>> >> Therefore, I'll do my best to describe the effect, as some say, "in >>> >> prose", and hope my description is understandable for you all. In >>> >> case >>> >> it isn't, I'm definitely open to clarification. I'll be very happy to >>> >> know your opinions about what might be the best way to code this. >>> >> I'd like to stress that I'm not intending this effect for real-time >>> >> performance at all, even though the description of the effect itself >>> >> might make you think I am. I'm not even suggesting something like a >>> >> "Preview" facility because I don't want the processing speed to be of >>> >> any importance here. In every case, I'm willing to sacrifice speed >>> >> over precision, even if the algorithm eventually turned out to be >>> >> super-slow. >>> >> Although I'd love to have such a thing working one day, I'm even >>> >> ready >>> >> for the possibility that this effect might never be implemented, if I >>> >> realize it would be too difficult for me to code (honestly, I've >>> >> never >>> >> coded in anything other than QBasic or briefly in Turbo Pascal, which >>> >> would probably require me to learn C all from scratch if C turned out >>> >> to be inevitable). >>> >> >>> >> - The core part of the algorithm is a frequency shifter [1]. Unlike a >>> >> pitch shifter, whose aim is to alter all the frequencies by a >>> >> constant >>> >> ratio, a frequency shifter alters all the frequencies by a constant >>> >> difference. >>> >> - The corresponding dialog box would offer the following parameters: >>> >> 1) the amount by which the frequencies should be shifted, given in >>> >> Hz, >>> >> which could be either positive or negative; >>> >> 2) two volume settings, namely for "dry" and "wet"; >>> >> 3) the amount by which the wet signal is fed back into the input, >>> >> given as a value that is less than 100% and more than -100%. >>> >> 4) the amount by which the feedback is to be delayed, probably given >>> >> in ms, which should always be given as a positive number; this >>> >> parameter has no effect if feedback is set to 0. >>> >> >>> >> [1] The actual realization would go like this: >>> >> - A) We store two intermediate copies of our original signal, label >>> >> them "IP" and "Q", and modify them as described in [2], >>> >> - B) Each of the modified intermediate signals is separately >>> >> amplitude-modulated: >>> >> IP is multiplied by a cosine wave of the given frequency, >>> >> Q is multiplied by a sine wave of the same frequency, >>> >> - C) we sum the two products to get the frequency-shifted signal, >>> >> - D) this signal, multiplied by the "Wet" coefficient, is sent to the >>> >> output, together with the original signal multiplied by the "Dry" >>> >> coefficient, >>> >> - E) the same frequency-shifted signal, this time multiplied by the >>> >> "Feedback" coefficient and delayed by "Delay" ms, is sent back to the >>> >> input. >>> >> >>> >> [2] We make a filter that works like an inverted Hilbert transform, >>> >> for which reason I'll call it the IHT. The length of the filter will >>> >> probably be hard-coded and unknown to the user. The longer the >>> >> filter, >>> >> the closer the approximation gets to a proper IHT. >>> >> - For a positive integer l, the filter length should be either l*4 or >>> >> l*4-1 samples. Practically, the two make no difference because every >>> >> other coefficient is equal to zero. >>> >> - Even though the filter is l*4 samples long, our sample position >>> >> indexes, instead of going from 0 to l*4-1, should go from -2*l to >>> >> +2*l-1. Let's call them k. Similarly, for a filter of length 4*l-1, >>> >> the sample position indexes k would go from -(2*n-1) to +2*n-1, i.e. >>> >> from -2*n + 1 to 2*n - 1. >>> >> The actual values of the filter coefficients meet the following rule: >>> >> - For all even numbers k, the coefficient c(k) is equal to zero. >>> >> - For all odd numbers k, the coefficient c(k) is equal to -2/)k*π). >>> >> - Next, we convolve our original signal with this filter and store >>> >> the >>> >> result into an intermediate buffer, which may be called Q (as in >>> >> "quadrature"). >>> >> - Then, depending on whether our filter length is even or odd, we >>> >> delay our original signal either by 2*n or by 2*n-1 samples and store >>> >> this delayed copy into another intermediate buffer, which we may call >>> >> IP (meaning "in phase"). >>> >> >>> >> You may be wondering why I insist on using an IHT instead of a proper >>> >> HT or on multiplying IP by a cosine wave rather than a sine wave. The >>> >> answers are: >>> >> - If I choose the amount of frequency shifting to be zero and do it >>> >> the way I've described, the supposed frequency-shifted signal will >>> >> only be delayed by "Delay" ms but in all other aspects it will be >>> >> identical to the original sound -- i.e. there won't be any additional >>> >> phase shifts or delays. In contrast, if IP were multiplied by a sine >>> >> wave and Q were multiplied by a cosine wave, then the supposed >>> >> frequency-shifted signal (with a zero frequency shift) would >>> >> correspond to the original signal not just delayed but also >>> >> Hilbert-transformed. This doesn't seem like an issue if the feedback >>> >> is set to zero. However, once I set the feedback to a non-zero value, >>> >> this thing starts to matter significantly. >>> >> - When I use an IHT, then I can get the desired frequency shift by >>> >> adding the two amplitude-modulated signals. In contrast, if I used a >>> >> proper HT, adding them would give me the opposite frequency shift and >>> >> to get the desired one, I would have to subtract them. >>> >> >>> >> Okay, that's it. Sorry for such a long post but I didn't want to miss >>> >> any important details. >>> >> >>> >> Thanks for your comments or suggestions. >>> >> >>> >> Petr >>> >> >>> >> >>> >> >>> > >>> > >>> > >>> > -- >>> > El software de antivirus Avast ha analizado este correo electrónico en >>> > busca >>> > de virus. >>> > https://www.avast.com/antivirus >>> > >>> >>> >>> _______________________________________________ >>> audacity-devel mailing list >>> [email protected] >>> https://lists.sourceforge.net/lists/listinfo/audacity-devel >> >> >> _______________________________________________ >> audacity-devel mailing list >> [email protected] >> https://lists.sourceforge.net/lists/listinfo/audacity-devel >> > _______________________________________________ audacity-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/audacity-devel