I am not an audio person, but I have occasionally had to edit audio, and I’ve always used Audacity - it’s a great tool. Some time ago, I had to normalize sound levels on hundreds of voice recordings. A podcaster asked how I did it, I wrote it up in an email, and, thinking back, I decided it might be useful to others, so I’m posting it here. As I review the problem today, I think I would probably explore Audacity’s macro functionality to solve this type of problem - I don’t know why I jumped to scripting solution at the time. I did try the PyAudacity library, and found it was easier to interface directly though pipes.
Save the file below as audacityautomation.py
Set the infolder and outfolder folder variables in the script. Ensure the output folder is empty!
Ensure Audacity is Open
Ensure Audacity has scripting enabled (Edit -> Preferences -> Modules -> mod-script-pipe: set to Enabled) - you may have to restart Audacity
Then, from command line/terminal, in the folder you’ve copied the script, run
1
python audacityautomation.py
The script, as is, just runs the normalize command on every file – that’s set on this line in the script:
importosimportsys# Adapted from https://github.com/audacity/audacity/blob/master/scripts/piped-work/pipe_test.py# In Windows, remember to add escapes, like C:\\Users\\RichardAudette\\temp\\infolder\\ infolder="/home/raudette/temp/infolder"outfolder="/home/raudette/temp/outfolder"ifsys.platform=='win32':print("pipe-test.py, running on windows")TONAME='\\\\.\\pipe\\ToSrvPipe'FROMNAME='\\\\.\\pipe\\FromSrvPipe'EOL='\r\n\0'else:print("pipe-test.py, running on linux or mac")TONAME='/tmp/audacity_script_pipe.to.'+str(os.getuid())FROMNAME='/tmp/audacity_script_pipe.from.'+str(os.getuid())EOL='\n'print("Write to \""+TONAME+"\"")ifnotos.path.exists(TONAME):print(" ..does not exist. Ensure Audacity is running with mod-script-pipe.")sys.exit()print("Read from \""+FROMNAME+"\"")ifnotos.path.exists(FROMNAME):print(" ..does not exist. Ensure Audacity is running with mod-script-pipe.")sys.exit()print("-- Both pipes exist. Good.")TOFILE=open(TONAME,'w')print("-- File to write to has been opened")FROMFILE=open(FROMNAME,'rt')print("-- File to read from has now been opened too\r\n")defsend_command(command):"""Send a single command."""print("Send: >>> \n"+command)TOFILE.write(command+EOL)TOFILE.flush()defget_response():"""Return the command response."""result=''line=''whileTrue:result+=lineline=FROMFILE.readline()ifline=='\n'andlen(result)>0:breakreturnresultdefdo_command(command):"""Send one command, and return the response."""send_command(command)response=get_response()print("Rcvd: <<< \n"+response)returnresponse# Actual logic is hereforfilenameinos.listdir(infolder):infile=os.path.join(infolder,filename)outfile=os.path.join(outfolder,filename)# checking if it is an MP3 fileifos.path.isfile(infile)and"mp3"ininfile.lower():infile_cleanname=infile.replace("\\","/")# All audacity operations heredo_command(f"Import2: Filename=\"{infile_cleanname}\"")do_command("Select: Track=0")do_command("SelTrackStartToEnd")outfile_cleanname=outfile.replace("\\","/")#Start of sound manipulation operations# Any operation you want to perform on the samples, add them here#This line adjusts loudness - sets LUFS#do_command("LoudnessNormalization: LUFSLevel=-23")#This line sets peak sound level to -6 dBdo_command("Normalize: PeakLevel=-6")#End of sound operations - export filedo_command(f"Export2: Filename=\"{outfile_cleanname}\"")do_command(f"SaveProject2: Filename=\"{outfile_cleanname.replace('.mp3','.aup3')}\"")do_command("Close")