Adding random noise in the entire directory that contains audio files

I have been working with python and have been exhausted since not much familiar with the syntax but I put my best effort to get as far as possible. Now, I need help.

I have two folders, let’s call folder_1 and folder_2. In folder_1 I have some audio files (1000 files) of no longer than 3 seconds duration each and in folder_2 (100 audio files) I have noises of no longer than 3 seconds in duration each. I want a python code that should read sequentially audio files from folder_1 and then randomly select noise from folder_2 and add the noise in the audio file. I made a macro that can add a single noise in entire directory but I am not sure how to randomly select noise and get what I want. I made the following macro that can add same noise in the entire files.

Import2 (Import the noise)
Mix and Render to New Track
Export as WAV
END

Anyone who can help me with this?

http://sox.sourceforge.net/Docs/Scripts

To iterate through the files in a directory, see: Programming tutorials | Newbedev

If you name the files in a uniform way with numbers, for example file1.wav, file2.wav, file3.wav …
then you can select a file name randomly with something like (using fstrings):

import random as r

filename = f"file{r.randint(1, 100)}.wav"



Unless you want to normalize the file before export, you don’t need to mix and render.
If you do want to normalize before export, use “Mix and Render” rather than “Mix and Render to New Track” (and then normalize).

import os
import random as r

directory = r'C:\Users\DNS\Desktop\Audio Captcha\Test Python code\audio_captcha_training_set'
for filename in os.listdir(directory):
    if filename.endswith(".wav") or filename.endswith(".wav"):
        print(os.path.join(directory, filename))
        path = r'C:\Users\DNS\Desktop\Audio Captcha\Test Python code\testnoises'
        files=os.listdir(path)
        d=f"file{r.randint(1,3)}.wav"
        print(os.path.join(path, d))
    else:
        continue

This is what I have done so far (with your help), what should I do if I want that noise be render to the directory in which I have my training data set directly?
I have enabled mod-script-pipe. I am not sure how to send do command in script. I am pretty sure I need to replace print(os.path.join(path, d)) but how is something I am just wondering.

Does this add random noise by itself? I am not familiar with it

SoX is a program. Like Audacity it is a powerful, general purpose tool for editing and processing audio. Unlike Audacity it doesn’t have a graphical interface, it’s a command line app, which makes it a good choice for batch processing large numbers of files. The documentation for SoX is here: http://sox.sourceforge.net/Docs/Documentationhttp://sox.sourceforge.net/Docs/Documentationhttp://sox.sourceforge.net/Docs/Documentation

@steve, can you help me with this?

Audacity does not act directly on files. Audacity acts on “projects”.
To process a file in Audacity you need to import the file into an empty Audacity project, apply the edits / effects / whatever, and then export the result as a new file.


Probably the easiest way is to use the “pipeclient” module which you can find here: https://raw.githubusercontent.com/audacity/audacity/master/scripts/piped-work/pipeclient.py

============
Module Usage

Example

Import the module:

import pipeclient

Create a client instance:

client = pipeclient.PipeClient()

Send a command:

client.write(“Command”, timer=True)

Read the last reply:

print(client.read()

I wrote this on Linux (with Python 3.6.9) so it will need to be adapted for Windows.
Also, I’ve only tested with a handful of files. I don’t know how many files it can handle in one run. I’d suggest that you test with just a few files then gradually increase the number of files. If it fails after a large number of files, you may need to restart Audacity and run it on less files.

#!/usr/bin/env python3

import os
from random import choice

import pipeclient as pc

IN_DIR = r"/home/steve/Desktop/temp/folder_in"
OUT_DIR = r"/home/steve/Desktop/temp/folder_out"
NOISE_DIR = r"/home/steve/Desktop/temp/folder_noise"


def process():
    client = pc.PipeClient()
    for file in os.listdir(IN_DIR):
        sound = os.path.join(IN_DIR, file)
        noise = os.path.join(NOISE_DIR, choice(os.listdir(NOISE_DIR)))
        output = os.path.join(OUT_DIR, file)
        client.write(f"Import2: Filename={sound}")
        client.write(f"Import2: Filename={noise}")
        client.write("SelectAll:")
        client.write("MixAndRender:")
        client.write("Normalize: PeakLevel=-1 ApplyGain=1")
        client.write(f"Export2: Filename={output}")
        client.write("RemoveTracks:")
        client.read()

if __name__ == '__main__':
    process()

Thank you so much steve, I will look into it in great detail and share my experience. I will share the final code if I turn out to be successful in doing what I want. Your efforts are much appreciated. God bless you!

I’ve just noticed that the script that I wrote assumes no spaces in the file names.
If your file names (or file paths) have spaces, then the Filenames need to be quoted in the “client.write” strings:

#!/usr/bin/env python3

import os
from random import choice

import pipeclient as pc

IN_DIR = r"/home/steve/Desktop/temp/folder_in"
OUT_DIR = r"/home/steve/Desktop/temp/folder_out"
NOISE_DIR = r"/home/steve/Desktop/temp/folder_noise"


def process():
    client = pc.PipeClient()
    for file in os.listdir(IN_DIR):
        sound = os.path.join(IN_DIR, file)
        noise = os.path.join(NOISE_DIR, choice(os.listdir(NOISE_DIR)))
        output = os.path.join(OUT_DIR, file)
        client.write(f'Import2: Filename="{sound}"')
        client.write(f'Import2: Filename="{noise}"')
        client.write('SelectAll:')
        client.write('MixAndRender:')
        client.write('Normalize: PeakLevel=-1 ApplyGain=1')
        client.write(f'Export2: Filename="{output}"')
        client.write('RemoveTracks:')
        client.read()

if __name__ == '__main__':
    process()