A macro to add silence depending on the cursor position

Hello,

I’d like to write a macro that adds silence at the beginning (and end - probably another macro) of a song. The amount of silence depends on the cursor position so I need a tool that reads the cursor position - or the start of the selection - and calculates how much silence to add at the beginning.

I see there’re tools to store cursor and selection but I need a way to retrieve the numbers and do a very simple calculation so the macro knows how much silence to add.

I’d appreciate any help.

Marcelo

do a very simple calculation

I think you hit the problem. I believe you can’t do “If this, then do that” calculations. It’s not a decision branching language.

Koz

In that case, is there a way to write a script that writes a manual position and the name of the MP3 to an external text file?

Then I would need another script that reads a text file and opens an MP3 and adds silence accordingly

That is correct for “normal” Macros - they simply process a linear sequence of commands.

In order to perform “logical” operations, you need to use a more powerful scripting language, such as Python or Nyquist.

Python may be used as an external scripting language, communicating with Audacity via “mod-script-pipe” (see: Scripting - Audacity Manual)

Nyquist is possibly a better option in this particular case. Nyquist is built into Audacity and scripts can be written as plug-ins. See: Nyquist-Macros - Audacity Manual
If you need help writing this Nyquist Macro, feel free to ask, but please do work through this page and try out the examples first.

Thank you so much for the answer. I’ll check both the Python and the Nyquist options although I’m familiar with Python and not at all with Lisp.

Marcelo

Sorry. I cannot find the “Python command line” :blush:

Maybe I should ask differently. I would like to run the pipe_test.py program but I cannot find where to put it. There should be a Python command line but I cannot find it

Big difference between scripting with Nyquist and scripting with Python:

  • Nyquist is built into Audacity and runs “inside” Audacity.
  • Python runs “outside” of Audacity and sends / receives messages via “mod-script-pipe”.

To run a Nyquist script, you can either:

  • Run the script in the Nyquist Prompt.
    This is useful for running short / simple commands.
  • Write the script as a text file, save it with a “.NY” file extension, and install it as a plug-in.
    This is useful for more complex scripts, or scripts that you may want to use again in the future.

To run a Python script with Audacity, you must have Python installed on your computer (preferably Python 3.x), and enable “mod-script-pipe”.
Mod-script-pipe is included in Audacity 2.3.2, but is disabled by default. It has to be enabled in Preferences, and then restart Audacity. See: https://manual.audacityteam.org/man/modules_preferences.html

You don’t “install” Python scripts into Audacity, you just run them on your computer while Audacity is running (with mod-script-pipe enabled), and the Python script sends commands to Audacity by “writing” to the named pipe.

Do you have the “pipeclient.py” file?
Running that as a “command line script” is perhaps the easiest way to test out commands.
It can also be imported as a module. See the docstrings in the file for details.

Thank you for the help!

I’ve set the python and have run the pipeclient.py, and it works. At least the ‘Q’ works.

Where can I see how to run Audacity commands? I tried to type ‘Left at playback position’ and got an error.

Good start :slight_smile:

In the “Scripting Reference” section of the manual: Scripting Reference - Audacity Manual

The documentation is rather “bare bones” at the moment, and some of the commands may change in future versions of Audacity (this is all very new).

I’m still trying to work work Python, which is easier for me than learning Lisp. It took me several trial and errors but I figured out the format of the GetInfo command.

What would be the way to get the start and end of a selection? I tried the Type=Tracks but it only gives the start/end of the track. Is there a way to get those values into the python?

Thanks,
Marcelo

Do you really need to? If you want to do something (such as insert silence) at the start of the selection, then you only need to set the start + end of the selection with:

SelectTime:Start="0" End="0" RelativeTo="SelectionStart"

and then generate the silence.

If you really do need to know the actual times, then the easiest way is with the Nyquist commands:

(get '*selection* 'start)

and

(get '*selection* 'end)

Let me explain. My songs have some kind of “almost” silence at the beginning. I need that the whole silence at the beginning will be exactly 2.5 seconds, so I have to measure the amount of existing silence so I know how much to add or how much to cut. My idea was to “select” the real song, leaving the silence out of the selection, so I can measure the silence at the beginning - and at the end - and add more silence or cut, accordingly.

Something like:

if “existing silence” more than 2.5 sec then calculate the difference and cut at the beginning
else calculate the difference and add silence at the beginning

Do the same with the end, but with 0.5 secs.

I assume there no way to send a Nyquist command through the Python pipe so I’ll have to learn Lisp …

Thank you!

You could run either “Silence Finder” or “Sound Finder”, then read the label track using

GetInfo: Type="Labels"

Hello,

  1. I found a way to read the selection into the Python program. I manually select the song, according to what I see, and AddLabel and GetInfo: Type=Labels. Then I just find the right texts in the reply message.

2, Now to the real problem. I have the Python program calculate how much I have to cut or how much silence I have to add. If I have to cut, everything works fine because I send a Select command with the right number and a Cut command. If I have to add silence, sending the “Silence…” command opens the Generate->Silence form and allows me to set the silence duration. Since I have the number calculated by the program, I don’t want the form but to set the silence duration sending it in a command. Using the form brings me back to manual work.

So my question is: is there a way to generate the silence without opening a form but setting the silence duration in the command itself?

Thank you in advance,
Marcelo

Say you want to insert 2 seconds of silence at the cursor position:

Select: Start="0" End="2" Mode="Set" RelativeTo="SelectionStart"
Repeat:Count="1"
SelectTime: Start="0" End="2" RelativeTo="SelectionStart"
Silence:

Thank you, Steve! I’m almost there. I think it’s my last batch of questions.

  1. How can I close the Label Track, in case it is open and has labels?

  2. Is there a way to close a project without getting a messagebox that asks whether to save it?

  3. Is there a way to open an MP3 by its name or path? Import2?

The program is already working but, in addition to the selection of the song that is interactive on purpose, there’re some places where it stops and asks for the user interaction. If 2 and 3 were possible, I’d put the whole procedure in a loop that runs on a files list and everything but the selection would be automated.

Thanks,
Marcelo

Select Tracks
then
Remove Tracks

Undo, all the way back to the start of the project, then close.

Yes, “Import2”
Ensure that you use the full file name and file path.
On Windows you “may” need to use double backslash or forward slash rather than the usual single backslash as the file separator (I’ve not tested as I don’t usually use Windows).

In my last question number 2, instead of Undoing all the way back to the beginning and then Closing, I’d like to Save the project with a preset name (which will be removed) and Close.

I tried several SaveProject2 options but none seems to work. The first one is the simplest one:

message = “SaveProject2:”# Filename=" + p_project_temp

while “message” is the text sent to the pipe.

I expected to get the project saved somewhere with some name. Instead I got the attached message.

The idea is to SaveProject2 with a path, so I can immediately delete it - or actually delete it, if it exists, before the save. Then I can just Close without getting any messagebox.

Thanks,
Marcelo
Capture.JPG

Is that in your Python code?
If so, what gets printed if you add, immediately after that line:

print(message)