Example #1
0
 def setUp(self):
     self.x = Audio(fs=10, initialdata=np.zeros((10, 1)))
     self.x.samples[0] =  -1.0
     self.x.samples[1] =   1.0
     print(self.x)
     print(self.x.samples)
     print()
Example #2
0
    def __init__(self,
                 N=None,
                 taps=None,
                 fs=96000,
                 repeats=2,
                 B=(1, 0, 0),
                 A=(1, 0, 0)):
        """N is the order of the MLS, taps are preferably selected from the mlstaps
        dictionary, like
        
            >>> taps=TAPS[N][0]
            
        B and A are emphasis filter coefficients. The filter used as emphasis must
        be a minimum phase filter. This means that all the poles and the zeroes are
        withing the unit circle. We can then invert the filter to apply de-emphasis.
        
        The filters.biquads.RBJ class can be used to generate a suitable emphasis
        filter.
        """
        assert repeats > 1, "at least two sequences are needed, (repeats=2)"

        _MLS_base.__init__(self, N=N, taps=taps)
        Audio.__init__(self,
                       fs=fs,
                       initialdata=self.get_full_sequence(repeats=repeats))

        self.repeats = repeats
        self._length_impresp = self.L / self.fs
        self._filter_emphasis = Filter(B=B, A=A, fs=self.fs)
        self._filter_deemphasis = Filter(B=A, A=B,
                                         fs=self.fs)  # inverse filter

        assert self._filter_emphasis.is_minimum_phase(), \
            "The emphasis filter must be minimum phase, i.e. possible to invert"
Example #3
0
 def __init__(self, N=None, taps=None, fs=96000, repeats=2, B=(1, 0, 0), A=(1, 0, 0)):
     """N is the order of the MLS, taps are preferably selected from the mlstaps
     dictionary, like
     
         >>> taps=TAPS[N][0]
         
     B and A are emphasis filter coefficients. The filter used as emphasis must
     be a minimum phase filter. This means that all the poles and the zeroes are
     withing the unit circle. We can then invert the filter to apply de-emphasis.
     
     The filters.biquads.RBJ class can be used to generate a suitable emphasis
     filter.
     """
     assert repeats > 1, "at least two sequences are needed, (repeats=2)"
     
     _MLS_base.__init__(self, N=N, taps=taps)
     Audio.__init__(self, fs=fs, initialdata=self.get_full_sequence(repeats=repeats))
     
     self.repeats            = repeats
     self._length_impresp    = self.L/self.fs
     self._filter_emphasis   = Filter(B=B, A=A, fs=self.fs)
     self._filter_deemphasis = Filter(B=A, A=B, fs=self.fs) # inverse filter
     
     assert self._filter_emphasis.is_minimum_phase(), \
         "The emphasis filter must be minimum phase, i.e. possible to invert"
Example #4
0
 def test_int8(self):
     x = Audio(fs=10, initialdata=np.zeros((10, 1), dtype=np.int8))
     x.samples[0] = -128
     x.samples[1] =  127
     
     self.convert(x, targetbits=32)
     
     self.assertAlmostEqual(x.samples[0], -1.0,      places=20)
     self.assertAlmostEqual(x.samples[1], 127/128,   places=20)
Example #5
0
 def test_int16(self):
     x = Audio(fs=10, initialdata=np.zeros((10, 1), dtype=np.int16))
     x.samples[0] = -32768
     x.samples[1] =  32767
     
     self.convert(x, targetbits=32)
     
     self.assertAlmostEqual(x.samples[0], -1.0,          places=20)
     self.assertAlmostEqual(x.samples[1], 32767/32768,   places=20)
Example #6
0
 def test_int32(self):
     x = Audio(fs=10, initialdata=np.zeros((10, 1), dtype=np.int32))
     x.samples[0] = -2147483648
     x.samples[1] =  2147483647
     
     self.convert(x, targetbits=32)
     
     # resolution is lost in this conversion, however we should be close enough.
     self.assertAlmostEqual(x.samples[0], -1.0, places=20) # exact value
     self.assertAlmostEqual(x.samples[1],  1.0, places=20) # close enough
Example #7
0
 def play(self, x, frames_per_buffer=1024):
     """Play audio. If dropouts or buffer underruns occur try different
     values for the frames_per_buffer variable."""
     
     _Device.play(self, x)
     self._validate(frames_per_buffer)
     
     missing_frames = self._get_missing_frames(frames_per_buffer, len(x))
     
     # generate silence to fill up missing frames
     pad = Audio(channels=x.ch, fs=x.fs, nofsamples=missing_frames, dtype=x.samples.dtype)
     
     # append the missing frames to a copy of the audio to be played. We now have
     # audio that can be split into complete (full) buffers
     cpy = Audio(fs=x.fs, initialdata=x.samples)
     cpy.concat(pad)
     
     assert len(cpy)%frames_per_buffer == 0
     
     stream = self.pa.open(format                = self._data_format(x),
                           channels              = x.ch,
                           rate                  = x.fs,
                           frames_per_buffer     = frames_per_buffer,
                           output_device_index   = self._index_out,
                           input                 = False,
                           output                = True,
                           )
     try:
         self._logger.info("play: start")
         counter = 0
         
         # split the audio into chunks the size of one buffer, so we can
         # iterate over the audio in chunksizes of the same size as one buffer
         it = iter(np.split(cpy.samples, len(cpy)/frames_per_buffer))
         try:
             while True:
                 chunk = it.next()
                 stream.write(chunk.tostring(), num_frames=frames_per_buffer)
                 counter += 1
                 
         except StopIteration:
             pass
             
         finally:
             stream.stop_stream()
             
         self._logger.debug("chunks played  : %i"    %counter)
         self._logger.debug("samples played : %i"    %(counter*frames_per_buffer))
         self._logger.debug("duration       : %.3f"  %(counter*frames_per_buffer/x.fs))
         
     finally:
         self._logger.debug("play: close stream")
         stream.close()
         
     self._logger.info("play: done")
Example #8
0
 def check_values(self, values, expected, position):
     x = Audio(fs=10, initialdata=values)
     
     peak, idx = x.peak()
     self.assertTrue(len(peak)==1)
     self.assertTrue(len(idx)==1)
     
     print("index: %3i  peak: %f" %(idx, peak))
     print(x)
     
     self.assertAlmostEqual(peak, expected, places=3)
     self.assertEqual(idx, position)
Example #9
0
 def check_values(self, values, expected, position):
     x = Audio(fs=10, initialdata=values)
     
     peak, idx = x.peak()
     self.assertTrue(len(peak)==2)
     self.assertTrue(len(idx)==2)
     
     print("index: %s  peak: %s" %(idx, peak))
     print(x)
     
     self.assertAlmostEqual(peak[0], expected[0], places=3)
     self.assertAlmostEqual(peak[1], expected[1], places=3)
     
     self.assertEqual(idx[0], position[0])
     self.assertEqual(idx[1], position[1])
Example #10
0
class Test_ConvertFloatToInt(unittest.TestCase):
    def setUp(self):
        self.x = Audio(fs=10, initialdata=np.zeros((10, 1)))
        self.x.samples[0] =  -1.0
        self.x.samples[1] =   1.0
        print(self.x)
        print(self.x.samples)
        print()
        
    def convert(self, targetbits=None):
        self.x.convert_to_integer(targetbits=targetbits)
        print(self.x)
        print(self.x.samples)
        
        self.assertIsInstance(self.x.samples, np.ndarray)
        
    def test_int8(self):
        self.convert(targetbits=8)
        self.assertTrue(self.x.samples.dtype==np.int8)
        
        # 8 bits 2's complement
        # min is -128
        # max is  127
        self.assertEquals(self.x.samples[0], -127) # must be symmetrical
        self.assertEquals(self.x.samples[1],  127) # must be symmetrical
        
    def test_int16(self):
        self.convert(targetbits=16)
        self.assertTrue(self.x.samples.dtype==np.int16)
        
        # 16 bits 2's complement
        # min is -32768
        # max is  32767
        self.assertEquals(self.x.samples[0], -32767) # must be symmetrical
        self.assertEquals(self.x.samples[1],  32767) # must be symmetrical
        
    def test_int32(self):
        self.convert(targetbits=32)
        self.assertTrue(self.x.samples.dtype==np.int32)
        
        # 32 bits 2's complement
        # min is -2147483648
        # max is  2147483647
        self.assertEquals(self.x.samples[0], -2147483647) # must be symmetrical
        self.assertEquals(self.x.samples[1],  2147483647) # must be symmetrical
Example #11
0
 def play_rec(self, x, **kwargs):
     _Device.play_rec(self, x, **kwargs)
     self._logger.warn("*** Stub play_rec")
     
     # fake a signal with white noise
     n = Noise(channels=x.ch, fs=x.fs, nofsamples=x.nofsamples, gaindb=-60)
     n.convert_to_float(targetbits=32)
     y = Audio(fs=x.fs, initialdata=n.samples)
     return y
Example #12
0
 def rec(self, duration=None, channels=1, fs=96000, **kwargs):
     _Device.rec(self, duration=duration, channels=channels, fs=fs, **kwargs)
     self._logger.warn("*** Stub rec")
     
     # fake a signal with white noise
     n = Noise(channels=channels, fs=fs, duration=duration, gaindb=-60)
     n.convert_to_float(targetbits=32)
     y = Audio(fs=fs, initialdata=n.samples)
     return y
Example #13
0
class Test_ConstructorChannels(unittest.TestCase):
    def setUp(self):
        self.x = Audio(channels=4)
        print(self.x)

    def test_str_method(self):
        self.assertIsInstance(self.x.__str__(), str)

    def test_channels(self):
        self.assertEqual(self.x.ch, 4)
        self.assertEqual(len(self.x), 0)

    def test_RMS_is_nan(self):
        print(self.x.rms())
        self.assertTrue(np.isnan(self.x.rms()).all())

    def test_peak_is_nan(self):
        peak, idx = self.x.peak()
        print(peak)
        print(idx)
        self.assertTrue(np.isnan(peak).all())
        self.assertTrue((idx == 0).all())

    def test_crestfactor_is_nan(self):
        print(self.x.crest_factor())
        self.assertTrue(np.isnan(self.x.crest_factor()).all())
Example #14
0
class Test_EmptyConstructor(unittest.TestCase):
    def setUp(self):
        self.x = Audio()
        print(self.x)

    def test_default_constructor(self):
        self.assertAlmostEqual(self.x.fs, 96000, places=7)
        self.assertEqual(self.x.ch, 0)
        self.assertEqual(self.x.nofsamples, 0)
        self.assertEqual(self.x.duration, 0)
        self.assertIsInstance(self.x.samples, np.ndarray)

    def test_str_method(self):
        self.assertIsInstance(self.x.__str__(), str)

    def test_empty_comment(self):
        self.assertSequenceEqual(self.x.comment(), '')

    def test_add_comment(self):
        self.assertSequenceEqual(self.x.comment(), '')

        s = 'This is a comment\nwith a line break'
        self.x.comment(comment=s)
        print(self.x)

        self.assertSequenceEqual(self.x.comment(), s)
Example #15
0
 def __str__(self):
     B, A = self._filter_emphasis.get_coefficients()
     
     mls_string = _MLS_base.__str__(self)
     mls_string = "\n".join(mls_string.splitlines()[2:-1])
     
     s  = Audio.__str__(self)
     s += '%s\n'                             %mls_string
     s += 'repeats          : %i\n'          %self.repeats
     s += 'len(impulse)     : %.3f [s]\n'    %self._length_impresp
     s += 'emphasis filt. B : %s\n'          %str(B)
     s += 'emphasis filt. A : %s\n'          %str(A)
     return s
Example #16
0
    def __str__(self):
        B, A = self._filter_emphasis.get_coefficients()

        mls_string = _MLS_base.__str__(self)
        mls_string = "\n".join(mls_string.splitlines()[2:-1])

        s = Audio.__str__(self)
        s += '%s\n' % mls_string
        s += 'repeats          : %i\n' % self.repeats
        s += 'len(impulse)     : %.3f [s]\n' % self._length_impresp
        s += 'emphasis filt. B : %s\n' % str(B)
        s += 'emphasis filt. A : %s\n' % str(A)
        return s
Example #17
0
 def test_set_samples(self):
     x = Audio(nofsamples=300, fs=600)
     print(x)
     self.assertAlmostEqual(x.duration, 0.5, places=7)
Example #18
0
 def setUp(self):
     self.x = Audio(channels=4)
     print(self.x)
Example #19
0
 def setUp(self):
     self.x = Audio()
     print(self.x)
Example #20
0
 def rec(self, duration=None, channels=1, fs=96000, frames_per_buffer=1024, dtype=np.float32):
     """Record. If dropouts or buffer underruns occur try different
     values for the frames_per_buffer variable."""
     
     _Device.rec(self, duration=duration, channels=channels, fs=fs)
     self._validate(frames_per_buffer)
     
     missing_frames = self._get_missing_frames(frames_per_buffer, int(duration*fs))
     
     nofsamples = missing_frames+int(duration*fs)
     
     rec = Audio(channels=channels, fs=fs, nofsamples=nofsamples, dtype=dtype)
     
     assert len(rec)%frames_per_buffer == 0
     
     stream = self.pa.open(format                = self._data_format(rec),
                           channels              = rec.ch,
                           rate                  = rec.fs,
                           frames_per_buffer     = frames_per_buffer,
                           input_device_index    = self._index_in,
                           input                 = True,
                           output                = False,
                           )
     try:
         self._logger.info("rec: start")
         counter = 0
         
         # split the audio into chunks the size of one buffer, so we can
         # iterate over the audio in chunksizes of the same size as one buffer
         it_in = iter(np.split(rec.samples, len(rec)/frames_per_buffer))
         try:
             while True:
                 chunk_in    = it_in.next()
                 raw_1d      = np.fromstring(stream.read(frames_per_buffer),
                                             dtype=rec.samples.dtype)
                 # because we use an iterator chunk_in is a sliding window in the rec variable
                 chunk_in[:] = raw_1d.reshape((frames_per_buffer, rec.ch))
                 
                 counter += 1
                 
         except StopIteration:
             pass
             
         finally:
             stream.stop_stream()
             
         self._logger.debug("chunks recorded : %i" %counter)
         self._logger.debug("samples recorded: %i" %(counter*frames_per_buffer))
         self._logger.debug("duration        : %.3f" %(counter*frames_per_buffer/rec.fs))
         
     finally:
         self._logger.debug("rec: close stream")
         stream.close()
         
     # remove the padding (empty frames) added to fill the last buffer. Trim
     # at the start, since we can treat that as latency.
     rec.trim(start=missing_frames, end=None)
     
     self._logger.debug("rec: trimmed %i samples from the start" %missing_frames)
     self._check_if_clipped(rec)
     self._logger.info("rec: done")
     
     return rec
Example #21
0
 def test_set_duration(self):
     x = Audio(duration=1.5, fs=600)
     print(x)
     self.assertEqual(len(x), 900)
Example #22
0
class Test_ConvertBackToBack(unittest.TestCase):
    def setUp(self):
        self.x = Audio(fs=10, initialdata=np.zeros((10, 1)))
        self.x.samples[0] =  -1.0
        self.x.samples[1] =   1.0
        print(self.x)
        print(self.x.samples)
        print()
        
    def quantization_step_size(self, bits):
        return 2**-(bits-1)
    
    def test_float_to_int8_to_float64(self):
        self.x.convert_to_integer(targetbits=8)
        self.x.convert_to_float(targetbits=64)
        print(self.x)
        print(self.x.samples)
        
        q = self.quantization_step_size(8)
        self.assertAlmostEqual(self.x.samples[0], -1.0 + q, places=20)
        self.assertAlmostEqual(self.x.samples[1],  1.0 - q, places=20)
        
    def test_float_to_int16_to_float64(self):
        self.x.convert_to_integer(targetbits=16)
        self.x.convert_to_float(targetbits=64)
        print(self.x)
        print(self.x.samples)
        
        q = self.quantization_step_size(16)
        self.assertAlmostEqual(self.x.samples[0], -1.0 + q, places=20)
        self.assertAlmostEqual(self.x.samples[1],  1.0 - q, places=20)
        
    def test_float_to_int32_to_float64(self):
        self.x.convert_to_integer(targetbits=32)
        self.x.convert_to_float(targetbits=64)
        print(self.x)
        print(self.x.samples)
        
        q = self.quantization_step_size(32)
        self.assertAlmostEqual(self.x.samples[0], -1.0 + q, places=20)
        self.assertAlmostEqual(self.x.samples[1],  1.0 - q, places=20)
Example #23
0
 def get_impulse(self, x):
     """Extract the impulse response. Returns an Audio instance.
     """
     imp = _MLS_base.get_impulse(self, x)
     y = Audio(fs=self.fs, initialdata=imp)
     return y
Example #24
0
 def test_set_duration_and_channels(self):
     x = Audio(duration=1.5, fs=600, channels=5)
     print(x)
     self.assertEqual(len(x), 900)
Example #25
0
 def play_rec(self, x, frames_per_buffer=1024):
     """Play audio and record from input. If dropouts or buffer underruns occur
     try different values for the frames_per_buffer variable."""
     
     _Device.play_rec(self, x)
     self._validate(frames_per_buffer)
     
     missing_frames = self._get_missing_frames(frames_per_buffer, len(x))
     
     # generate silence to fill up missing frames
     pad = Audio(channels=x.ch, fs=x.fs, nofsamples=missing_frames, dtype=x.samples.dtype)
     
     # append the missing frames to a copy of the audio to be played. We now have
     # audio that can be split into complete (full) buffers
     cpy = Audio(fs=x.fs, initialdata=x.samples)
     cpy.concat(pad)
     
     assert len(cpy)%frames_per_buffer == 0
     
     rec = Audio(channels=cpy.ch, fs=cpy.fs, nofsamples=len(cpy), dtype=cpy.samples.dtype)
     
     stream = self.pa.open(format                = self._data_format(x),
                           channels              = x.ch,
                           rate                  = x.fs,
                           frames_per_buffer     = frames_per_buffer,
                           input_device_index    = self._index_in,
                           output_device_index   = self._index_out,
                           input                 = True,
                           output                = True,
                           )
     try:
         self._logger.info("play_rec: start")
         counter = 0
         
         # split the audio into chunks the size of one buffer, so we can
         # iterate over the audio in chunksizes of the same size as one buffer
         it_out = iter(np.split(cpy.samples, len(cpy)/frames_per_buffer))
         it_in  = iter(np.split(rec.samples, len(rec)/frames_per_buffer))
         try:
             while True:
                 chunk_out   = it_out.next()
                 chunk_in    = it_in.next()
                 
                 stream.write(chunk_out.tostring(), num_frames=frames_per_buffer)
                 
                 raw_1d      = np.fromstring(stream.read(frames_per_buffer),
                                             dtype=rec.samples.dtype)
                 # because we use an iterator chunk_in is a sliding window in the rec variable
                 chunk_in[:] = raw_1d.reshape((frames_per_buffer, rec.ch))
                 
                 counter += 1
                 
         except StopIteration:
             pass
             
         finally:
             stream.stop_stream()
             
         self._logger.debug("chunks played  : %i"    %counter)
         self._logger.debug("samples played : %i"    %(counter*frames_per_buffer))
         self._logger.debug("duration       : %.3f"  %(counter*frames_per_buffer/x.fs))
         
     finally:
         self._logger.debug("play_rec: close stream")
         stream.close()
         
     # remove the padding (empty frames) added to fill the last buffer. Trim
     # at the start, since we can treat that as latency.
     rec.trim(start=missing_frames, end=None)
     
     self._logger.debug("play_rec: trimmed %i samples from the start" %missing_frames)
     self._check_if_clipped(rec)
     self._logger.info("play_rec: done")
     
     return rec