Thread: Re: [Audacity-nyquist] Processing individual samples
A free multi-track audio editor and recorder
Brought to you by:
aosiniao
From: <edg...@we...> - 2008-02-08 21:11:21
|
> Hi all, > > I've been toying with Audacity sources for a while. For effects, C is > fast (good) but needs to be compiled and linked in Audacity (bad, not > distributable). Ok, let's do it in Nyquist - I'm a total newbie in > Lisp but beginning to grasp a few concepts. What I want will be slow, > in fact I'm pretty sure it will take a looooong time to execute, but > this is not a real issue to me. > > I'm looking for a way to alter individual samples based on a given > algorithm. In fact, I'd like to know if there's a canonical way to do > it, something like a standard loop where I could insert whatever math > function(s) I need. I suppose snd-fetch could be involved, as well as > snd-from-array, all within the loop. Is it the right direction? Am I > missing something? See the Nyquist manual, DSP in Lisp: http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/manual/part5.html#40 Note: the current Nyquist 3.0 manual on Roger's CMU Page is incompatible to the Nyquist implementation in Audacity. -- The author of this email does not necessarily endorse the following advertisements, which are the sole responsibility of the advertiser: _______________________________________________________________________ Jetzt neu! Schützen Sie Ihren PC mit McAfee und WEB.DE. 30 Tage kostenlos testen. http://www.pc-sicherheit.web.de/startseite/?mc=022220 |
From: <edg...@we...> - 2008-02-09 04:30:41
Attachments:
dsp.ny
|
> > Hi all, > > I've been toying with Audacity sources for a while. For effects, C is > fast (good) but needs to be compiled and linked in Audacity (bad, not > distributable). Ok, let's do it in Nyquist - I'm a total newbie in > Lisp but beginning to grasp a few concepts. What I want will be slow, > in fact I'm pretty sure it will take a looooong time to execute, but > this is not a real issue to me. > > I'm looking for a way to alter individual samples based on a given > algorithm. In fact, I'd like to know if there's a canonical way to do > it, something like a standard loop where I could insert whatever math > function(s) I need. I suppose snd-fetch could be involved, as well as > snd-from-array, all within the loop. Is it the right direction? Am I > missing something? > > Thanks in advance for your feedback and suggestions. > -- > Jean ----------------------------- Because I know that the DSP example in the Nyquist manual is not-so-easy to understand, I have written a basic sceleton of an Audacity Nyquist DSP effect plugin. In the middle of the code there is a line: (* 0.5 current-sample) which ist the [rather simple] DSP function executed. So the plugin will return the Audacity track with half of the original volume. Just simply replace this line from above with your own functions. The plugin code is mainly based on the DSP example in the Nyquist manual. Maybe also important to know: Nyquist handles samples as floats, where in Nyquist the range is not limited to -1.0 to 1.0, but only by the float format of your machine and/or OS. But nevertheless be careful, when the Nyquist sound gets returned to Audacity, all samples will get clipped to a range of -1.0 to 1.0 again [by Audacity, not by Nyquist]. If your mailbox scrambles the indentation of the code [like mine does], look at the file in the attachment. Links to all other Nyquist docs can be found in the Audacity Users Wiki: http://audacityteam.org/wiki/index.php?title=Nyquist_Audio_Programming ----------------------------- ;nyquist plug-in ;version 1 ;type process ;name "DSP Effect..." ;action "Performing DSP Effect..." ;control dummy "" int "" 0 0 0 ;; the dummy slider above is only to open a effect window ;; where you can press the "Debug" button in case of trouble. ;; Just write TWO semicolons at the beginning of the "control" ;; line if you want to disable the effect window temporarily. ;; define a dsp class ;; (setf dsp-class (send class :new '(copy-of-sound))) ;; initial function of dsp class ;; (send dsp-class :answer :isnew '(sound) '((setf copy-of-sound (snd-copy sound)))) ;; method to be executed with every call to dsp-class ;; (send dsp-class :answer :next '() '((let ((current-sample (snd-fetch copy-of-sound))) ;; "cond" checks for end-of-samples condition (cond (current-sample ;; ;; replace the following line with your own function(s) ;; (* 0.5 current-sample) ))))) ;; define a dsp function for mono signals ;; (defun dsp (sound) (let (obj) (setf obj (send dsp-class :new sound)) (snd-fromobject (snd-t0 sound) (snd-srate sound) obj))) ;; add automatic handling of mono/stereo tracks. Processes both stereo ;; channels one after the other. To process both channels simultaneously ;; or whole blocks of samples the object code above needs to be rewritten. ;; (if (arrayp s) (vector (dsp (aref s 0)) (dsp (aref s 1))) (dsp s)) ----------------------------- have fun, - edgar -- The author of this email does not necessarily endorse the following advertisements, which are the sole responsibility of the advertiser: ________________________________________________________ Bis 50 MB Dateianhänge? Kein Problem! http://www.digitaledienste.web.de/freemail/club/lp/?lp=7 |
From: Jean Z. <jz...@fr...> - 2008-02-09 12:55:51
|
Le 09/02/2008 à 05:30, edg...@we... écrivait : > Because I know that the DSP example in the Nyquist manual is not-so-easy > to understand, I have written a basic sceleton of an Audacity Nyquist > DSP effect plugin. In the middle of the code there is a line: > > (* 0.5 current-sample) > > which ist the [rather simple] DSP function executed. So the plugin will > return the Audacity track with half of the original volume. Just simply > replace this line from above with your own functions. > > The plugin code is mainly based on the DSP example in the Nyquist manual. Thanks a lot! This is what I was looking for, and more. I was beginning to cycle through the usual "try something / fail / what do all these messages mean / try something else" routine when your code enlightened me. I think it could appear on your Nyquist Audio Programming page, which I see as a future reference cookbook. > Maybe also important to know: Nyquist handles samples as floats, where > in Nyquist the range is not limited to -1.0 to 1.0, but only by the float > format of your machine and/or OS. But nevertheless be careful, when the > Nyquist sound gets returned to Audacity, all samples will get clipped to > a range of -1.0 to 1.0 again [by Audacity, not by Nyquist]. Same for the effects C code. Anyway I'm mostly interested in functions whose properties are - f(0)=0 - f(1)=1 - continuous - differentiable - derivative > 0, between 0 and 1 > have fun, Thanks again, -- Jean |
From: <edg...@we...> - 2008-02-10 07:56:33
|
> -----Ursprüngliche Nachricht----- > Von: Discussion of developing Nyquist plug-ins for Audacity <aud...@li...> > Gesendet: 09.02.08 13:56:06 > An: Discussion of developing Nyquist plug-ins for Audacity <aud...@li...> > Betreff: Re: [Audacity-nyquist] Processing individual samples > > Le 09/02/2008 à 05:30, edg...@we... écrivait : > > > Because I know that the DSP example in the Nyquist manual is not-so-easy > > to understand, I have written a basic sceleton of an Audacity Nyquist > > DSP effect plugin. In the middle of the code there is a line: > > > > (* 0.5 current-sample) > > > > which ist the [rather simple] DSP function executed. So the plugin will > > return the Audacity track with half of the original volume. Just simply > > replace this line from above with your own functions. > > > > The plugin code is mainly based on the DSP example in the Nyquist manual. > > Thanks a lot! This is what I was looking for, and more. > > I was beginning to cycle through the usual "try something / fail / what > do all these messages mean / try something else" routine when your code > enlightened me. I think it could appear on your Nyquist Audio Programming > page, which I see as a future reference cookbook. > > > Maybe also important to know: Nyquist handles samples as floats, where > > in Nyquist the range is not limited to -1.0 to 1.0, but only by the float > > format of your machine and/or OS. But nevertheless be careful, when the > > Nyquist sound gets returned to Audacity, all samples will get clipped to > > a range of -1.0 to 1.0 again [by Audacity, not by Nyquist]. > > Same for the effects C code. Anyway I'm mostly interested in functions > whose properties are > > - f(0)=0 > - f(1)=1 > - continuous > - differentiable > - derivative > 0, between 0 and 1 > > > have fun, > > Thanks again, > -- > Jean > > ------------------------------------------------------------------------- > This SF.net email is sponsored by: Microsoft > Defy all challenges. Microsoft(R) Visual Studio 2008. > http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ > _______________________________________________ > Audacity-nyquist mailing list > Aud...@li... > https://lists.sourceforge.net/lists/listinfo/audacity-nyquist > -- The author of this email does not necessarily endorse the following advertisements, which are the sole responsibility of the advertiser: _____________________________________________________________________ Der WEB.DE SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen! http://smartsurfer.web.de/?mc=100071&distributionid=000000000066 |
From: <edg...@we...> - 2008-02-10 08:00:44
|
Hi Jean, please ignore the first mail, my stupid mailbox had automatically sent an answer without asking me first... > I was beginning to cycle through the usual "try something / fail / what > do all these messages mean / try something else" routine The backtrace and the [in great parts non-existent] error messages are a major disease of Nyquist. You need knowledge about the inner workings of the interpreter to be able [after long riddeling] what the real error in the lisp code could be. I always pays off to split your code in lots of small functions which then can be tested individually, one after the other. On the other hand: the rather awkward Nyquist backtrace is based in the fact, that XLISP [the Lisp interpreter Nyquist is based on] is, while from the build-in functions approx. a third the size of Common Lisp, from the code size only approx. 5 to 10 precent of a Common Lisp system what makes it possible e.g. to run Nyquist from an USB stick on all supported systems without root or administrator privileges. In other words: I can carry around a whole sound studio on an USB stick in the pocket of my trowser. That's what I *really* like on Nyquist. Therefore I'm willing to live live with wacky backtrace messages flooding my screen from time to time. :) > I think it could appear on your Nyquist Audio Programming > page, which I see as a future reference cookbook. Yes, the DSP code must become part of the Wiki pages. > Same for the effects C code. Anyway I'm mostly interested in functions > whose properties are > > - f(0)=0 > - f(1)=1 > - continuous > - differentiable > - derivative > 0, between 0 and 1 I think the next problem will be that it of course does not make much sense to filter single samples [in fact it is impossible]. Roger had sent last week some code which demonstrates how to use fetch-snd-array to read sample data blockwise. I think if you use different 'step' and 'block' sizes with snd-fetch-array you will be able to create overlapping 'frames' [arrays] like e.g. with the typical proceeding of FFT functions. Roger wrote: The other possibility is to compute the peak in Lisp. Maybe someone has done this already, but if not, here's the function. This destroys samples as you compute, so the variable S ends up with no samples [Edgar: that's why the init function of dsp-class uses 'snd-copy'. In other words, the dsp object code only destroys the copy, but not the original]: (defun destructive-peak (s) (let ((peak 0.0) (step 1000) points) (loop (setf points (snd-fetch-array s step step)) (if (null points) (return peak)) (dotimes (i (length points)) (setf peak (max peak (abs (aref points i)))))))) Edgar: I must first try myself, but I think if you use snd-fetch-array instead of snd-fetch in the dsp-class method, this would offer to read samples in typical dsp-like 'frames' manner. How to 'blend' or 'crossfade' the frames is a different question. Roger once wrote that he uses parts of sine waves for this purpose. But I first now will finish the drafts for the Audacity Wiki. Let's see what happens next... - edgar --- original message was --- > > Le 09/02/2008 à 05:30, edg...@we... écrivait : > > > Because I know that the DSP example in the Nyquist manual is not-so-easy > > to understand, I have written a basic sceleton of an Audacity Nyquist > > DSP effect plugin. In the middle of the code there is a line: > > > > (* 0.5 current-sample) > > > > which ist the [rather simple] DSP function executed. So the plugin will > > return the Audacity track with half of the original volume. Just simply > > replace this line from above with your own functions. > > > > The plugin code is mainly based on the DSP example in the Nyquist manual. > > Thanks a lot! This is what I was looking for, and more. > > I was beginning to cycle through the usual "try something / fail / what > do all these messages mean / try something else" routine when your code > enlightened me. I think it could appear on your Nyquist Audio Programming > page, which I see as a future reference cookbook. > > > Maybe also important to know: Nyquist handles samples as floats, where > > in Nyquist the range is not limited to -1.0 to 1.0, but only by the float > > format of your machine and/or OS. But nevertheless be careful, when the > > Nyquist sound gets returned to Audacity, all samples will get clipped to > > a range of -1.0 to 1.0 again [by Audacity, not by Nyquist]. > > Same for the effects C code. Anyway I'm mostly interested in functions > whose properties are > > - f(0)=0 > - f(1)=1 > - continuous > - differentiable > - derivative > 0, between 0 and 1 > > > have fun, > > Thanks again, > -- > Jean -- The author of this email does not necessarily endorse the following advertisements, which are the sole responsibility of the advertiser: _____________________________________________________________________ Unbegrenzter Speicherplatz für Ihr E-Mail Postfach? Jetzt aktivieren! http://www.digitaledienste.web.de/freemail/club/lp/?lp=7 |
From: Jean Z. <jz...@fr...> - 2008-02-10 21:22:45
|
Le 10/02/2008 à 09:00, edg...@we... écrivait : > > I was beginning to cycle through the usual "try something / fail / what > > do all these messages mean / try something else" routine > > The backtrace and the [in great parts non-existent] error messages are > a major disease of Nyquist. You need knowledge about the inner workings > of the interpreter to be able [after long riddeling] what the real error > in the lisp code could be. Nothing special here IMHO. Learning a new language in a new context amounts to being stranded in the jungle with only a machete and a gallon of water, you know the drill. :-) > I think the next problem will be that it of course does not make much > sense to filter single samples [in fact it is impossible]. Disclaimer: I'm an amateur when it comes to signal processing, with a general knowledge of FFT and friends, rules of thumbs galore, and that's about it. If some of the following rant seems totally off the wall to you, do not hesitate to correct me. As a guitarist and wannabe electronics hacker I'm interested in the harmonic distortion generated by effect boxes or amplifiers. In particular, the signal processing occuring in a tube amplifier looks a bit like a static compressor in that the main factor in the transfer function is the intensity of the signal; time is theoretically not involved, like is the case in a dynamic compressor. This behaviour creates harmonic distortion and it seems the harmonic content comes partly from the output stage architecture : single-ended, push-pull, "class A" vs. AB (the actual meaning being doubtful in this context), fixed or cathode bias... I also have very old distortion stompboxes which have a "good" sound and they are currently being analysed by scope and FFT. I can more or less reproduce the latter type of germanium distortion fairly easily: just compress the signal so that a sine wave is rounded with third harmonics. sin(x*pi/2) and ln((e-1)*x+1) do the trick [¹] (iterate to your taste) while a second-degree polynomial like x²+2x generates too many high-order harmonics - the sound becomes too harsh. A tube amplifier would also yield a 2nd harmonic, probably due to the fact that an amplifier processes the sound in an asymmetrical way when driven up. So, to me, stateless processing, sample by sample, does have its use and what's more, I can use different functions for the positive and negative samples (good when you square a value). Of course, this code alone is way too simple to really emulate an amplifier. I believe that a POD, for instance, features other algorithms in order to take into account the inductive load and the bandpass filter of the speakers, the filtering and resonance of the cabinet - closed, open-back - and so forth. Other Audacity plugins like Delay, High- and Low-Pass Filter come in handy in this context, as well as the Compressor effect to simulate the "sag" which happens when the power supply itself is overdriven. [¹] BTW I have a problem with log and sqrt functions, the plugin can't find them... > But I first now will finish the drafts for the Audacity Wiki. > > Let's see what happens next... Lisp suffers from a bad reputation, being quite alien to us imperative programmers. Your initiative will probably diminish the general reluctance and alleviate somewhat the steep learning curve of the language by providing recipes, allowing programmers to concentrate on the algorithms rather than on the syntax. And provide more plugins to Audacity users. Thanks for that, too. -- Jean |
From: <edg...@we...> - 2008-02-11 04:21:13
|
Hi Jean [and all others on this list], > > > I was beginning to cycle through the usual "try something / fail / > > > what do all these messages mean / try something else" routine > > > > The backtrace and the [in great parts non-existent] error messages are > > a major disease of Nyquist. You need knowledge about the inner workings > > of the interpreter to be able [after long riddeling] what the real error > > in the lisp code could be. > > Nothing special here IMHO. Learning a new language in a new context > amounts to being stranded in the jungle with only a machete and a > gallon of water, you know the drill. :-) > > > I think the next problem will be that it of course does not make much > > sense to filter single samples [in fact it is impossible]. > > Disclaimer: I'm an amateur when it comes to signal processing, with a > general knowledge of FFT and friends, rules of thumbs galore, and > that's about it. If some of the following rant seems totally off the > wall to you, do not hesitate to correct me. > > As a guitarist and wannabe electronics hacker I'm interested in the > harmonic distortion generated by effect boxes or amplifiers. In > particular, the signal processing occuring in a tube amplifier looks a > bit like a static compressor in that the main factor in the transfer > function is the intensity of the signal; time is theoretically not > involved, like is the case in a dynamic compressor. This behaviour > creates harmonic distortion and it seems the harmonic content comes > partly from the output stage architecture : single-ended, push-pull, > "class A" vs. AB (the actual meaning being doubtful in this context), > fixed or cathode bias... I also have very old distortion stompboxes > which have a "good" sound and they are currently being analysed by > scope and FFT. Information: I had built my own guitar effects for approx. twenty years (from tube amplifiers to germanium, silicium and mosfet semiconductors). Maybe we should add a guitar fuzz box section anywhere? :) > I can more or less reproduce the latter type of germanium distortion > fairly easily: just compress the signal so that a sine wave is rounded > with third harmonics. sin(x*pi/2) and ln((e-1)*x+1) do the trick [¹] > (iterate to your taste) while a second-degree polynomial like x²+2x > generates too many high-order harmonics - the sound becomes too harsh. > A tube amplifier would also yield a 2nd harmonic, probably due to the > fact that an amplifier processes the sound in an asymmetrical way when > driven up. You do not neccessarily need DSP to do this, you can approximate tube or semiconductor characteristics by cascading several Nyquist 'clip' functions with different treshold values in a much faster way. There also exists a Nyquist 'shape' function for exactly this purpose but it unfortunately doesn't work right with Nyquist in Audacity. Of course DSP gives you the most flexible way to do experiment with amplifier characteristics but according to my experience the audio result is not really better, only the math formulae are excessively more complicated. But it's not my intention to keep you from experimenting. > So, to me, stateless processing, sample by sample, does have its use > and what's more, I can use different functions for the positive and > negative samples (good when you square a value). Of course, this code > alone is way too simple to really emulate an amplifier. I believe that > a POD, for instance, features other algorithms in order to take into > account the inductive load and the bandpass filter of the speakers, > the filtering and resonance of the cabinet - closed, open-back - and > so forth. Other Audacity plugins like Delay, High- and Low-Pass Filter > come in handy in this context, as well as the Compressor effect to > simulate the "sag" which happens when the power supply itself is > overdriven. In principle you are right, for simulating amplifier characteristics it is sufficient to work with single samples, but as soon as you want to change the frequency characteristics, e.g. for simulating highpass, lowpass or bandpass filters via DSP, this only works with sequences of samples. But a whole battery of filters is already available as Nyquist built-in functions so this will probably not be necessary for building guitar effects with Nyquist. And caution: the Audacity 'Compressor' effect is still misfunctional and with a minimum Attack time of 100 milliseconds slower than the slowest grandma and therefore IMHO just simply far beyond useless anyway. For a guitar compressor e.g. you need attack times between 1 and 5 milliseconds. But the good news is: with Nyquist you can write your own compressors too. > [¹] BTW I have a problem with log and sqrt functions, the plugin can't > find them... Information about missing Nyquist functions [in Audacity] can be found under 'Nyquist Apropos plugin' in the updated Nyquist docs: http://www.audacity-forum.de/download/edgar/nyquist/nyquist-doc/devel/audacity-nyquist-en.htm#apropos > Lisp suffers from a bad reputation, being quite alien to us imperative > programmers. Your initiative will probably diminish the general > reluctance and alleviate somewhat the steep learning curve of the > language by providing recipes, allowing programmers to concentrate on > the algorithms rather than on the syntax. And provide more plugins to > Audacity users. Thanks for that, too. My eternal talking: a programmer who has not at least a basic knowlodge of the concepts of Fortran, Algol and Lisp is inadvertibly doomed to re-invent the wheel from the beginning. This does of course not mean that everybody must learn these [rather old] languages in every detail but without knowlege about the origins of computer programming you will inadvertibly run against walls again and again and again... But you are right: It took me approx. half a year of every-day reading and trying until I was able to write my first 'free-hand' Lisp programs without looking up every detail in the docs. Roger has started to introduce the SAL notation [derived from the SAL notation used in recent versions of 'Common Music' by Heinrich Taube], which is a Lisp front-end to save typing parens, but this still is not implemented in Audacity. [@roger: I think this could work without changing the Audacity/Nyquist C code but I just simply still haven't tried to tell the truth] P.S.: Links to some fuzz-box effects: The Broadcast Limiters II and III at the end of the 'Effects' section on the Nyquist Plug-ins download page in the Audacity Users Wiki are directly derived from my old silicium diode guitar fuzz boxes: http://audacityteam.org/wiki/index.php?title=Download_Nyquist_Plug-ins I also have a german 'tube amplifier simulator' on store which works in a similar manner [but is still rather slow with high 'dB' numbers]: http://www.audacity-forum.de/download/edgar/plugins/dB-max/RFT-dB-Max.ny Maybe somebody [including me] could do more tests with the Nyquist 'shape' function in Audacity? I always only got 'table limit exceeded' error messages, even with wavetables of only a few samples. Is it me myself or Nyquist in Audacity who causes this bug? - edgar -- The author of this email does not necessarily endorse the following advertisements, which are the sole responsibility of the advertiser: ________________________________________________________ Bis 50 MB Dateianhänge? Kein Problem! http://www.digitaledienste.web.de/freemail/club/lp/?lp=7 |