Repository: rabitt/pysox

Issue:
mcompand Error Checking
**Issue:**
The `mcompand` function fails when the number of bands exceeds the number of points in the transfer function of a single band. For example, the following fails:
```
mcompand(
    n_bands=3,
    crossover_frequencies=[6500, 8000],
    attack_time=[0.001, 0.001, 0.001],
    decay_time=[0.020, 0.020, 0.020],
    soft_knee_db=[None, 2.0, None],
    tf_points=[[(-40, -40), (0, 0)],
        [(-40, -40), (-30, -38), (-20, -36), (0, -34)],
        [(-40, -40), (0, 0)]])
```
The resulting error is `ValueError: Found duplicate x-value in tf_points list.`

**Solution:**
Line 1817 of transform.py reads `if len(tf_points) > len(set([p[0] for p in tfp])):`. This should be `if len(tfp) > len(set([p[0] for p in tfp])):`.

Thanks!

Discussion:

Patch:
diff --git a/sox/transform.py b/sox/transform.py
index 20b5d89..d76344b 100644
--- a/sox/transform.py
+++ b/sox/transform.py
@@ -2222,7 +2222,7 @@ class Transformer(object):
                 raise ValueError(
                     "Tuple values in tf_points lists must be <= 0 (dB)."
                 )
-            if len(tf_points) > len(set([p[0] for p in tfp])):
+            if len(tfp) > len(set([p[0] for p in tfp])):
                 raise ValueError("Found duplicate x-value in tf_points list.")
 
         if not isinstance(gain, list) or len(gain) != n_bands:


Test patch:
diff --git a/tests/test_transform.py b/tests/test_transform.py
index 6243a6a..0ed1fc0 100644
--- a/tests/test_transform.py
+++ b/tests/test_transform.py
@@ -3091,6 +3091,35 @@ class TestTransformerMcompand(unittest.TestCase):
         self.assertEqual(expected_res, actual_res)
         tfm_assert_array_to_file_output(INPUT_FILE, OUTPUT_FILE, tfm)
 
+    def test_tf_points_valid2(self):
+        tfm = new_transformer()
+        tfm.mcompand(
+            n_bands=3,
+            crossover_frequencies=[6500, 8000],
+            attack_time=[0.001, 0.001, 0.001],
+            decay_time=[0.020, 0.020, 0.020],
+            soft_knee_db=[None, 2.0, None],
+            tf_points=[[(-40, -40), (0, 0)],
+                [(-40, -40), (-30, -38), (-20, -36), (0, -34)],
+                [(-40, -40), (0, 0)]],
+            gain=[None, None, None])
+        actual_args = tfm.effects
+        expected_args = [
+            'mcompand',
+            '0.001000,0.020000 -40.000000,-40.000000,0.000000,0.000000',
+            '6500.000000',
+            ('0.001000,0.020000 2.000000:-40.000000,-40.000000,-30.000000,' +
+             '-38.000000,-20.000000,-36.000000,0.000000,-34.000000'),
+            '8000.000000',
+            '0.001000,0.020000 -40.000000,-40.000000,0.000000,0.000000'
+        ]
+
+        self.assertEqual(expected_args, actual_args)
+
+        actual_res = tfm.build(INPUT_FILE, OUTPUT_FILE)
+        expected_res = True
+        self.assertEqual(expected_res, actual_res)
+
     def test_tf_points_wrong_len(self):
         tfm = new_transformer()
         with self.assertRaises(ValueError):