Repository: rabitt/pysox

Issue:
Combiner.preview() fails
`Combiner` inherits `preview` from `Transformer` but it needs to be overwritten because the base call is different for multiple inputs.

Discussion:

Patch:
diff --git a/docs/changes.rst b/docs/changes.rst
index 920d6fc..34e354e 100644
--- a/docs/changes.rst
+++ b/docs/changes.rst
@@ -8,4 +8,19 @@ v0.1
 
 v1.1.8
 ~~~~~~
-- Move specification of input/output file arguments from __init__ to .build()
\ No newline at end of file
+- Move specification of input/output file arguments from __init__ to .build()
+
+v1.3.0
+~~~~~~
+- patched core sox call to work on Windows
+- added remix
+- added gain to mcompand
+- fixed scientific notation format bug
+- allow null output filepaths in `build`
+- added ability to capture `build` outputs to stdout and stderr
+- added `power_spectrum`
+- added `stat`
+- added `clear` method
+- added `noiseprof` and `noisered` effects
+- added `vol` effect
+- fixed `Combiner.preview()`
\ No newline at end of file
diff --git a/sox/combine.py b/sox/combine.py
index 1a50272..2103bb7 100644
--- a/sox/combine.py
+++ b/sox/combine.py
@@ -15,6 +15,7 @@ from .core import ENCODING_VALS
 from .core import enquote_filepath
 from .core import is_number
 from .core import sox
+from .core import play
 from .core import SoxError
 from .core import SoxiError
 from .core import VALID_FORMATS
@@ -110,6 +111,45 @@ class Combiner(Transformer):
                 logging.info("[SoX] {}".format(out))
             return True
 
+    def preview(self, input_filepath_list, combine_type, input_volumes=None):
+        '''Play a preview of the output with the current set of effects
+
+        Parameters
+        ----------
+        input_filepath_list : list of str
+            List of paths to input audio files.
+        combine_type : str
+            Input file combining method. One of the following values:
+                * concatenate : combine input files by concatenating in the
+                    order given.
+                * merge : combine input files by stacking each input file into
+                    a new channel of the output file.
+                * mix : combine input files by summing samples in corresponding
+                    channels.
+                * mix-power : combine input files with volume adjustments such
+                    that the output volume is roughly equivlent to one of the
+                    input signals.
+                * multiply : combine input files by multiplying samples in
+                    corresponding samples.
+        input_volumes : list of float, default=None
+            List of volumes to be applied upon combining input files. Volumes
+            are applied to the input files in order.
+            If None, input files will be combined at their original volumes.
+
+        '''
+        args = ["play", "--no-show-progress"]
+        args.extend(self.globals)
+        args.extend(['--combine', combine_type])
+
+        input_format_list = _build_input_format_list(
+            input_filepath_list, input_volumes, self.input_format
+        )
+        input_args = _build_input_args(input_filepath_list, input_format_list)
+        args.extend(input_args)
+        args.extend(self.effects)
+
+        play(args)
+
     def set_input_format(self, file_type=None, rate=None, bits=None,
                          channels=None, encoding=None, ignore_length=None):
         '''Sets input file format arguments. This is primarily useful when
diff --git a/sox/file_info.py b/sox/file_info.py
index bcf368c..a66d9aa 100644
--- a/sox/file_info.py
+++ b/sox/file_info.py
@@ -258,8 +258,7 @@ def validate_output_file(output_filepath):
     '''
 
     nowrite_conditions = [
-        bool(os.path.dirname(output_filepath)) or\
-            not os.access(os.getcwd(), os.W_OK),
+        bool(os.path.dirname(output_filepath)),
         not os.access(os.path.dirname(output_filepath), os.W_OK)]
 
     if all(nowrite_conditions):
diff --git a/sox/transform.py b/sox/transform.py
index 74be29a..c694fee 100644
--- a/sox/transform.py
+++ b/sox/transform.py
@@ -458,6 +458,12 @@ class Transformer(object):
 
     def preview(self, input_filepath):
         '''Play a preview of the output with the current set of effects
+
+        Parameters
+        ----------
+        input_filepath : str
+            Path to input audio file.
+
         '''
         args = ["play", "--no-show-progress"]
         args.extend(self.globals)
@@ -1875,15 +1881,10 @@ class Transformer(object):
 
         '''
         if os.path.isdir(profile_path):
-            raise ValueError("profile_path {} is a directory, but filename should be specified.")
+            raise ValueError("profile_path {} is a directory, but should be a file")
         
-        if os.path.dirname(profile_path) == '' and profile_path != '':
-            _abs_profile_path = os.path.join(os.getcwd(), profile_path)
-        else:
-            _abs_profile_path = profile_path
-                
-        if not os.access(os.path.dirname(_abs_profile_path), os.W_OK):
-            raise IOError("profile_path {} is not writeable.".format(_abs_profile_path))
+        if not os.access(os.path.dirname(profile_path), os.W_OK):
+            raise IOError("profile_path {} is not writeable.".format(profile_path))
 
         effect_args = ['noiseprof', profile_path]
         self.build(input_filepath, None, extra_args=effect_args)
diff --git a/sox/version.py b/sox/version.py
index 6d16084..83db3e9 100644
--- a/sox/version.py
+++ b/sox/version.py
@@ -2,5 +2,5 @@
 # -*- coding: utf-8 -*-
 """Version info"""
 
-short_version = '1.2'
-version = '1.2.9'
+short_version = '1.3'
+version = '1.3.0'


Test patch:
diff --git a/tests/test_combine.py b/tests/test_combine.py
index 36985bf..c0fdea6 100644
--- a/tests/test_combine.py
+++ b/tests/test_combine.py
@@ -379,6 +379,22 @@ class TestBuildInputFormatList(unittest.TestCase):
         self.assertEqual(expected, actual)
 
 
+class TestCombinePreview(unittest.TestCase):
+    def setUp(self):
+        self.cbn = new_combiner()
+        self.cbn.trim(0, 0.1)
+
+    def test_valid(self):
+        expected = None
+        actual = self.cbn.preview([INPUT_WAV, INPUT_WAV], 'mix')
+        self.assertEqual(expected, actual)
+
+    def test_valid_vol(self):
+        expected = None
+        actual = self.cbn.preview([INPUT_WAV, INPUT_WAV], 'mix', [1.0, 0.5])
+        self.assertEqual(expected, actual)
+
+
 class TestBuildInputArgs(unittest.TestCase):
 
     def test_unequal_length(self):
diff --git a/tests/test_transform.py b/tests/test_transform.py
index 1f7795a..3ad7533 100644
--- a/tests/test_transform.py
+++ b/tests/test_transform.py
@@ -2679,14 +2679,6 @@ class TestTransformerNoiseprof(unittest.TestCase):
         with self.assertRaises(IOError):
             tfm.noiseprof(INPUT_FILE, '/usr/noise.prof')
 
-    def test_noise_prof_invalid_cwd(self):
-        tfm = new_transformer()
-        _cwd = os.getcwd()
-        os.chdir('/')
-        with self.assertRaises(IOError):
-            tfm.noiseprof(INPUT_FILE, 'noise.prof')
-        os.chdir(_cwd)
-
 
 class TestTransformerNoisered(unittest.TestCase):