Support for Nyquist effects in Chains

Effects, Recipes, Interfacing with other software, etc.
Forum rules
If you require help using Audacity, please post on the forum board relevant to your operating system:
Windows
Mac OS X
GNU/Linux and Unix-like
steve
Site Admin
Posts: 81651
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Question re. adding effect to Chain

Post by steve » Sat May 28, 2011 10:00 am

Thanks for your work on this Edgar. This sounds very encouraging.
I'll need a bit of time to play with this.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)

steve
Site Admin
Posts: 81651
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Question re. adding effect to Chain

Post by steve » Sat May 28, 2011 1:50 pm

That's fantastic :D

I had a bit of trouble applying the patch thanks to phpBB messing up the formatting of the code, but have now got it successfully installed.

This feature could I'm sure be developed further (passing parameters would be the number 1 major improvement) but as it is now it is an extremely useful new feature.
I suspect that your right about further development requiring "major surgery", however, what you have already achieved goes way beyond what I was hoping for. I was only asking for a feasibility assessment, but you've provided a functional new feature with enormous potential. Thank you, I'm delighted :D
Edgar wrote: 1) User Interface:
A) Is it OK to interrupt the chain with a typical Nyquist dialog asking for user input?
i) If "No" how do we pass parameters into the effect?
ii) If "Yes" do we want to be able to access all (Nyquist??) effects?
B) If we go with a one-off effect that the user writes/edits where do we store the file?
i) If it is a typical xxx.ny file stored in plug-ins it will be picked up automatically for inclusion in the general menu.
a) Do we want it in the Audacity menu?
b) If we do not want it in the menu how do we deal with this?
ii) We could invent a custom extension-- .nc maybe, and keep it in the plug-ins folder.
A) No, not really as that largely defeats the point of batch processing.
i) Technically, I've no idea. In terms of the interface, what would be most useful would be to enter "variable value" pairs to replace the ;control settings (more later)
ii) Ability to access all Nyquist plug-ins would be great, but even one is a massive boon as it allows custom effects to be created by the user and applied in a chain. There must have been dozens of requests on the forum where we've had to send users off to explore SoX and other command line tools which can now be handled by Audacity Chains. A very recent case was a user asking how to copy the right channel of a stereo track to the left channel for a large collection of audio recordings. Another recent case was how to batch Normalize without altering the stereo balance. This feature has a tremendous range of application - I'm excited!

B) As now, a typical xxx.ny file works perfectly, though I think it would be beneficial to not hide it but to include it in the list of effects.
The advantage of displaying the "Batch" effect in the normal Effect menu is that it makes testing the Nyquist code very much easier.
Example:
Task: to make a custom multi-band notch filter for removing noise.
Nyquist Code: Something like (notch2 (notch2 (notch2 s 60 10) 120 20) 180 25)
To tweak the parameters, the "chain.ny" file can be opened in a text editor, the initial parameters set, and the file saved but kept open in the text editor. The effect can then be applied to a test sample, using the "Batch" effect from the "Edit" menu. If the results are not quite right, the parameters can be changed in the text editor, saved again, and tested again. When the parameters are just right, the effect can then be used in a Chain command.
Edgar wrote: 2) Code:
A) Can we find a member of the Development Team to mentor the project?
i) If not, can we find someone on Mac who can compile Audacity so we may pre-alpha test on all 3 platforms?
B) Should we expect to get this committed pre-2.0?
C) Can this be written as a module?
i) If so, should it be a module?
ii) Can we find a programmer who knows how to write modules who might help?
A) So far no response, but with the encouraging results of your patch I'll see if I can entice anyone.
i) I'm not sure how far along Bruno is with building on Mac - I'll PM him.
B) Unfortunately my guess is no, unless we get the backing of a senior developer.
C) No idea, but with revision 11179 I can't get the Nyquist WorkBench module to show up. Do you know if modules have been disabled in some way?

About passing parameters and using existing plug-ins:

Example: Batch processing with "Vocal Remover".
  1. Copy and paste from vocalremove.ny to chains.ny
  2. Delete or comment out (with an additional preceding semicolon) the ;categories line.
  3. (optional) Delete the ;info header line
  4. Change the name to "Batch" in the ;name header line
  5. Delete or comment out (with an additional preceding semicolons) the ;control header lines
  6. Set the variables for the user input parameters with a new line, for example:

    Code: Select all

    (setq action 0 bc 0 range "500 2000")
The new chains.ny file will now look like this:

Code: Select all

;nyquist plug-in
;version 3
;type process
;name "Vocal Remover (for center-panned vocals)..."
;action "Removing vocals or other center-panned audio..."

;;control action "Remove vocals or view Help" choice "Remove vocals,View Help" 0
;;control bc "Removal choice" choice "Simple (entire spectrum),Remove frequency band,Retain frequency band" 0
;;control range "Frequency band lower and upper limit [Hz]n [Enter two values between 0 and 20000]" string " " "500 2000"
(setq action 0 bc 0 range "500 2000")
.....
.....
This will now allow the Vocal Remover effect to be used for batch processing in Chain commands. The "parameters" are set by the line (setq action 0 bc 0 range "500 2000") which in this case are the same as the defaults.

The crucial parts are that
1) The ;control header lines are disabled
2) The variables "action", "bc" and "range" are set to valid values. In this case, integer 0, integer 0 and string "500 2000".

Removing the ;control header lines is not a problem since the "chains.ny" plug-in will invariably be customised by the user, so they can just be deleted.
What would be nice, and this is likely to be the problematic part, is how to send the variable/value pairs from the "Parameters" field in the Chains command to the plug-in.

Plug-in types:
There are three types of Nyquist plug-in - "process", "generate" and "analyze" which appear in the "Effect", "Generate" and "Analyze" menus respectively.
If the "chain.ny" effect is not hidden from the normal menus, then it might be a good idea to have 3 Nyquist-chain plug-ins, one of each type, so that the plug-in is not jumping from one menu to another. (this could probably also be helpfully abused to allow using multiple Nyquist effects in the same chain - I'll do some experiments).

Thanks again Edgar.
Steve
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)

Edgar
Forum Crew
Posts: 2043
Joined: Thu Sep 03, 2009 9:13 pm
Operating System: Windows 10

Re: Question re. adding effect to Chain

Post by Edgar » Sat May 28, 2011 4:08 pm

steve wrote: Plug-in types:
There are three types of Nyquist plug-in - "process", "generate" and "analyze" which appear in the "Effect", "Generate" and "Analyze" menus respectively.
If the "chain.ny" effect is not hidden from the normal menus, then it might be a good idea to have 3 Nyquist-chain plug-ins, one of each type, so that the plug-in is not jumping from one menu to another. (this could probably also be helpfully abused to allow using multiple Nyquist effects in the same chain - I'll do some experiments).

Code: Select all

-   return project->OnEffect(ALL_EFFECTS | CONFIGURED_EFFECT , f, params, false);
+   //efm5 start
+   int type = ALL_EFFECTS | CONFIGURED_EFFECT;
+   if (pbNyquistChain) type = PLUGIN_EFFECT | PROCESS_EFFECT;
+   return project->OnEffect(type, f, params, false);
+   //efm5 end
I had to enforce the type as under batch processing "ALL_EFFECTS | CONFIGURED_EFFECT" was being defaulted and if the Nyquist code does not see a type including one of INSERT_EFFECT, PROCESS_EFFECT or ANALYZE_EFFECT it fails gracefully. If you use a "non-PROCESS_EFFECT" in the chain my code may fail someday unless we determine a way to set type dynamically to suit (with the current patched Audacity code & testing EqualLevel--an ANALYZE_EFFECT--it works just fine masquarading as a PROCESS_EFFECT).

Code: Select all

// HIDDEN_EFFECT allows an item to be excluded from the effects
// menu in both CleanSpeech and in normal builds.
#define HIDDEN_EFFECT   0x0008

#define INSERT_EFFECT   0x0010
#define PROCESS_EFFECT  0x0020
#define ANALYZE_EFFECT  0x0040
#define ALL_EFFECTS     0x00FF
steve wrote: The advantage of displaying the "Batch" effect in the normal Effect menu is that it makes testing the Nyquist code very much easier.
True, but only for the non-naive user. If the the naive user saw "Batch" as a menu item it might be terribly confusing--I guess the default chain.ny could be a NOOP dialog explaining the feature's usage.

steve
Site Admin
Posts: 81651
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Question re. adding effect to Chain

Post by steve » Sat May 28, 2011 6:04 pm

Edgar wrote:I guess the default chain.ny could be a NOOP dialog explaining the feature's usage.
That's exactly what I had in mind.
I also thought that it might be clearer and less alluring to the naive user if the name of the effect was "Chains" rather than "Batch".

Code: Select all

;nyquist plug-in
;version 1
;type process
;name "Chain"
;action "Processing custom chain effect"
(format nil 
"This is a 'dummy' effect that may be edited and used in Chain commands.~%
See 'Nyquist Chain' in the manual for more details.")
Edgar wrote: I had to enforce the type as under batch processing "ALL_EFFECTS | CONFIGURED_EFFECT" was being defaulted and if the Nyquist code does not see a type including one of INSERT_EFFECT, PROCESS_EFFECT or ANALYZE_EFFECT it fails gracefully. If you use a "non-PROCESS_EFFECT" in the chain my code may fail someday unless we determine a way to set type dynamically to suit (with the current patched Audacity code & testing EqualLevel--an ANALYZE_EFFECT--it works just fine masquarading as a PROCESS_EFFECT).
I've just tried it with this and it seems to accept all Nyquist plug-in types (though I doubt there's much demand for Generate plug-ins in Chains).

Code: Select all

   int type = ALL_EFFECTS | CONFIGURED_EFFECT;
   if 
      (pbNyquistChain) type = PLUGIN_EFFECT | ANALYZE_EFFECT | PROCESS_EFFECT | INSERT_EFFECT;
   return project->OnEffect(type, f, params, false);
Code question:
I noticed that in your first patch you had:

Code: Select all

 static const wxString CleanSpeech = wxT("CleanSpeech");
@@ -238,6 +242,9 @@
    AddToChain( wxT("Leveller") );
    AddToChain( wxT("Normalize") );
    AddToChain( wxT("ExportMp3") );
+#  if defined(USE_NYQUIST)
+   AddToChain( wxT("Nyquist") );//efm5
+# endif
 }
but this has been left out of your most recent patch. Is it not needed?


Regarding using multiple Nyquist plug-ins, it's probably possible to code the Nyquist plug-in so that it runs different code on sequential runs (if that's ever needed).

This is the current patch that I'm using - does it look OK? Does it work on Windows?
Attachments
NyquistChain.patch
(2.97 KiB) Downloaded 65 times
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)

Edgar
Forum Crew
Posts: 2043
Joined: Thu Sep 03, 2009 9:13 pm
Operating System: Windows 10

Re: Question re. adding effect to Chain

Post by Edgar » Sat May 28, 2011 6:55 pm

steve wrote: Code question:
I noticed that in your first patch you had:

Code: Select all

 static const wxString CleanSpeech = wxT("CleanSpeech");
@@ -238,6 +242,9 @@
    AddToChain( wxT("Leveller") );
    AddToChain( wxT("Normalize") );
    AddToChain( wxT("ExportMp3") );
+#  if defined(USE_NYQUIST)
+   AddToChain( wxT("Nyquist") );//efm5
+# endif
 }
but this has been left out of your most recent patch. Is it not needed?
Cleanspeech is going away for 2.0 (or so I have been told when crafting bug fixes which needed to take it into account) so the excised code is not needed and was never tested with Cleanspeech.
steve wrote: Regarding using multiple Nyquist plug-ins, it's probably possible to code the Nyquist plug-in so that it runs different code on sequential runs (if that's ever needed).
The whole API and UI stuff for this feature is very tentative and if/when the menu/effects/commands stuff gets rewritten it will all have to be revisited and hopefully become moot. Once Audacity can treat built-in & plug-in effect with equality the batch processing should come automatically.
steve wrote: This is the current patch that I'm using - does it look OK? Does it work on Windows?
I am leaving for my daily "feed the animals" adventure. Will grab a new SVN and test the patch in a couple hours or so. BTW, since I seem to be persona non grata these days it might be best if you leave my name out of any discussions with the Team <grin>.

Edgar
Forum Crew
Posts: 2043
Joined: Thu Sep 03, 2009 9:13 pm
Operating System: Windows 10

Re: Question re. adding effect to Chain

Post by Edgar » Sat May 28, 2011 9:25 pm

The patch does not include adding chain.ny to the repository--I cannot seem to create a patch which does so.

Your patch is OK but I prefer this tiny change in formatting:

Code: Select all

Index: src/BatchCommands.cpp
===================================================================
--- src/BatchCommands.cpp	(revision 11179)
+++ src/BatchCommands.cpp	(working copy)
@@ -59,7 +59,8 @@
    wxT("ExportFlac"),
    wxT("ExportMp3"),
    wxT("ExportOgg"),
-   wxT("ExportWav")
+   wxT("ExportWav"),
+   wxT("Nyquist")
 };
 
 static const wxString CleanSpeech = wxT("CleanSpeech");
@@ -425,12 +426,14 @@
    }
 
    wxString filename;
-   if (mFileName.IsEmpty()) {   
-      filename = project->BuildCleanFileName(project->GetFileName());
+   if (command != wxT("Nyquist")) {
+      if (mFileName.IsEmpty()) {   
+         filename = project->BuildCleanFileName(project->GetFileName());
+      }
+      else {
+         filename = project->BuildCleanFileName(mFileName);
+      }
    }
-   else {
-      filename = project->BuildCleanFileName(mFileName);
-   }
 
    // We have a command index, but we don't use it!
    // TODO: Make this special-batch-command code use the menu item code....
@@ -487,7 +490,12 @@
       wxMessageBox(_("FLAC support is not included in this build of Audacity"));
       return false;
 #endif
-   } 
+   } else if (command == wxT("Nyquist")) {
+      Effect * f = EffectManager::Get().GetEffectByIdentifier(wxT("Chain"));
+      if (f != NULL) {
+         return ApplyEffectCommand(f, command, params, true);
+      }
+   }
    wxMessageBox(wxString::Format(_("Command %s not implemented yet"),command.c_str()));
    return false;
 }
@@ -511,7 +519,7 @@
    return true;
 }
 
-bool BatchCommands::ApplyEffectCommand(   Effect * f, const wxString command, const wxString params)
+bool BatchCommands::ApplyEffectCommand(   Effect * f, const wxString command, const wxString params, bool pbNyquistChain)
 {
    //Possibly end processing here, if in batch-debug
    if( ReportAndSkip(command, params))
@@ -525,7 +533,10 @@
    project->SelectAllIfNone();
 
    // NOW actually apply the effect.
-   return project->OnEffect(ALL_EFFECTS | CONFIGURED_EFFECT , f, params, false);
+   int type = ALL_EFFECTS | CONFIGURED_EFFECT;
+   if (pbNyquistChain)
+      type = PLUGIN_EFFECT | ANALYZE_EFFECT | PROCESS_EFFECT | INSERT_EFFECT;
+   return project->OnEffect(type, f, params, false);
 }
 
 bool BatchCommands::ApplyMenuCommand(const wxString command, const wxString params)
Index: src/BatchCommands.h
===================================================================
--- src/BatchCommands.h	(revision 11179)
+++ src/BatchCommands.h	(working copy)
@@ -28,7 +28,7 @@
    bool ApplyCommand( const wxString command, const wxString params );
    bool ApplyCommandInBatchMode(const wxString & command, const wxString &params);
    bool ApplySpecialCommand(int iCommand, const wxString command,const wxString params);
-   bool ApplyEffectCommand(Effect * f, const wxString command, const wxString params);
+   bool ApplyEffectCommand(Effect * f, const wxString command, const wxString params, bool pbNyquistChain = false);
    bool ApplyMenuCommand(const wxString command, const wxString params);
    bool ReportAndSkip( const wxString command, const wxString params );
    void AbortBatch();
Attachments
NyquistChain1.patch
(3.06 KiB) Downloaded 70 times
chain.ny
(246 Bytes) Downloaded 56 times

waxcylinder
Forum Staff
Posts: 14687
Joined: Tue Jul 31, 2007 11:03 am
Operating System: Windows 10

Re: Question re. adding effect to Chain

Post by waxcylinder » Mon Jun 27, 2011 5:05 pm

@Steve: has Ed "fixed this for you" ? Or does it still need transferring to the Wiki?

Peter.
________________________________________FOR INSTANT HELP: (Click on Link below)
* * * * * FAQ * * * * * Tutorials * * * * * Audacity Manual * * * * *

steve
Site Admin
Posts: 81651
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Question re. adding effect to Chain

Post by steve » Mon Jun 27, 2011 8:26 pm

Thanks to Ed we have a fully working proof of concept.
The feature request is to implement this concept into Audacity.
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)

steve
Site Admin
Posts: 81651
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Question re. adding effect to Chain

Post by steve » Mon Jul 18, 2011 6:35 pm

I've just been sent a new patch from one of the developers - more later (I'm on my way out).
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)

steve
Site Admin
Posts: 81651
Joined: Sat Dec 01, 2007 11:43 am
Operating System: Linux *buntu

Re: Question re. adding effect to Chain

Post by steve » Wed Jul 20, 2011 8:20 pm

Here's the patch.
It adds support for all currently installed Nyquist Plug-ins, not just "chain.ny"

Note that this is an unofficial patch.

A couple of minor issues that may occur with this patch:

The developer reported that there may be ellipsis at the end of the name in the "Select Command" dialog (I'm not seeing this on Ubuntu 10.10 with svn Head)

There is one peculiarity that I am seeing, which is that the default value for a slider widget is not being read. If a Nyquist effect that has not been previously used in the current Audacity session is added to a Chain, then the value of any slider widget that takes a float value defaults to 99999999.990000 and slider widgets that take integer
values default to 99999999. Once a Nyquist effect has been run in the Audacity session, or if the effect is opened by clicking on the Parameters button, then the slider widget value is read correctly.
Attachments
nyqchains.patch
(4.26 KiB) Downloaded 65 times
9/10 questions are answered in the FREQUENTLY ASKED QUESTIONS (FAQ)

Post Reply