def __init__(self,
                 aiff_file,
                 sample_rate,
                 channels,
                 channel_mask,
                 bits_per_sample,
                 chunk_length,
                 process=None):
        """aiff_file should be rewound to the start of the SSND chunk."""

        alignment = AiffAudio.SSND_ALIGN.parse_stream(aiff_file)
        PCMReader.__init__(self,
                           file=__capped_stream_reader__(
                               aiff_file,
                               chunk_length - AiffAudio.SSND_ALIGN.sizeof()),
                           sample_rate=sample_rate,
                           channels=channels,
                           channel_mask=channel_mask,
                           bits_per_sample=bits_per_sample,
                           process=process,
                           signed=True,
                           big_endian=True)
        self.ssnd_chunk_length = chunk_length - 8
        standard_channel_mask = ChannelMask(self.channel_mask)
        aiff_channel_mask = AIFFChannelMask(standard_channel_mask)
        if (channels in (3, 4, 6)):
            self.channel_order = [
                aiff_channel_mask.channels().index(channel)
                for channel in standard_channel_mask.channels()
            ]
        else:
            self.channel_order = None
Beispiel #2
0
    def __init__(self, aiff_file,
                 sample_rate, channels, channel_mask, bits_per_sample,
                 chunk_length, process=None):
        """aiff_file should be rewound to the start of the SSND chunk."""

        alignment = AiffAudio.SSND_ALIGN.parse_stream(aiff_file)
        PCMReader.__init__(self,
                           file=__capped_stream_reader__(
                aiff_file,
                chunk_length - AiffAudio.SSND_ALIGN.sizeof()),
                           sample_rate=sample_rate,
                           channels=channels,
                           channel_mask=channel_mask,
                           bits_per_sample=bits_per_sample,
                           process=process,
                           signed=True,
                           big_endian=True)
        self.ssnd_chunk_length = chunk_length - 8
        standard_channel_mask = ChannelMask(self.channel_mask)
        aiff_channel_mask = AIFFChannelMask(standard_channel_mask)
        if (channels in (3, 4, 6)):
            self.channel_order = [aiff_channel_mask.channels().index(channel)
                                  for channel in
                                  standard_channel_mask.channels()]
        else:
            self.channel_order = None
Beispiel #3
0
    def fix_id3_preserve_originals(self, tempFilePath):
        f = file(self.filename, 'rb')

        #figure out where the start and end points of the FLAC file are
        audiotools.ID3v2Comment.skip(f)
        flac_start = f.tell()
        f.seek(-128, 2)
        if (f.read(3) == 'TAG'):
            f.seek(-3, 1)
            flac_end = f.tell()
        else:
            f.seek(0, 2)
            flac_end = f.tell()

        #copy the FLAC data to a temporary location
        temp = tempfile.TemporaryFile()
        f.seek(flac_start, 0)
        reader = audiotools.__capped_stream_reader__(f, flac_end - flac_start)
        audiotools.transfer_data(reader.read, temp.write)

        #rewrite the original FLAC with our temporary data
        temp.seek(0, 0)
        f.close()
        f = file(tempFilePath, 'wb')
        audiotools.transfer_data(temp.read, f.write)
        temp.close()
        f.close()
        returnValue = audiotools.open(tempFilePath)
        return returnValue
Beispiel #4
0
 def to_pcm(self):
     for (chunk_id, chunk_length, chunk_offset) in self.chunks():
         if (chunk_id == 'SSND'):
             f = open(self.filename, 'rb')
             f.seek(chunk_offset, 0)
             alignment = self.SSND_ALIGN.parse_stream(f)
             #FIXME - handle different types of SSND alignment
             pcmreader = PCMReader(__capped_stream_reader__(
                 f, chunk_length - self.SSND_ALIGN.sizeof()),
                                   sample_rate=self.sample_rate(),
                                   channels=self.channels(),
                                   channel_mask=int(self.channel_mask()),
                                   bits_per_sample=self.bits_per_sample(),
                                   signed=True,
                                   big_endian=True)
             if (self.channels() <= 2):
                 return pcmreader
             elif (self.channels() in (3, 4, 6)):
                 #FIXME - handle undefined channel mask
                 standard_channel_mask = self.channel_mask()
                 aiff_channel_mask = AIFFChannelMask(self.channel_mask())
                 return ReorderedPCMReader(pcmreader, [
                     aiff_channel_mask.channels().index(channel)
                     for channel in standard_channel_mask.channels()
                 ])
             else:
                 return pcmreader
     else:
         return PCMReaderError()
Beispiel #5
0
    def chunk_files(self):
        f = open(self.filename, 'rb')
        try:
            aiff_header = self.AIFF_HEADER.parse_stream(f)
        except construct.ConstError:
            raise AiffException(_(u"Not an AIFF file"))
        except construct.core.FieldError:
            raise AiffException(_(u"Invalid AIFF file"))

        total_size = aiff_header.aiff_size - 4
        while (total_size > 0):
            chunk_header = self.CHUNK_HEADER.parse_stream(f)
            total_size -= 8
            yield (chunk_header.chunk_id, chunk_header.chunk_length,
                   __capped_stream_reader__(f, chunk_header.chunk_length))
            total_size -= chunk_header.chunk_length
        f.close()
    def __init__(self,
                 wave_file,
                 sample_rate,
                 channels,
                 channel_mask,
                 bits_per_sample,
                 process=None):
        """wave_file should be a file-like stream of wave data

        sample_rate, channels, channel_mask and bits_per_sample are ints
        if present, process is waited for when close() is called
        """

        self.file = wave_file
        self.sample_rate = sample_rate
        self.channels = channels
        self.bits_per_sample = bits_per_sample
        self.channel_mask = channel_mask

        self.process = process

        from .bitstream import BitstreamReader

        #build a capped reader for the data chunk
        wave_reader = BitstreamReader(wave_file, 1)
        try:
            (riff, wave) = wave_reader.parse("4b 32p 4b")
            if (riff != 'RIFF'):
                raise InvalidWave(_(u"Not a RIFF WAVE file"))
            elif (wave != 'WAVE'):
                raise InvalidWave(_(u"Invalid RIFF WAVE file"))

            while (True):
                (chunk_id, chunk_size) = wave_reader.parse("4b 32u")
                if (chunk_id == 'data'):
                    self.wave = __capped_stream_reader__(self.file, chunk_size)
                    self.data_chunk_length = chunk_size
                    break
                else:
                    wave_reader.skip_bytes(chunk_size)
                    if (chunk_size % 2):
                        wave_reader.skip(8)

        except IOError:
            raise InvalidWave(_(u"data chunk not found"))
    def chunk_files(self):
        """Yields a (chunk_id,length,file) per AIFF chunk.

        The file object is capped to read only its chunk data."""

        f = open(self.filename, 'rb')
        try:
            aiff_header = self.AIFF_HEADER.parse_stream(f)
        except Con.ConstError:
            raise InvalidAIFF(_(u"Not an AIFF file"))
        except Con.core.FieldError:
            raise InvalidAIFF(_(u"Invalid AIFF file"))

        total_size = aiff_header.aiff_size - 4
        while (total_size > 0):
            chunk_header = self.CHUNK_HEADER.parse_stream(f)
            total_size -= 8
            yield (chunk_header.chunk_id, chunk_header.chunk_length,
                   __capped_stream_reader__(f, chunk_header.chunk_length))
            total_size -= chunk_header.chunk_length
        f.close()