3

I have to mix audio data for a machine learning task.

The setting is the following: I have two folders of tracks. One contains background files with background noise, the other contains files with a sound to recognise.

Now I have to mix them together to get all permutations between each file from the first folder and each file from the second folder.

To give an example:

  • Folder One: b1, b2, b3

  • Folder Two: s1, s2, s3

  • Mixed Folder: s1b1, s1b2, s1b3, s2b1, s2b2, s2b3, s3b1, s3b2, s3b3

I am currently using Audacity to do this manually, but my deadline is in 8 days and I still have to do this with a couple dozen files.

So my question is if there is some way to automate this?

Or to make this task somewhat less time-consuming?

I know that it would probably be possible with Matlab, but I am searching a faster and easier way, hence I thought to try it here.


Here is my solution. I have realized it in C#. Just in case someone stumbles upon this.

class Program
{
    // contains noise file names
    static List<string> noiseFilesDir = new List<string>();
    // contains sound file names
    static List<string> soundFilesDir = new List<string>();

    static string soxRoot = @"C:\Program Files (x86)\sox-14-4-2";

    static void Main(string[] args)
    {
        foreach (string s in Directory.GetFiles(soxRoot + "\\NoiseFiles", "*.wav").Select(Path.GetFileNameWithoutExtension))
        {
            noiseFilesDir.Add(s);
        }
        foreach (string s in Directory.GetFiles(soxRoot + "\\SoundFiles", "*.wav").Select(Path.GetFileNameWithoutExtension))
        {
            soundFilesDir.Add(s);
        }

        var processStartInfo = new ProcessStartInfo();
        processStartInfo.WorkingDirectory = soxRoot;
        processStartInfo.FileName = "cmd.exe";
        processStartInfo.RedirectStandardInput = true;
        processStartInfo.UseShellExecute = false;

        Process proc = Process.Start(processStartInfo);

        using (StreamWriter sw = proc.StandardInput)
        {
            if (sw.BaseStream.CanWrite)
            {
                //sw.WriteLine();
                for (int i = 0; i < soundFilesDir.Count; i++)
                {
                    for (int j = 0; j < noiseFilesDir.Count; j++)
                    {
                        string cmdString = string.Format(@"sox -m SoundFiles\{0}.wav NoiseFiles\{1}.wav MixedFiles\{0}{1}.wav", soundFilesDir[i], noiseFilesDir[j]);
                        sw.WriteLine(cmdString);
                    }
                }
            }
        }
    }
}
0

Using Sox, you can easily mix two files together by using the command

sox −m input1.wav input2.wav output.wav

This command will already be faster than opening both files in Audacity, and selecting export options.

Now, next step would be to setup a script that will execute this command on all your combinations. Depending on your computer platform, several possibilities exist (bash, python, ...).

As an example, a quick and dirty python script :

import os
import subprocess
from os.path import basename

# directory containing noise files
noiseDir = "/Users/audionuma/Desktop/noise"
# directory containing signal files
signalDir = "/Users/audionuma/Desktop/signal"
# destination directory for mixed files
outputDir = "/Users/audionuma/Desktop/out"

pathsToNoise = [os.path.join(noiseDir,fn) for fn in next(os.walk(noiseDir))[2]]
pathsToSignal = [os.path.join(signalDir,fn) for fn in next(os.walk(signalDir))[2]]

for noisePath in pathsToNoise:
  for signalPath in pathsToSignal:
    outFileName = os.path.splitext(basename(noisePath))[0] + "_" + os.path.splitext(basename(signalPath))[0] + ".wav"
    outFilePath = os.path.join(outputDir, outFileName)
    subprocess.call(["sox", "-m", noisePath, signalPath, outFilePath])
  • Thanks! I will look into it tomorrow, but I think this is exactly what i was looking for. – Gwenselah May 31 '15 at 23:46
  • I was to slow to edit the comment, so: You don't happen to know if it is possible to calculate the signal to noise ratio with sox, given two files? For example when you have s1 and s1b1 one could define the noise as the difference between those two and calculate the snr of s1b1 with this. I couldn't find this information on the fly. But anyway, thanks very much. I won't forget to mark your answer as soon as it works ;). – Gwenselah May 31 '15 at 23:53
  • Hello. Your other question on snr computation should take place in a new thread no to be mixed up with the initial question. – audionuma Jun 1 '15 at 5:52
  • This really works great. Thank you for the example, but I realized it in C# already. I will put my code below this in case someone is interested in it. – Gwenselah Jun 1 '15 at 18:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.