def test_is_complete(self):
     # All headers are specified in this header.
     hdr = mp3_header.MP3Header(sampling_rate_hz=44100,
                                bit_rate_kbps=128,
                                padding=False,
                                protected=True,
                                channels=mp3_header.JOINT_STEREO)
     self.assertTrue(hdr.is_complete())
     # This is an incomplete header.
     hdr = mp3_header.MP3Header(sampling_rate_hz=44100)
     self.assertFalse(hdr.is_complete())
Beispiel #2
0
def tuple_to_audio_file(au_file_tuple):
    """Convert a tuple into a new AudioFile object.

    This is the inverse of audio_file_to_tuple.
    """
    au_file = audio_file.AudioFile()
    (au_file.volume, au_file.import_timestamp, au_file.fingerprint,
     raw_album_id, sampling_rate_hz, bit_rate_kbps, channels,
     au_file.frame_count, au_file.frame_size,
     au_file.duration_ms) = au_file_tuple
    au_file.album_id = int(raw_album_id)
    au_file.mp3_header = mp3_header.MP3Header(
        sampling_rate_hz=sampling_rate_hz,
        bit_rate_kbps=bit_rate_kbps,
        channels=channels)
    return au_file
 def __init__(self, src):
     message.MessageConsumer.__init__(self, src)
     message.MessageSource.__init__(self)
     self._expected_hdr = mp3_header.MP3Header(
         sampling_rate_hz=self.sampling_rate_hz)
     self._buffered = []
     # This is the starting ms timestamp of the first block that
     # goes through the splitter.
     self._start_timestamp_ms = None
     # This tracks the number of elapsed ms, based on the MP3 frames
     # that we observe passing through the splitter.
     self._elapsed_frame_ms = 0
     # Normally we expect that the elapsed wall-clock time and the
     # elapsed time based on counting up frame durations will be
     # approximately equal.  This is not always the case, though:
     # when we first connect to a Barix, it will occasionally
     # return up to ~1s of buffered audio almost immediately.  When
     # this happens, it can take 200-300ms before the system gets
     # back into equilibrium of 1 second of audio per second of
     # wall-clock time.  Since there is no time sync in the stream
     # returned by the Barix, we need to introduce a fudge factor
     # to avoid systematic bias when assigning our own start and end
     # times to the messages we produce by splitting the blocks.
     self._start_adjustment_ms = 0
Beispiel #4
0
def get_test_audio_file(n):
    """Generates a test AudioFile object.

    Args:
      n: An integer >= 0; a distinct AudioFile object is generated for
        each value of n.

    Returns:
      An AudioFile object, all of whose fields have been populated with
      test data.
    """
    au_file = audio_file.AudioFile()
    au_file.volume = n
    au_file.import_timestamp = 1229997336 + n
    au_file.fingerprint = "%016x" % n
    au_file.album_id = abs(hash("TALB %d" % n))
    au_file.frame_count = 12345 + (n % 10)
    au_file.frame_size = (8 << 20) + (n << 10)
    au_file.mp3_header = mp3_header.MP3Header(bit_rate_kbps=192 + n,
                                              sampling_rate_hz=44100 + n,
                                              channels=(n % 4))
    au_file.duration_ms = (180 + n) * 1000
    # Assemble fake ID3 tags.
    au_file.mutagen_id3 = mutagen.id3.ID3()
    tpe1 = mutagen.id3.TPE1(text=["TPE1 %d" % n])
    au_file.mutagen_id3.add(tpe1)
    tit2 = mutagen.id3.TIT2(text=["TIT2 %d" % n])
    au_file.mutagen_id3.add(tit2)
    talb = mutagen.id3.TALB(text=["TALB %d" % n])
    au_file.mutagen_id3.add(talb)
    trck = mutagen.id3.TRCK(text=["%d/7" % ((n % 7) + 1)])
    au_file.mutagen_id3.add(trck)
    talb = mutagen.id3.TPUB(text=["  Bad    whitespace    "])
    au_file.mutagen_id3.add(talb)
    # Finally return the thing.
    return au_file
 def test_match(self):
     a = mp3_header.MP3Header(sampling_rate_hz=44100,
                              bit_rate_kbps=128)
     self.assertTrue(a.match(a))
     self.assertTrue(a.match(mp3_header.MP3Header(sampling_rate_hz=44100)))
     self.assertFalse(a.match(mp3_header.MP3Header(bit_rate_kbps=192)))
#!/usr/bin/env python

###
### A unit test for mp3_header.py
###

import unittest
import sys
import mutagen.mp3
from chirp.common import mp3_header


VALID_MP3_HEADERS = {
    '\xff\xfb\x90\x64':
        mp3_header.MP3Header(bit_rate_kbps=128, sampling_rate_hz=44100,
                             channels=mp3_header.JOINT_STEREO,
                             padding=False, protected=False),
    '\xff\xfb\xb0\x00': 
        mp3_header.MP3Header(bit_rate_kbps=192, sampling_rate_hz=44100,
                             channels=mp3_header.STEREO,
                             padding=False, protected=False),
    '\xff\xfb\xb2\x00': 
        mp3_header.MP3Header(bit_rate_kbps=192, sampling_rate_hz=44100,
                             channels=mp3_header.STEREO,
                             padding=True, protected=False),
    }
    

INVALID_MP3_HEADERS = (
    '',
    'GARBAGE',
    def test_basic_injection(self):
        # A mock MP3 frame.
        mock_frame = message.Message()
        mock_frame.message_type = message.FRAME
        mock_frame.payload = "mock frame"
        mock_frame.mp3_header = mp3_header.MP3Header()
        mock_frame.mp3_header.duration_ms = 14000  # A 14-second-long frame

        # A mock block.
        mock_block = message.Message()
        mock_block.message_type = message.BLOCK
        mock_block.payload = "mock block"

        src = message.MessageSource()
        inj = block_injector.BlockInjector(src)
        inj.loop_in_thread()

        # Add 3 frames; since we haven't set a block payload yet, the
        # injector should just let these pass through
        for _ in xrange(3):
            src._add_message(mock_frame)
        src.wait_until_empty()

        # Define a block to be injected.
        injected_one = "Injected Payload"
        inj.set_block_payload(injected_one)

        # Now add 5 more frames.  A block should be injected after the first
        # (i.e. immediately) and fourth (i.e. after >30s elapse) frames.
        for _ in xrange(5):
            src._add_message(mock_frame)
        src._add_message(mock_block)
        # Also add our mock block.  Blocks should pass through the
        # injector without having any effect.
        src.wait_until_empty()

        # Define another block to be injected.
        injected_two = "Another injected payload"
        inj.set_block_payload(injected_two)

        # Now add 5 more frames.  Once again, a block should be
        # injected after the first and fourth frames.
        for _ in xrange(5):
            src._add_message(mock_frame)
        src.wait_until_empty()

        # Clear out the injected block.
        inj.set_block_payload(None)

        # Now add 10 more frames.  Since we cleared our injected block
        # payload, nothing should be injected.
        for _ in xrange(10):
            src._add_message(mock_frame)

        # Stop the source, and wait for the injector to settle.
        src._add_stop_message()
        inj.wait()

        # Now pull all of the messages out of our injector, and check that
        # we got what we expected.
        all_messages = list(inj.get_all_messages())
        # Our initial three frames, plus one more.
        for _ in xrange(4):
            self.assertTrue(all_messages.pop(0) is mock_frame)
        # Our first injected block.
        msg = all_messages.pop(0)
        self.assertEqual(message.BLOCK, msg.message_type)
        self.assertEqual(injected_one, msg.payload)
        # Three more frames.
        for _ in xrange(3):
            self.assertTrue(all_messages.pop(0) is mock_frame)
        # The next injected block.
        msg = all_messages.pop(0)
        self.assertEqual(message.BLOCK, msg.message_type)
        self.assertEqual(injected_one, msg.payload)
        # Another frame.
        self.assertTrue(all_messages.pop(0) is mock_frame)
        # Our mock block
        self.assertTrue(all_messages.pop(0) is mock_block)
        # Another frame.
        self.assertTrue(all_messages.pop(0) is mock_frame)
        # Another injected block, this time with our second payload.
        msg = all_messages.pop(0)
        self.assertEqual(message.BLOCK, msg.message_type)
        self.assertEqual(injected_two, msg.payload)
        # Three more frames.
        for _ in xrange(3):
            self.assertTrue(all_messages.pop(0) is mock_frame)
        # The next injected block.
        msg = all_messages.pop(0)
        self.assertEqual(message.BLOCK, msg.message_type)
        self.assertEqual(injected_two, msg.payload)
        # Eleven more frames.
        for _ in xrange(11):
            self.assertTrue(all_messages.pop(0) is mock_frame)
        # Finally, our end-of-stream marker.
        msg = all_messages.pop(0)
        self.assertTrue(msg.is_end_of_stream())
        # That's all folks!
        self.assertEqual(0, len(all_messages))