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