def __init__(self, fileobj): super().__init__(RiffChunk, fileobj) if self.root.id != u'RIFF': raise InvalidChunk("Root chunk must be a RIFF chunk, got %s" % self.root.id) self.file_type = self.root.name
def __init__(self, fileobj): # AIFF Files always start with the FORM chunk which contains a 4 byte # ID before the start of other chunks super().__init__(AIFFChunk, fileobj) if self.root.id != u'FORM': raise InvalidChunk("Root chunk must be a FORM chunk, got %s" % self.root.id)
def __init__(self, fileobj, id, data_size, parent_chunk): if id not in (u'RIFF', u'LIST'): raise InvalidChunk('Expected RIFF or LIST chunk, got %s' % id) RiffChunk.__init__(self, fileobj, id, data_size, parent_chunk) self.init_container()
def __init__(self, fileobj): super().__init__(DSDIFFChunk, fileobj) if self.root.id != u'FRM8': raise InvalidChunk("Root chunk must be a FRM8 chunk, got %r" % self.root)
def __init__(self, fileobj, id, data_size, parent_chunk): if id != 'DST': raise InvalidChunk('Not a DST chunk: %s' % id) DSDIFFChunk.__init__(self, fileobj, id, data_size, parent_chunk) self.init_container(name_size=0)
def __init__(self, fileobj, id, data_size, parent_chunk): if id not in self.LIST_CHUNK_IDS: raise InvalidChunk('Not a list chunk: %s' % id) DSDIFFChunk.__init__(self, fileobj, id, data_size, parent_chunk) self.init_container()
def __init__(self, fileobj): """Raises error""" iff = DSDIFFFile(fileobj) try: prop_chunk = iff['PROP'] except KeyError as e: raise error(str(e)) if prop_chunk.name == 'SND ': for chunk in prop_chunk.subchunks(): if chunk.id == 'FS' and chunk.data_size == 4: data = chunk.read() if len(data) < 4: raise InvalidChunk("Not enough data in FS chunk") self.sample_rate, = struct.unpack('>L', data[:4]) elif chunk.id == 'CHNL' and chunk.data_size >= 2: data = chunk.read() if len(data) < 2: raise InvalidChunk("Not enough data in CHNL chunk") self.channels, = struct.unpack('>H', data[:2]) elif chunk.id == 'CMPR' and chunk.data_size >= 4: data = chunk.read() if len(data) < 4: raise InvalidChunk("Not enough data in CMPR chunk") compression_id, = struct.unpack('>4s', data[:4]) self.compression = compression_id.decode('ascii').rstrip() if self.sample_rate < 0: raise error("Invalid sample rate") if self.compression == 'DSD': # not compressed try: dsd_chunk = iff['DSD'] except KeyError as e: raise error(str(e)) # DSD data has one bit per sample. Eight samples of a channel # are clustered together for a channel byte. For multiple channels # the channel bytes are interleaved (in the order specified in the # CHNL chunk). See DSDIFF spec chapter 3.3. sample_count = dsd_chunk.data_size * 8 / (self.channels or 1) if self.sample_rate != 0: self.length = sample_count / float(self.sample_rate) self.bitrate = (self.channels * self.bits_per_sample * self.sample_rate) elif self.compression == 'DST': try: dst_frame = iff['DST'] dst_frame_info = dst_frame['FRTE'] except KeyError as e: raise error(str(e)) if dst_frame_info.data_size >= 6: data = dst_frame_info.read() if len(data) < 6: raise InvalidChunk("Not enough data in FRTE chunk") frame_count, frame_rate = struct.unpack('>LH', data[:6]) if frame_rate: self.length = frame_count / frame_rate if frame_count: dst_data_size = dst_frame.data_size - dst_frame_info.size avg_frame_size = dst_data_size / frame_count self.bitrate = avg_frame_size * 8 * frame_rate
def __init__(self, fileobj, id, data_size, parent_chunk): if id != u'FORM': raise InvalidChunk('Expected FORM chunk, got %s' % id) AIFFChunk.__init__(self, fileobj, id, data_size, parent_chunk) self.init_container()