first commit

This commit is contained in:
Sandor Vasi
2016-03-01 08:40:00 +01:00
commit 737bef4759
11 changed files with 1431 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
target/
**/*.iml
.idea

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2016 Corballis Consulting Ltd.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

75
README.md Normal file
View File

@@ -0,0 +1,75 @@
# sox-wrapper-java
Java wrapper around the famous [sox](https://sourceforge.net/projects/sox/) audio processing tool.
Please note that the sox executable is not part of this project. This is a wrapper application only that points to the
executable.
Few of the arguments are not implemented yet, but with the help of the `SoX argument(String ...args)` method
any kind of parameter can be added to the parameter list.
Although the constructor of the SoX class requires the user to provide the full path of the sox executable,
it may not be a good idea to hard-code file system paths to java code. Use property files or environment variables instead.
Have a nice coding :)
## How to use
```
<dependency>
<groupId>ie.corballis</groupId>
<artifactId>sox-wrapper-java</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
```
## Code Examples
### Simple sox usage
The code below represents the following code in the CLI:
```sox --rate 16000 input.wav --encoding signed-integer --bits 16 output.wav remix 1 ```
```
Sox sox = new Sox("/usr/bin/sox");
sox
.sampleRate(16000)
.inputFile("input.wav")
.encoding(SoXEncoding.SIGNED_INTEGER)
.bits(16)
.outputFile("output.wav")
.effect(SoXEffect.REMIX,"1")
.execute();
}
```
### Pass unimplemented arguments to the sox
If an argument, you are looking for is not implemented yet, feel free to open an issue, or simply use the
`SoX argument(String ...args)` method to pass custom arguments to the sox.
```
Sox sox = new Sox("/usr/bin/sox");
sox.argument("--myargumentKey", "myArgumentValue")
.inputFile("input.wav")
.outputFile("output.wav")
.execute();
}
```
### Sox with Spring Framework
This is a recommendation, how to integrate the sox java wrapper with the Spring Framework
```
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SoXConfiguration {
@Bean(id="sox" scope="prototype")
public Sox sox() {
Sox sox = new Sox("/usr/bin/sox");
return sox;
}
```
With the above described Spring configuration class you can inject the sox wrapper anywhere in you Spring project like this:
```@Autowired private SoX sox;``` and the framework will initialize a new wrapper for you.

137
pom.xml Normal file
View File

@@ -0,0 +1,137 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ie.corballis</groupId>
<artifactId>sox-java</artifactId>
<version>1.0-SNAPSHOT</version>
<url>https://github.com/corballis/sox-wrapper-java</url>
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>7</version>
</parent>
<licenses>
<license>
<name>MIT License</name>
<url>http://www.opensource.org/licenses/mit-license.php</url>
<distribution>repo</distribution>
</license>
</licenses>
<developers>
<developer>
<id>sawo</id>
<name>Sandor Vasi</name>
<email>sawo@freemail.hu</email>
</developer>
</developers>
<scm>
<connection>scm:git:git@github.com:corballis/sox-wrapper-java.git</connection>
<url>scm:git:git@github.com:corballis/sox-wrapper-java.git</url>
<developerConnection>scm:git:git@github.com:corballis/sox-wrapper-java.git</developerConnection>
<tag>HEAD</tag>
</scm>
<properties>
<slf4j-api.version>1.7.8</slf4j-api.version>
<junit.version>4.8.2</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j-api.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>release-sign-artifacts</id>
<activation>
<property>
<name>performRelease</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.4.2</version>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,8 @@
package ie.corballis.sox;
public class AlreadyExecutedException extends Exception {
public AlreadyExecutedException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,544 @@
package ie.corballis.sox;
public enum AudioFileFormat {
_8SVX {
@Override
public String toString() {
return "8svx";
}
},
AIF {
@Override
public String toString() {
return "aif";
}
},
AIFC {
@Override
public String toString() {
return "aifc";
}
},
AIFF {
@Override
public String toString() {
return "aiff";
}
},
AIFFC {
@Override
public String toString() {
return "aiffc";
}
},
AL {
@Override
public String toString() {
return "al";
}
},
AMB {
@Override
public String toString() {
return "amb";
}
},
AU {
@Override
public String toString() {
return "au";
}
},
AVR {
@Override
public String toString() {
return "avr";
}
},
CAF {
@Override
public String toString() {
return "caf";
}
},
CDDA {
@Override
public String toString() {
return "cdda";
}
},
CDR {
@Override
public String toString() {
return "cdr";
}
},
CVS {
@Override
public String toString() {
return "cvs";
}
},
CVSD {
@Override
public String toString() {
return "cvsd";
}
},
CVU {
@Override
public String toString() {
return "cvu";
}
},
DAT {
@Override
public String toString() {
return "dat";
}
},
DVMS {
@Override
public String toString() {
return "dvms";
}
},
F32 {
@Override
public String toString() {
return "f32";
}
},
F4 {
@Override
public String toString() {
return "f4";
}
},
F64 {
@Override
public String toString() {
return "f64";
}
},
F8 {
@Override
public String toString() {
return "f8";
}
},
FAP {
@Override
public String toString() {
return "fap";
}
},
FLAC {
@Override
public String toString() {
return "flac";
}
},
FSSD {
@Override
public String toString() {
return "fssd";
}
},
GSM {
@Override
public String toString() {
return "gsm";
}
},
GSRT {
@Override
public String toString() {
return "gsrt";
}
},
HCOM {
@Override
public String toString() {
return "hcom";
}
},
HTK {
@Override
public String toString() {
return "htk";
}
},
IMA {
@Override
public String toString() {
return "ima";
}
},
IRCAM {
@Override
public String toString() {
return "ircam";
}
},
LA {
@Override
public String toString() {
return "la";
}
},
LPC {
@Override
public String toString() {
return "lpc";
}
},
LPC10 {
@Override
public String toString() {
return "lpc10";
}
},
LU {
@Override
public String toString() {
return "lu";
}
},
MAT {
@Override
public String toString() {
return "mat";
}
},
MAT4 {
@Override
public String toString() {
return "mat4";
}
},
MAT5 {
@Override
public String toString() {
return "mat5";
}
},
MAUD {
@Override
public String toString() {
return "maud";
}
},
NIST {
@Override
public String toString() {
return "nist";
}
},
OGG {
@Override
public String toString() {
return "ogg";
}
},
PAF {
@Override
public String toString() {
return "paf";
}
},
PRC {
@Override
public String toString() {
return "prc";
}
},
PVF {
@Override
public String toString() {
return "pvf";
}
},
RAW {
@Override
public String toString() {
return "raw";
}
},
S1 {
@Override
public String toString() {
return "s1";
}
},
S16 {
@Override
public String toString() {
return "s16";
}
},
S2 {
@Override
public String toString() {
return "s2";
}
},
S24 {
@Override
public String toString() {
return "s24";
}
},
S3 {
@Override
public String toString() {
return "s3";
}
},
S32 {
@Override
public String toString() {
return "s32";
}
},
S4 {
@Override
public String toString() {
return "s4";
}
},
S8 {
@Override
public String toString() {
return "s8";
}
},
SB {
@Override
public String toString() {
return "sb";
}
},
SD2 {
@Override
public String toString() {
return "sd2";
}
},
SDS {
@Override
public String toString() {
return "sds";
}
},
SF {
@Override
public String toString() {
return "sf";
}
},
SL {
@Override
public String toString() {
return "sl";
}
},
SLN {
@Override
public String toString() {
return "sln";
}
},
SMP {
@Override
public String toString() {
return "smp";
}
},
SND {
@Override
public String toString() {
return "snd";
}
},
SNDFILE {
@Override
public String toString() {
return "sndfile";
}
},
SNDR {
@Override
public String toString() {
return "sndr";
}
},
SNDT {
@Override
public String toString() {
return "sndt";
}
},
SOU {
@Override
public String toString() {
return "sou";
}
},
SOX {
@Override
public String toString() {
return "sox";
}
},
SPH {
@Override
public String toString() {
return "sph";
}
},
SW {
@Override
public String toString() {
return "sw";
}
},
TXW {
@Override
public String toString() {
return "txw";
}
},
U1 {
@Override
public String toString() {
return "u1";
}
},
U16 {
@Override
public String toString() {
return "u16";
}
},
U2 {
@Override
public String toString() {
return "u2";
}
},
U24 {
@Override
public String toString() {
return "u24";
}
},
U3 {
@Override
public String toString() {
return "u3";
}
},
U32 {
@Override
public String toString() {
return "u32";
}
},
U4 {
@Override
public String toString() {
return "u4";
}
},
U8 {
@Override
public String toString() {
return "u8";
}
},
UB {
@Override
public String toString() {
return "ub";
}
},
UL {
@Override
public String toString() {
return "ul";
}
},
UW {
@Override
public String toString() {
return "uw";
}
},
VMS {
@Override
public String toString() {
return "vms";
}
},
VOC {
@Override
public String toString() {
return "voc";
}
},
VORBIS {
@Override
public String toString() {
return "vorbis";
}
},
VOX {
@Override
public String toString() {
return "vox";
}
},
W64 {
@Override
public String toString() {
return "w64";
}
},
WAV {
@Override
public String toString() {
return "wav";
}
},
WAVPCM {
@Override
public String toString() {
return "wavpcm";
}
},
WV {
@Override
public String toString() {
return "wv";
}
},
WVE {
@Override
public String toString() {
return "wve";
}
},
XA {
@Override
public String toString() {
return "xa";
}
},
XI {
@Override
public String toString() {
return "xi";
}
}
}

View File

@@ -0,0 +1,389 @@
package ie.corballis.sox;
public enum SoXEffect {
ALLPASS {
@Override
public String toString() {
return "allpass";
}
},
BAND {
@Override
public String toString() {
return "band";
}
},
BANDPASS {
@Override
public String toString() {
return "bandpass";
}
},
BANDREJECT {
@Override
public String toString() {
return "bandreject";
}
},
BASS {
@Override
public String toString() {
return "bass";
}
},
BEND {
@Override
public String toString() {
return "bend";
}
},
BIQUAD {
@Override
public String toString() {
return "biquad";
}
},
CHORUS {
@Override
public String toString() {
return "chorus";
}
},
CHANNELS {
@Override
public String toString() {
return "channels";
}
},
COMPAND {
@Override
public String toString() {
return "compand";
}
},
CONTRAST {
@Override
public String toString() {
return "contrast";
}
},
DCSHIFT {
@Override
public String toString() {
return "dcshift";
}
},
DEEMPH {
@Override
public String toString() {
return "deemph";
}
},
DELAY {
@Override
public String toString() {
return "delay";
}
},
DITHER {
@Override
public String toString() {
return "dither";
}
},
DIVIDE_PLUS {
@Override
public String toString() {
return "divide+";
}
},
DOWNSAMPLE {
@Override
public String toString() {
return "downsample";
}
},
EARWAX {
@Override
public String toString() {
return "earwax";
}
},
ECHO {
@Override
public String toString() {
return "echo";
}
},
ECHOS {
@Override
public String toString() {
return "echos";
}
},
EQUALIZER {
@Override
public String toString() {
return "equalizer";
}
},
FADE {
@Override
public String toString() {
return "fade";
}
},
FIR {
@Override
public String toString() {
return "fir";
}
},
FIRFIT_PLUS {
@Override
public String toString() {
return "firfit+";
}
},
FLANGER {
@Override
public String toString() {
return "flanger";
}
},
GAIN {
@Override
public String toString() {
return "gain";
}
},
HIGHPASS {
@Override
public String toString() {
return "highpass";
}
},
HILBERT {
@Override
public String toString() {
return "hilbert";
}
},
INPUT_HASH {
@Override
public String toString() {
return "input#";
}
},
LOUDNESS {
@Override
public String toString() {
return "loudness";
}
},
LOWPASS {
@Override
public String toString() {
return "lowpass";
}
},
MCOMPAND {
@Override
public String toString() {
return "mcompand";
}
},
NOISEPROF {
@Override
public String toString() {
return "noiseprof";
}
},
NOISERED {
@Override
public String toString() {
return "noisered";
}
},
NORM {
@Override
public String toString() {
return "norm";
}
},
OOPS {
@Override
public String toString() {
return "oops";
}
},
OUTPUT_HASH {
@Override
public String toString() {
return "output#";
}
},
OVERDRIVE {
@Override
public String toString() {
return "overdrive";
}
},
PAD {
@Override
public String toString() {
return "pad";
}
},
PHASER {
@Override
public String toString() {
return "phaser";
}
},
PITCH {
@Override
public String toString() {
return "pitch";
}
},
RATE {
@Override
public String toString() {
return "rate";
}
},
REMIX {
@Override
public String toString() {
return "remix";
}
},
REPEAT {
@Override
public String toString() {
return "repeat";
}
},
REVERB {
@Override
public String toString() {
return "reverb";
}
},
REVERSE {
@Override
public String toString() {
return "reverse";
}
},
RIAA {
@Override
public String toString() {
return "riaa";
}
},
SILENCE {
@Override
public String toString() {
return "silence";
}
},
SINC {
@Override
public String toString() {
return "sinc";
}
},
SPECTROGRAM {
@Override
public String toString() {
return "spectrogram";
}
},
SPEED {
@Override
public String toString() {
return "speed";
}
},
SPLICE {
@Override
public String toString() {
return "splice";
}
},
STAT {
@Override
public String toString() {
return "stat";
}
},
STATS {
@Override
public String toString() {
return "stats";
}
},
STRETCH {
@Override
public String toString() {
return "stretch";
}
},
SWAP {
@Override
public String toString() {
return "swap";
}
},
SYNTH {
@Override
public String toString() {
return "synth";
}
},
TEMPO {
@Override
public String toString() {
return "tempo";
}
},
TREBLE {
@Override
public String toString() {
return "treble";
}
},
TREMOLO {
@Override
public String toString() {
return "tremolo";
}
},
TRIM {
@Override
public String toString() {
return "trim";
}
},
UPSAMPLE {
@Override
public String toString() {
return "upsample";
}
},
VAD {
@Override
public String toString() {
return "vad";
}
},
VOL {
@Override
public String toString() {
return "vol";
}
}
}

View File

@@ -0,0 +1,55 @@
package ie.corballis.sox;
public enum SoXEncoding {
SIGNED_INTEGER {
@Override
public String toString() {
return "signed-integer";
}
},
UNSIGNED_INTEGER {
@Override
public String toString() {
return "unsigned-integer";
}
},
FLOATING_POINT {
@Override
public String toString() {
return "floating-point";
}
},
MU_LAW {
@Override
public String toString() {
return "mu-law";
}
},
A_LAW {
@Override
public String toString() {
return "a-law";
}
},
IMA_ADPCM {
@Override
public String toString() {
return "ima-adpcm";
}
},
MS_ADPCM {
@Override
public String toString() {
return "ms-adpcm";
}
},
GSM_FULL_RATE {
@Override
public String toString() {
return "gsm-full-rate";
}
}
}

View File

@@ -0,0 +1,158 @@
package ie.corballis.sox;
import java.io.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Sox {
private static Logger logger = LoggerFactory.getLogger(Sox.class);
private final String soXBinaryPath;
private List<String> arguments = new ArrayList<String>();
private boolean globalOptionSet = false;
private boolean formatOptionSet = false;
private boolean inputFileSet = false;
private boolean outputFileSet = false;
private boolean hasBeenExecuted = false;
public Sox(String soxPath) {
this.soXBinaryPath = soxPath;
}
public Sox ignoreLength() {
arguments.add("--ignore-length");
formatOptionSet = true;
return this;
}
// format options
public Sox fileType(AudioFileFormat format) {
arguments.add("--type");
arguments.add(format.toString());
return this;
}
public Sox encoding(SoXEncoding encoding) {
arguments.add("--encoding");
arguments.add(encoding.toString());
return this;
}
public Sox bits(Integer bits) {
arguments.add("--bits");
arguments.add(bits.toString());
return this;
}
public Sox reverseNibbles() {
arguments.add("--reverse-nibbles");
return this;
}
public Sox reverseBits() {
arguments.add("--reverse-bits");
return this;
}
public Sox sampleRate(Integer sample) {
arguments.add("--rate");
arguments.add(sample.toString());
formatOptionSet = true;
return this;
}
// global options
public Sox verbose(Integer level) {
arguments.add("-V" + level.toString());
globalOptionSet = true;
return this;
}
public Sox effect(SoXEffect effect, String ... effectArguments) {
arguments.add(effect.toString());
for (String effectArgument : effectArguments) {
arguments.add(effectArgument);
}
return this;
}
public Sox argument(String ... arguments) {
Collections.addAll(this.arguments, arguments);
return this;
}
public Sox inputFile(String inputFile) {
arguments.add(inputFile);
return this;
}
public Sox outputFile(String outputFile) throws WrongParametersException {
if (inputFileSet) {
throw new WrongParametersException("The output file has to be later then an input file");
}
arguments.add(outputFile);
outputFileSet = true;
return this;
}
public void execute() throws IOException, WrongParametersException, AlreadyExecutedException {
if (hasBeenExecuted) {
throw new AlreadyExecutedException("The execute() method cannot be called twice");
}
File soxBinary = new File(soXBinaryPath);
if (!soxBinary.exists()) {
throw new FileNotFoundException("Sox binary is not available under the following path: " + soXBinaryPath);
}
if (!outputFileSet) {
throw new WrongParametersException("The output file argument is missing");
}
arguments.add(0, soXBinaryPath);
logger.debug("Sox arguments: {}", arguments);
ProcessBuilder processBuilder = new ProcessBuilder(arguments);
processBuilder.redirectErrorStream(true);
Process process = null;
IOException errorDuringExecution = null;
try {
process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
logger.debug(line);
}
} catch (IOException e) {
errorDuringExecution = e;
logger.error("Error while running Sox. {}", e.getMessage());
} finally {
if (process != null) {
process.destroy();
}
if (errorDuringExecution != null) {
throw errorDuringExecution;
}
}
}
public String getSoXBinaryPath() {
return soXBinaryPath;
}
public List<String> getArguments() {
return arguments;
}
public void setArguments(List<String> arguments) {
this.arguments = arguments;
}
}

View File

@@ -0,0 +1,7 @@
package ie.corballis.sox;
public class WrongParametersException extends Throwable {
public WrongParametersException(String s) {
super(s);
}
}

View File

@@ -0,0 +1,34 @@
package ie.corballis.sox;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
public class ArgumentTester {
@Test
public void testArguments() throws WrongParametersException {
Sox sox = new Sox("/usr/local/bin/sox");
List<String> arguments = sox
.sampleRate(16000)
.inputFile("input.wav")
.outputFile("output.wav")
.bits(16)
.encoding(SoXEncoding.SIGNED_INTEGER)
.effect(SoXEffect.REMIX).argument("1")
.getArguments();
List<String> expectedArguments = Arrays.asList(
"input.wav",
"output.wav",
"--bits",
"16",
"--encoding",
"signed-integer",
"remix",
"1");
assertEquals(expectedArguments, arguments);
}
}