Revised soundsec wrong behaviour and Bug 10942: soundsec is too long 64/13964/10
Pierre-Aime Agnel [Mon, 10 Mar 2014 16:26:09 +0000 (17:26 +0100)]
Change-Id: I8e7783d38635cc4899ae32e7d9f591c4f2836064

scilab/CHANGES_5.5.X
scilab/modules/sound/help/en_US/soundsec.xml
scilab/modules/sound/macros/soundsec.sci
scilab/modules/sound/tests/nonreg_tests/bug_10942.dia.ref [new file with mode: 0644]
scilab/modules/sound/tests/nonreg_tests/bug_10942.tst [new file with mode: 0644]
scilab/modules/sound/tests/unit_tests/soundsec.dia.ref [new file with mode: 0644]
scilab/modules/sound/tests/unit_tests/soundsec.tst [new file with mode: 0644]

index ebf735f..0b4e263 100644 (file)
@@ -451,6 +451,9 @@ Scilab Bug Fixes
 
 * Bug #10936 fixed - Scilab hung with invalid strf in plot2d.
 
+* Bug #10942 fixed - Sound function soundsec revised.
+                     Now soundsec can be used for non integer values of time.
+
 * Bug #10998 fixed - matrix*hypermatrix and hypermatrix*matrix operations failed.
 
 * Bug #11001 fixed - exists and isdef did not work with primitives.
index f315818..25ac106 100644 (file)
@@ -6,34 +6,35 @@
     * This file must be used under the terms of the CeCILL.
     * This source file is licensed as described in the file COPYING, which
     * you should have received as part of this distribution.  The terms
-    * are also available at    
+    * are also available at
     * http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
     *
     -->
 <refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:lang="en" xml:id="soundsec">
     <refnamediv>
         <refname>soundsec</refname>
-        <refpurpose>generates n sampled seconds of time
-            parameter
+        <refpurpose>
+            generates a vector of samples for <literal>t</literal> seconds at frequency <literal>freq</literal> Hz.
         </refpurpose>
     </refnamediv>
     <refsynopsisdiv>
         <title>Calling Sequence</title>
-        <synopsis>t=soundsec(n [,rate])</synopsis>
+        <synopsis>samples=soundsec(t [,freq])</synopsis>
     </refsynopsisdiv>
     <refsection>
         <title>Arguments</title>
         <variablelist>
             <varlistentry>
-                <term>n</term>
+                <term>t</term>
                 <listitem>
-                    <para>an integer, the number of seconds to generate.</para>
+                    <para>a 1-by-1 matrix of positive real numbers, the time length to sample.</para>
                 </listitem>
             </varlistentry>
             <varlistentry>
-                <term>rate</term>
+                <term>freq</term>
                 <listitem>
-                    <para>an integer, the number of samples per second.</para>
+                    <para>a 1-by-1 matrix of positive real number, the frequency of samples per second.</para>
+                    <para>default value is 22050 Hz</para>
                 </listitem>
             </varlistentry>
         </variablelist>
     <refsection>
         <title>Description</title>
         <para>
-            generates a vector coding time from 0 to <literal>n</literal>seconds at
-            sampled rate <literal>rate</literal>.
+            Generates a vector coding time from 0 to <literal>t</literal> seconds at sampled rate <literal>freq</literal>.
+        </para>
+        <para>
+            Samples are always generated to fit in <literal>[0,t[</literal> (excluding upper bound).
+        </para>
+        <para>
+            Value 0 for either <literal>t</literal> or <literal>freq</literal> return an empty matrx
         </para>
     </refsection>
     <refsection>
@@ -51,7 +57,7 @@
 // At first we create 0.5 seconds of sound parameters.
 t=soundsec(0.5);
 
-// Then we generate the sound.
+// Then we generate a pure A4 = 440Hz sine
 s=sin(2*%pi*440*t);
 analyze(s,200,600,22050);
  ]]></programlisting>
index 32ad66d..77aa5ca 100644 (file)
@@ -1,6 +1,7 @@
 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 // Copyright (C) ???? - INRIA - Scilab
 // Copyright (C) ???? - ENPC
+// Copyright (C) 2014 - Scilab Enterprises - Pierre-Aimé AGNEL
 //
 // This file must be used under the terms of the CeCILL.
 // This source file is licensed as described in the file COPYING, which
@@ -9,8 +10,65 @@
 // http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
 
 function [t]=soundsec (n,rate)
-    // Return n seconds of t parameter at rate rate (sample/sec)
+    // Return [0,n) seconds of t parameter at frequency = rate (sample/sec)
+    // Always excludes the last sample if it arrives exactly at n seconds
     [lhs,rhs]=argn(0);
+
+    //set rate if not defined
     if rhs <=1 ; rate=22050; end;
-    t= linspace(0,n,n*rate);
+
+    //==============================================================================
+    // Format testing of the parameters
+
+    //n must be a real positive scalar
+    if  typeof(n)=="constant"
+        if isreal(n)
+            if ~isscalar(n)
+                //n is not a real positive scalar
+                error(999, msprintf(_("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"soundsec",1,1,1));
+            end
+        else //n is not real
+            error(999, msprintf(_("%s: Wrong type for argument #%d: Real matrix expected.\n"),"soundsec",1));
+        end
+    else //n is not a constant matrix
+        error(999, msprintf(_("%s: Wrong type for argument #%d: Real matrix expected.\n"),"soundsec",1));
+    end
+
+    //rate must be a real strictly positive scalar
+    if  typeof(rate)=="constant"
+        if isreal(rate)
+            if ~isscalar(rate)
+                //rate is not a real positive scalar
+                error(999, msprintf(_("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"soundsec",2,1,1));
+            end
+        else //rate is not real
+            error(999, msprintf(_("%s: Wrong type for argument #%d: Real matrix expected.\n"),"soundsec",2));
+        end
+    else //rate is not a constant matrix
+        error(999, msprintf(_("%s: Wrong type for argument #%d: Real matrix expected.\n"),"soundsec",2));
+    end
+
+    //n and rate must be positive
+    if n<0
+        error(999, msprintf(_("%s: Wrong value for input argument #%d: Must be >= %d.\n"),"soundsec",1,0));
+    end
+
+    if rate<0
+        error(999, msprintf(_("%s: Wrong value for input argument #%d: Must be >= %d.\n"),"soundsec",2,0));
+    end
+    //Format test end
+    //==============================================================================
+
+    max_sample = floor(n*rate);
+    if (max_sample==n*rate)
+        //Remove the last sample if it falls exactly at the n-th seconds
+        max_sample = max_sample-1
+    end
+
+    if rate==0
+        //avoid dividing by 0, if rate is 0 the result will be the empty set
+        rate=1;
+    end
+
+    t = (0:max_sample)/rate;
 endfunction
diff --git a/scilab/modules/sound/tests/nonreg_tests/bug_10942.dia.ref b/scilab/modules/sound/tests/nonreg_tests/bug_10942.dia.ref
new file mode 100644 (file)
index 0000000..0682daa
--- /dev/null
@@ -0,0 +1,2 @@
+t=[0:1:0.001*8000-1]/8000;
+assert_checkequal(soundsec(0.001,8000),t);
diff --git a/scilab/modules/sound/tests/nonreg_tests/bug_10942.tst b/scilab/modules/sound/tests/nonreg_tests/bug_10942.tst
new file mode 100644 (file)
index 0000000..7ea9fb1
--- /dev/null
@@ -0,0 +1,20 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2014 - Scilab Enterprises - Pierre-Aime Agnel
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+//
+// <-- Non-regression test for bug 10942 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=10492
+//
+// <-- Short Description -->
+// soundsec does not sample at the given frequency and is one element too long
+//
+
+t=[0:1:0.001*8000-1]/8000;
+assert_checkequal(soundsec(0.001,8000),t);
diff --git a/scilab/modules/sound/tests/unit_tests/soundsec.dia.ref b/scilab/modules/sound/tests/unit_tests/soundsec.dia.ref
new file mode 100644 (file)
index 0000000..43686ce
--- /dev/null
@@ -0,0 +1,50 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2014 - Scilab Enterprises - Pierre-Aime Agnel
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+//
+// <-- Unit tests for macro soundsec.sci -->
+//==============================================================================
+//Check abnormal entries
+non_real_time = msprintf(_("%s: Wrong type for argument #%d: Real matrix expected.\n"),"soundsec",1);
+non_real_freq = msprintf(_("%s: Wrong type for argument #%d: Real matrix expected.\n"),"soundsec",2);
+non_positive_time=msprintf(_("%s: Wrong value for input argument #%d: Must be >= %d.\n"),"soundsec",1,0);
+non_positive_freq=msprintf(_("%s: Wrong value for input argument #%d: Must be >= %d.\n"),"soundsec",2,0);
+non_scalar_time=msprintf(_("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"soundsec",1,1,1);
+non_scalar_freq=msprintf(_("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"soundsec",2,1,1);
+//Soundsec must be called with real scalar values
+assert_checkerror('soundsec(""test"",1)',non_real_time);
+assert_checkerror('soundsec(%i,1)',non_real_time);
+assert_checkerror('soundsec(1,""test"")',non_real_freq);
+assert_checkerror('soundsec(1,%i)',non_real_freq);
+assert_checkerror('soundsec(0:10,1)',non_scalar_time);
+assert_checkerror('soundsec(1,0:10)',non_scalar_freq);
+//Soundsec must be called with positive parameters
+assert_checkerror('soundsec(-1,10)',non_positive_time);
+assert_checkerror('soundsec(1,-1)',non_positive_freq);
+//==============================================================================
+//Check behaviour
+//Soundsec returns empty value for a 0 sec sample
+assert_checkequal(soundsec(0, 100), []);
+//Soundsec returns empty value for a 0 frequency sample
+assert_checkequal(soundsec(100, 0), []);
+//Checks default behaviour for rate
+assert_checkalmostequal( soundsec(10/22050), [0:9]./22050);
+//Check 1s of samples at 10hz excluding the last is [0:9]
+samples_t = soundsec(1, 10);
+assert_checkalmostequal(samples_t, (0:9)/10);
+//Check call on non integer time
+samples_t = soundsec(0.11, 100); //eleven samples 0 0.01 ... 0.09 0.1
+assert_checkalmostequal(samples_t, (0:10)/100);
+//Check call on non integer frequency
+samples_t = soundsec(1,5.2); //samples 0 1/5.2 2/5.2 ... 5/5.2
+assert_checkalmostequal(samples_t, (0:5)/5.2);
+//Check call on non integer frequency and time
+samples_t = soundsec(1.2324,50.75); 
+//samples 0 1/50.75 ... 50/50.75 51/51.75 ... 62/50.75
+//note that 1.2324 > 62/50.75 and 1.2324 <= 63/50.75
+assert_checkalmostequal(samples_t, (0:62)/50.75);
diff --git a/scilab/modules/sound/tests/unit_tests/soundsec.tst b/scilab/modules/sound/tests/unit_tests/soundsec.tst
new file mode 100644 (file)
index 0000000..ceca961
--- /dev/null
@@ -0,0 +1,69 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2014 - Scilab Enterprises - Pierre-Aime Agnel
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+//
+// <-- CLI SHELL MODE -->
+//
+// <-- Unit tests for macro soundsec.sci -->
+
+//==============================================================================
+//Check abnormal entries
+non_real_time = msprintf(_("%s: Wrong type for argument #%d: Real matrix expected.\n"),"soundsec",1);
+non_real_freq = msprintf(_("%s: Wrong type for argument #%d: Real matrix expected.\n"),"soundsec",2);
+
+non_positive_time=msprintf(_("%s: Wrong value for input argument #%d: Must be >= %d.\n"),"soundsec",1,0);
+non_positive_freq=msprintf(_("%s: Wrong value for input argument #%d: Must be >= %d.\n"),"soundsec",2,0);
+
+non_scalar_time=msprintf(_("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"soundsec",1,1,1);
+non_scalar_freq=msprintf(_("%s: Wrong size for input argument #%d: %d-by-%d matrix expected.\n"),"soundsec",2,1,1);
+
+
+//Soundsec must be called with real scalar values
+assert_checkerror("soundsec(""test"",1)",non_real_time);
+assert_checkerror("soundsec(%i,1)",non_real_time);
+assert_checkerror("soundsec(1,""test"")",non_real_freq);
+assert_checkerror("soundsec(1,%i)",non_real_freq);
+
+assert_checkerror("soundsec(0:10,1)",non_scalar_time);
+assert_checkerror("soundsec(1,0:10)",non_scalar_freq);
+
+//Soundsec must be called with positive parameters
+assert_checkerror("soundsec(-1,10)",non_positive_time);
+assert_checkerror("soundsec(1,-1)",non_positive_freq);
+
+
+//==============================================================================
+//Check behaviour
+
+//Soundsec returns empty value for a 0 sec sample
+assert_checkequal(soundsec(0, 100), []);
+//Soundsec returns empty value for a 0 frequency sample
+assert_checkequal(soundsec(100, 0), []);
+
+//Checks default behaviour for rate
+assert_checkalmostequal( soundsec(10/22050), [0:9]./22050);
+
+//Check 1s of samples at 10hz excluding the last is [0:9]
+samples_t = soundsec(1, 10);
+assert_checkalmostequal(samples_t, (0:9)/10);
+
+//Check call on non integer time
+samples_t = soundsec(0.11, 100); //eleven samples 0 0.01 ... 0.09 0.1
+assert_checkalmostequal(samples_t, (0:10)/100);
+
+//Check call on non integer frequency
+samples_t = soundsec(1,5.2); //samples 0 1/5.2 2/5.2 ... 5/5.2
+assert_checkalmostequal(samples_t, (0:5)/5.2);
+
+
+//Check call on non integer frequency and time
+samples_t = soundsec(1.2324,50.75);
+//samples 0 1/50.75 ... 50/50.75 51/51.75 ... 62/50.75
+//note that 1.2324 > 62/50.75 and 1.2324 <= 63/50.75
+assert_checkalmostequal(samples_t, (0:62)/50.75);
+
+
+