5

I have a folder full of .wav audio files.

Some are stereo, most are mono splits.

The mono split pairs are all named foo bar track.L.wav and foo bar track.R.wav

I can use the command line tool sox to combine a mono pair into 1 stereo track like this:

sox -M track1.L.wav track1.R.wav track1.Stereo.wav

where the first 2 files are the mono pairs, and the third is the output stereo file.

This is great, but I'd like to have a script that will automatically find all the mono pairs and combine them into stereo files.

I.e., I need it to find all files which have the same name except for the .L. and .R. before the extension, and run sox on them, outputting to a new file with the same name without the L/R suffix.

For example, if my folder contains these files:

track1.L.wav
track2.L.wav
track3.L.wav
track4.L.wav
track1.R.wav
track2.R.wav
track3.R.wav
track4.R.wav
track6.wav
track7.wav

I need to run these commands:

sox -M track1.L.wav track1.R.wav track1.Stereo.wav
sox -M track2.L.wav track2.R.wav track2.Stereo.wav
sox -M track3.L.wav track3.R.wav track3.Stereo.wav
sox -M track4.L.wav track4.R.wav track4.Stereo.wav

Here's where I am so far:

for file in ./*.L.wav;
do 
    file2=`echo $file | sed 's_\(.*\).L.wav_\1.R.wav_'`;
    out=`echo $file | sed 's_\(.*\).L.wav_\1.STEREO.wav_'`;
    echo $file - $file2 - $out;
done

That works, but when I replace the echo line with

sox -M $file $file2 $out;

it doesn't work; spaces in the filenames cause it to fail.

4 Answers 4

5

Try with this from a GNU/Linux console:

for file in ./*L*wav;
do
    for file2 in ./*R*wav;
    do
        $out = "Stereo"
        sox -M $file $file2 $file-$out.wav;
    done;
done

NOTE: "./" represent the music directory where your files are.

9
  • sox needs 3 args: the 2 files, plus the output file. I need the output file name to be the name of the first 2 without the L or R
    – d0g
    Oct 4, 2012 at 22:52
  • Sorry, this does not work; it does not match up the matching files. It just returns every file with an "L", followed by every other file, recursively.
    – d0g
    Oct 4, 2012 at 22:56
  • Yeah, I am sorry; I forgot the third argument
    – slackmart
    Oct 4, 2012 at 22:58
  • I updated the post to clarify; your code still doesn't line up matching pairs. Also, ./*.L.wav works better...
    – d0g
    Oct 4, 2012 at 23:07
  • The second for statement needs to somehow find files that match the * from the first for
    – d0g
    Oct 4, 2012 at 23:09
3

Going from sgmart's suggestion, I got it solved:

for file1 in ./*.L.wav; do 
  file2=`echo $file1 | sed 's_\(.*\).L.wav_\1.R.wav_'`;
  out=`echo $file1 | sed 's_\(.*\).L.wav_\1.STEREO.wav_'`;
  sox -MS "$file1" "$file2" "$out";
  mv "$file1" mono; mv "$file2" mono;
done

Needed "'s around the variables.

And I added a bit to move the processed files to a 'mono' subfolder.

1

For people that needs to do this in Windows with a batch file:

The 4 rules that need to be fullfilled are:

1) The batch file must be put in the directory where SOX is installed

2) Mono files needs to have .L.WAV and .R.WAV terminations

3) No white spaces in the file name

4) Put all your mono files/folders in a new folder called input inside the SOX installation folder

After running the batch file you'll get a new folder called output with all the stereo files and the same folder structure as the input folder

The code is commented so it is easy to follow each step in the process, feel free to modify and post here improved versions of this script (The copy part should be a move but I'm not very expert in cmd batch code!).

Here we go:

cd %~dp0
setlocal enabledelayedexpansion

REM for each file with extension .L.WAV in input folder and its subdirectories do:
for /R %~dp0input %%F in (*.L.WAV) do (

    REM get fullpath name and then remove the last 6 characters. ex: MYWAVE.L.WAV -> MYWAVE
    set fileName=%%F
    set finalName=!filename:~0,-6!

    REM set names for each parameter used by sox
    set wavL=!finalName!.L.WAV
    set wavR=!finalName!.R.WAV
    set wavST=!finalName!.ST.WAV

    REM call sox for mono to stereo conversion
    sox !wavL! !wavR! !wavST! -MS

)

REM creat output folder
mkdir %~dp0output

REM copy files to output folder 
echo d | xcopy %~dp0input %~dp0output /S

REM delete ST files from input folder 
for /R %~dp0input %%F in (*.ST.WAV) do del %%F

REM delete L files from output folder 
for /R %~dp0output %%F in (*.L.WAV) do del %%F

REM delete R files from output folder 
for /R %~dp0output %%F in (*.R.WAV) do del %%F
0

a python solution using sox called via os.system()

I have a tascam model 12 that I use to record, and when I import the folders, I want to combine the main mix into a stereo track. Doing this in a daw is always a little annoying, especially if it's late at night, and all I want to do is go to bed listening to a recording I just made.

I made it so you could glob multiple folders into the command line call and it would deal with them reasonably, also you can call it from within the folder that you want.

I gave it chmod +x and put it in my /usr/local/bin on mac os and it works fine calling it from other directories. Probably not windows compatible because of the forward slashes, but would be easy to edit for your system, or with a little effort, could be made to make work for both file systems. Shared here just because I've been meaning to do this for ages and it works nicely.

I started out trying to write a function to do it in fish, and then just decided it would be faster, if a bit uglier, to do it in python. But, on the bright side, means it's shell-agnostic.

Not pretty or commented, but maybe it will save someone else who wants to do something similar a little bit of time.

For explanation the tascam saves its files in a folder with the date, so I use the folder name as the output filename prefix, and TR11 and TR12 are the main mix mono files that I want to make left and right respectively. And I save the output wav files one folder above. All of that should be changed to match whatever situation you're dealing with.

The '+ " norm -1"' addition normalizes to -1 db. Also slows the process down considerably, so if you're doing a lot of files and don't need to normalize, leave that off and it will run faster.

filename: combine_tascam_tracks.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-


import os, glob, sys


original_path = os.getcwd()



def combine_files(this_path='.'):
    os.chdir(this_path)
    print(os.getcwd())
    
    left_wav  = glob.glob("*TR11.wav")[0]
    right_wav = glob.glob("*TR12.wav")[0]
    
    date_prefix = os.path.split(os.getcwd())[-1]
    
    output_filename = "../" + date_prefix + '_stereo.wav'
    
    sox_command = 'sox -M ' + left_wav + ' ' + right_wav + ' ' + output_filename + " norm -1"
    print(sox_command)
    
    exit_code = os.system(sox_command)
    
    print()
    print('sox exited with code', exit_code)
    print()
    os.chdir(original_path)
    


if len(sys.argv) > 1:
    
    for new_path in sys.argv[1:]:
        combine_files(new_path)
else:
    combine_files()

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .