Help with custom plugin causing corruption

Hi all

I’ve developed a custom plugin (first time of creating one) - and while it looks to do the job, it is corruption the project.

The intent of the plugin is to delete sections of the track based on the labels (“good” - leave, “bad” - delete).

Before:
BEFORE.PNG
After:
AFTER.PNG
Then I get a corruption error when I try to exit Audacy:
ERROR.PNG
Details of the error:

{
    "timestamp": 1644417274,
    "event_id": "ac3e32e24b4ff449b3161df2718d4c71",
    "platform": "native",
    "release": "audacity@3.1.3",
    "contexts": {
        "os": {
            "type": "os",
            "name": "Windows",
            "version": "10.0.19043"
        }
    },
    "exception": {
        "values": [
            {
                "type": "File_Error",
                "value": "Audacity failed to read from a file in <path>.",
                "mechanism": {
                    "type": "runtime_error",
                    "handled": false,
                    "data": {
                        "sqlite3.rc": "101",
                        "sqlite3.context": "ProjectFileIO::GetDiskUsage::step"
                    }
                }
            }
        ]
    }
}

Find attached the plugin. I expect I’m doing something incredibly stupid (its a speciality). I’m also not precious about doing this as a plugin - if there is a better way to achieve the same outcome, I’m more than happy to be told about it.

Thanks in advance
Mark
clean-podcast.ny (807 Bytes)

If you open Audacity’s log window (“Help menu > Diagnostics > Show log”) you will see that your plug-in returns an error in the final line:

15:42:13: Context was passed in, but was ignored.  ApplyAndSendResponse has its own one
15:42:13: Context was passed in, but was ignored.  ApplyAndSendResponse has its own one
15:42:13: Context was passed in, but was ignored.  ApplyAndSendResponse has its own one
15:42:13: Context was passed in, but was ignored.  ApplyAndSendResponse has its own one
15:42:13: Context was passed in, but was ignored.  ApplyAndSendResponse has its own one
15:42:13: Nyquist returned nyx_error:

The “nyx_error” is because the plug-in returned NIL, which is treated as an error.

To avoid the error, you need to return a valid value, but since you don’t actually want to return any audio from Nyquist, or text, or lists, or numbers, or anything else, you will need to return a valid “no-op” (https://en.wikipedia.org/wiki/NOP_(code))

In Audacity, when an empty string is returned by Nyquist, Audacity treats it as a no-op.
Here’s a version of your code which I think will work as you intended:

;nyquist plug-in
;version 4
;type process
;name "Clean Podcast"

(setf start-position 0)
(setf selections-to-delete ())

(defun add-selection (label)
  (setf selection-to-delete
      (list start-position (second label) (third label)))
  (push selection-to-delete selections-to-delete))

(defun process()
  (let ((label-info (aud-get-info "Labels")))
    (dolist (track label-info)
      (dolist (label (second track))
        (if (string= (third label) "bad")
          (add-selection label))
        (setf start-position (second label)))))
  (dolist (selection-to-delete selections-to-delete)
    (aud-do (format nil "Select:Start=~a End=~a Track=0 TrackCount=1 Mode=Set"
                    (first selection-to-delete)
                    (second selection-to-delete)))
    (aud-do "Delete:"))
  "") ; Return a "no-op" empty string.

(catch 'err (process))

(I also changed the “$” comments to normal “;” comments. The “$” syntax is to allow Audacity to find localized translations for the controls in plug-ins that are shipped with Audacity. It is not possible for Audacity to find translations for 3rd party plug-ins, so best to use the normal “;” syntax).

That works great. Much thanks