运行 sox 脚本将多个单声道音轨组合成立体声

运行 sox 脚本将多个单声道音轨组合成立体声

我有一个装满.wav音频文件的文件夹。

有些是立体声,大多数是单声道分离式。

单声道分离对均已命名foo bar track.L.wavfoo bar track.R.wav

我可以使用命令行工具sox将一对单声道组合成 1 个立体声音轨,如下所示:

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

其中前两个文件是单声道对,第三个是输出立体声文件。

这很棒,但我想要一个脚本可以自动找到所有单声道对并将它们组合成立体声文件。

即,我需要它查找所有具有相同名称(扩展名之前的.L.和除外)的文件,并对它们运行,输出到一个具有相同名称但没有后缀的新文件。.R.soxL/R

例如,如果我的文件夹包含这些文件:

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

我需要运行以下命令:

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

这是我目前的情况:

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

这有效,但是当我echo

sox -M $file $file2 $out;

它不起作用;文件名中的空格导致它失败。

答案1

从 GNU/Linux 控制台尝试此操作:

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

注意:“./”代表文件所在的音乐目录。

答案2

根据 sgmart 的建议,我解决了这个问题:

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

需要"围绕变量。

我添加了一些内容,将处理过的文件移动到“mono”子文件夹。

答案3

对于需要这样做的人来说视窗使用批处理文件:

4条规则需要满足的是:

1)批处理文件必须放在 SOX 的安装目录中

2)单声道文件需要有 .L.WAV 和 .R.WAV 终止

3)文件名中不能有空格

4)将所有单声道文件/文件夹放入名为输入在 SOX 安装文件夹中

运行批处理文件后,您将获得一个名为的新文件夹输出包含所有立体声文件和与输入文件夹

代码已注释,因此很容易跟踪过程中的每个步骤,可以随意修改并在此发布此脚本的改进版本(复制部分应该是一个动作,但我对 cmd 批处理代码不是很熟悉!)。

开始了:

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

答案4

使用 sox 通过 os.system() 调用的 python 解决方案

我有一台用于录音的 Tascam Model 12,当我导入文件夹时,我想将主混音合并为立体声轨道。在 Daw 中执行此操作总是有点烦人,尤其是在深夜,我只想上床睡觉,听着刚刚录制的录音。

我这样做是为了您可以将多个文件夹放入命令行调用中,它会合理地处理它们,您也可以从您想要的文件夹中调用它。

我给它 chmod +x 并将其放在我的 mac os 上的 /usr/local/bin 中,它可以很好地从其他目录调用它。可能由于正斜杠而不兼容 windows,但很容易为您的系统编辑,或者只需一点努力,就可以使它适用于两个文件系统。在这里分享只是因为我很久以来就想这样做,而且效果很好。

我开始尝试编写一个函数在 fish 中执行此操作,然后决定在 python 中执行此操作会更快,尽管有点丑陋。但从好的方面来看,这意味着它与 shell 无关。

虽然不太漂亮,也没有太多评论,但也许它可以节省那些想做类似事情的人一点时间。

需要说明的是,tascam 将其文件保存在带有日期的文件夹中,因此我使用文件夹名称作为输出文件名前缀,TR11 和 TR12 分别是我想要制作的左声道和右声道的主混音单声道文件。我将输出 wav 文件保存在上面一个文件夹中。所有这些都应该根据您处理的情况进行更改。

'+ "norm -1"' 加法可使标准值为 -1 db。同时,该过程也会显著减慢,因此,如果您要处理大量文件且无需进行标准值化,则请关闭该加法,这样运行速度会更快。

文件名: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()

相关内容