开发者

Using Java's ProcessBuilder to run SoX

I am running SoX from java using a ProcessBuilder to trim a wav file. I am sure I should be able to run SoX, cause in the other JUnit tests, I manage to successfully run the following commands:

sox/sox --version
sox/sox --i -r test/test.wav
sox/sox --i -D test/test.wav
sox/sox --i -b test/test.wav
sox/sox --i -c test/test.wav

but when I try to trim a file as in the following:

sox/sox -V3 "/Users/username/workspace/Thesis Corpus Integrator/test/test.wav" -b 16        "/Users/username/workspace/Thesis Corpus Integrator/test/newWaveFile.wav" channels 1 trim 0:00:00.000 =0:00:30.000

it throws an IOException with the error: error=2, No such file or directory. I tried running the command on a terminal, and it worked without a problem. If it matters, I ran it through a JUnit test from eclipse, on a macbook.

Here's the code I used to build it in ProcessBuilder:

StringBuilder command = new StringBuilder(soxCommand) // soxCommand resolves to sox/sox, and is used in all the other tests without any problems
if (WavCutter.getMetadata(srcFile.getAbsolutePath(),
                MetadataField.SAMPLE_RATE) != 16000) {
    command.append(" -V3");
    command.append(" -G");
    command.append(" \"" + srcFile.getAbsolutePath() + '\"');
    command.append(" -b 16");
    command.append(" \"" + destFile.getAbsolutePath() + 开发者_StackOverflow社区'\"');
    command.append(" channels 1");
    command.append(" gain -h");
    command.append(" rate 16000");
    command.append(" trim");
    command.append(" " + startTime.toString());
    command.append(" " + '=' + endTime.toString());

    Process soxProcess = new ProcessBuilder(command.toString())
                .start();

I also tried the same thing, but using an ArrayList.


Found the answer myself, with lots of help from bramp's comment. The problem is easily resolved by first using a List of Strings, and then by separating the non-dash prefixed arguments that require spaces, like sox's effects.

So from something like:

StringBuilder s = new StringBuilder("sox/sox"); // command itself is 'sox'

// everything after this is an argument
s.add(srcFile.getPath());
s.add("-b 16");
s.add(destFile.getPath());
s.add("rate 16000");
s.add("channels 1");

you get:

ArrayList<String> s = new ArrayList<String>();
s.add("sox/sox");              // command/process

// everything after this is an argument
s.add(srcFile.getPath());
s.add("-b 16");
s.add(destFile.getPath());
s.add("rate");                 // notice how I had to split up the rate argument
s.add("16000");  
s.add("channels");             // same applies here
s.add("1");

I think it may have something to do with how Java sends the arguments, or how SoX receives arguments. I was able to replicate my problem in the terminal by using the following command:

sox/sox test/test.wav -b 16 test/newtest.wav "rate 16000" "channels 1"
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜