def __init__(self, filename): AudioFile.__init__(self, filename) try: f = file(filename, 'rb') except IOError, msg: raise InvalidAU(str(msg))
def __init__(self, filename): AudioFile.__init__(self, filename) from audiotools.bitstream import BitstreamReader from audiotools.text import (ERR_AU_INVALID_HEADER, ERR_AU_UNSUPPORTED_FORMAT) try: f = open(filename, 'rb') (magic_number, self.__data_offset__, self.__data_size__, encoding_format, self.__sample_rate__, self.__channels__) = BitstreamReader(f, 0).parse("4b 5* 32u") except IOError as msg: raise InvalidAU(str(msg)) if (magic_number != '.snd'): raise InvalidAU(ERR_AU_INVALID_HEADER) try: self.__bits_per_sample__ = {2: 8, 3: 16, 4: 24}[encoding_format] except KeyError: raise InvalidAU(ERR_AU_UNSUPPORTED_FORMAT)
def __init__(self, filename): from audiotools.id3 import skip_id3v2_comment AudioFile.__init__(self, filename) try: with open(filename, "rb") as f: skip_id3v2_comment(f) from audiotools.bitstream import BitstreamReader from audiotools.text import (ERR_TTA_INVALID_SIGNATURE, ERR_TTA_INVALID_FORMAT) reader = BitstreamReader(f, True) (signature, format_, self.__channels__, self.__bits_per_sample__, self.__sample_rate__, self.__total_pcm_frames__) = reader.parse( "4b 16u 16u 16u 32u 32u 32p") if (signature != b"TTA1"): raise InvalidTTA(ERR_TTA_INVALID_SIGNATURE) elif (format_ != 1): raise InvalidTTA(ERR_TTA_INVALID_FORMAT) self.__total_tta_frames__ = div_ceil( self.__total_pcm_frames__ * 245, self.__sample_rate__ * 256) self.__frame_lengths__ = list(reader.parse( "%d* 32u" % (self.__total_tta_frames__) + "32p")) except IOError as msg: raise InvalidTTA(str(msg))
def __init__(self, filename): """filename is a plain string""" AudioFile.__init__(self, filename) self.__channels__ = 0 self.__sample_rate__ = 0 self.__bits_per_sample__ = 0 self.__data_size__ = 0 self.__channel_mask__ = ChannelMask(0) from .bitstream import BitstreamReader fmt_read = data_read = False try: for chunk in self.chunks(): if (chunk.id == "fmt "): try: (self.__channels__, self.__sample_rate__, self.__bits_per_sample__, self.__channel_mask__) = parse_fmt( BitstreamReader(chunk.data(), 1)) fmt_read = True if (fmt_read and data_read): break except IOError: continue elif (chunk.id == "data"): self.__data_size__ = chunk.size() data_read = True if (fmt_read and data_read): break except IOError: raise InvalidWave("I/O error reading wave")
def __init__(self, filename): """filename is a plain string""" from audiotools.bitstream import BitstreamReader AudioFile.__init__(self, filename) # first, fetch the mdia atom # which is the parent of both the mp4a and mdhd atoms try: with BitstreamReader(open(filename, "rb"), False) as reader: mdia = get_m4a_atom(reader, b"moov", b"trak", b"mdia")[1] mdia_start = mdia.getpos() except IOError: from audiotools.text import ERR_M4A_IOERROR raise InvalidM4A(ERR_M4A_IOERROR) except KeyError: from audiotools.text import ERR_M4A_MISSING_MDIA raise InvalidM4A(ERR_M4A_MISSING_MDIA) try: stsd = get_m4a_atom(mdia, b"minf", b"stbl", b"stsd")[1] except KeyError: from audiotools.text import ERR_M4A_MISSING_STSD raise InvalidM4A(ERR_M4A_MISSING_STSD) # then, fetch the mp4a atom for bps, channels and sample rate try: (stsd_version, descriptions) = stsd.parse("8u 24p 32u") (mp4a, self.__channels__, self.__bits_per_sample__) = stsd.parse( "32p 4b 48p 16p 16p 16p 4P 16u 16u 16p 16p 32p") except IOError: from audiotools.text import ERR_M4A_INVALID_MP4A raise InvalidM4A(ERR_M4A_INVALID_MP4A) # finally, fetch the mdhd atom for total track length mdia.setpos(mdia_start) try: mdhd = get_m4a_atom(mdia, b"mdhd")[1] except KeyError: from audiotools.text import ERR_M4A_MISSING_MDHD raise InvalidM4A(ERR_M4A_MISSING_MDHD) try: (version, ) = mdhd.parse("8u 24p") if version == 0: (self.__sample_rate__, self.__length__,) = mdhd.parse("32p 32p 32u 32u 2P 16p") elif version == 1: (self.__sample_rate__, self.__length__,) = mdhd.parse("64p 64p 32u 64U 2P 16p") else: from audiotools.text import ERR_M4A_UNSUPPORTED_MDHD raise InvalidM4A(ERR_M4A_UNSUPPORTED_MDHD) except IOError: from audiotools.text import ERR_M4A_INVALID_MDHD raise InvalidM4A(ERR_M4A_INVALID_MDHD)
def __init__(self, filename): """filename is a plain string.""" AudioFile.__init__(self, filename) try: f = open(filename, 'rb') except IOError, msg: raise InvalidShorten(str(msg))
def __init__(self, filename): """filename is a plain string.""" AudioFile.__init__(self, filename) try: self.__read_metadata__() except IOError, msg: raise InvalidVorbis(str(msg))
def __init__(self, filename): """filename is a plain string.""" AudioFile.__init__(self, filename) (self.__samplespersec__, self.__channels__, self.__bitspersample__, self.__totalsamples__) = ApeAudio.__ape_info__(filename)
def __init__(self, filename): """filename is a plain string.""" AudioFile.__init__(self, filename) try: mp3file = file(filename, "rb") except IOError, msg: raise InvalidMP3(str(msg))
def __init__(self, filename): """filename is a plain string""" AudioFile.__init__(self, filename) self.__sample_rate__ = 0 self.__channels__ = 0 try: self.__read_identification__() except IOError, msg: raise InvalidVorbis(str(msg))
def __init__(self, filename): """filename is a plain string""" from audiotools.bitstream import BitstreamReader AudioFile.__init__(self, filename) try: f = open(filename, 'rb') except IOError, msg: raise InvalidShorten(str(msg))
def __init__(self, filename): """filename is a plain string.""" AudioFile.__init__(self, filename) from .bitstream import BitstreamReader try: mp3file = open(filename, "rb") except IOError, msg: raise InvalidMP3(str(msg))
def __init__(self, filename): """filename is a plain string""" from .bitstream import BitstreamReader from . import ChannelMask import cStringIO AudioFile.__init__(self, filename) try: f = open(filename, 'rb') except IOError, msg: raise InvalidShorten(str(msg))
def verify(self, progress=None): """verifies the current file for correctness returns True if the file is okay raises an InvalidFile with an error message if there is some problem with the file""" # Checking for a truncated Ogg stream typically involves # verifying that the "end of stream" flag is set on the last # Ogg page in the stream in the event that one or more whole # pages is lost. But since the OpusFile decoder doesn't perform # this check and doesn't provide any access to its internal # Ogg decoder (unlike Vorbis), we'll perform that check externally. # # And since it's a fast check, we won't bother to update progress. from audiotools.ogg import PageReader import os.path try: reader = PageReader(open(self.filename, "rb")) except IOError as err: raise InvalidOpus(str(err)) try: page = reader.read() while (not page.stream_end): page = reader.read() reader.close() except (IOError, ValueError) as err: raise InvalidOpus(str(err)) return AudioFile.verify(self, progress)
def __init__(self, filename): from audiotools.bitstream import BitstreamReader AudioFile.__init__(self, filename) try: with BitstreamReader( open(self.filename, "rb"), True) as ogg_reader: (magic_number, version, header_type, granule_position, self.__serial_number__, page_sequence_number, checksum, segment_count) = ogg_reader.parse("4b 8u 8u 64S 32u 32u 32u 8u") if magic_number != b'OggS': from audiotools.text import ERR_OGG_INVALID_MAGIC_NUMBER raise InvalidVorbis(ERR_OGG_INVALID_MAGIC_NUMBER) if version != 0: from audiotools.text import ERR_OGG_INVALID_VERSION raise InvalidVorbis(ERR_OGG_INVALID_VERSION) segment_lengths = [ogg_reader.read(8) for i in range(segment_count)] (speex_string, speex_version, speex_version_id, header_size, self.__sampling_rate__, mode, mode_bitstream_version, self.__channels__, bitrate, frame_size, vbr, frame_per_packet, extra_headers, reserved1, reserved2) = ogg_reader.parse("8b 20b 13*32u") if speex_string != b"Speex ": raise InvalidSpeex(ERR_SPEEX_INVALID_VERSION) except IOError as err: raise InvalidSpeex(str(err))
def __init__(self, filename): AudioFile.__init__(self, filename) from .bitstream import BitstreamReader try: f = file(filename, 'rb') (magic_number, self.__data_offset__, self.__data_size__, encoding_format, self.__sample_rate__, self.__channels__) = BitstreamReader(f, 0).parse( "4b 32u 32u 32u 32u 32u") except IOError, msg: raise InvalidAU(str(msg))
def __init__(self, filename): """filename is a plain string.""" AudioFile.__init__(self, filename) f = file(filename, 'rb') try: if (f.read(4) == 'MPCK'): # a Musepack 8 stream for (key, packet) in Musepack8StreamReader(f).packets(): if (key == 'SH'): header = MusepackAudio.MUSEPACK8_HEADER.parse(packet) self.__sample_rate__ = (44100, 48000, 37800, 32000)[ header.sample_frequency] self.__total_frames__ = header.sample_count self.__channels__ = header.channel_count + 1 break elif (key == 'SE'): raise InvalidFile(_(u'No Musepack header found')) else: # a Musepack 7 stream f.seek(0, 0) try: header = MusepackAudio.MUSEPACK7_HEADER.parse_stream(f) except Con.ConstError: raise InvalidFile(_(u'Musepack signature incorrect')) header.last_frame_length = \ (header.last_frame_length_high << 4) | \ header.last_frame_length_low self.__sample_rate__ = (44100, 48000, 37800, 32000)[header.sample_frequency] self.__total_frames__ = (((header.frame_count - 1) * 1152) + header.last_frame_length) self.__channels__ = 2 finally: f.close()
def __init__(self, filename): """filename is a plain string""" AudioFile.__init__(self, filename) try: block = BitstreamReader(self.get_block(b"SH"), False) crc = block.read(32) if block.read(8) != 8: from audiotools.text import ERR_MPC_INVALID_VERSION raise InvalidMPC(ERR_MPC_INVALID_VERSION) self.__samples__ = int(MPC_Size.parse(block)) beg_silence = int(MPC_Size.parse(block)) self.__sample_rate__ = \ [44100, 48000, 37800, 32000][block.read(3)] max_band = block.read(5) + 1 self.__channels__ = block.read(4) + 1 ms = block.read(1) block_pwr = block.read(3) * 2 except IOError as err: raise InvalidMPC(str(err))
def __init__(self, filename): AudioFile.__init__(self, filename) from audiotools.bitstream import parse from audiotools.text import (ERR_AU_INVALID_HEADER, ERR_AU_UNSUPPORTED_FORMAT) try: with open(filename, "rb") as f: (magic_number, self.__data_offset__, self.__data_size__, encoding_format, self.__sample_rate__, self.__channels__) = parse("4b 5* 32u", False, f.read(24)) except IOError as msg: raise InvalidAU(str(msg)) if magic_number != b'.snd': raise InvalidAU(ERR_AU_INVALID_HEADER) try: self.__bits_per_sample__ = {2: 8, 3: 16, 4: 24}[encoding_format] except KeyError: raise InvalidAU(ERR_AU_UNSUPPORTED_FORMAT)
def __init__(self, filename): """filename is a plain string.""" AudioFile.__init__(self, filename) self.__wavtype__ = 0 self.__channels__ = 0 self.__samplespersec__ = 0 self.__bytespersec__ = 0 self.__blockalign__ = 0 self.__bitspersample__ = 0 self.__data_size__ = 0 self.__channel_mask__ = ChannelMask(0) self.__chunk_ids__ = [] from .bitstream import BitstreamReader try: wave_file = BitstreamReader(open(filename, 'rb'), 1) except IOError, msg: raise InvalidWave(str(msg))
def __init__(self, filename): AudioFile.__init__(self, filename) f = file(filename, 'rb') try: header = AuAudio.AU_HEADER.parse_stream(f) if (header.encoding_format not in (2, 3, 4)): raise InvalidFile(_(u"Unsupported Sun AU encoding format")) self.__bits_per_sample__ = { 2: 8, 3: 16, 4: 24 }[header.encoding_format] self.__channels__ = header.channels self.__sample_rate__ = header.sample_rate self.__total_frames__ = header.data_size / \ (self.__bits_per_sample__ / 8) / \ self.__channels__ self.__data_offset__ = header.data_offset self.__data_size__ = header.data_size except construct.ConstError: raise InvalidFile(str(msg))
def track_name(cls, file_path, track_metadata=None, format=None): """constructs a new filename string given a plain string to an existing path, a MetaData-compatible object (or None), a UTF-8-encoded Python format string and an ASCII-encoded suffix string (such as "mp3") returns a plain string of a new filename with format's fields filled-in and encoded as FS_ENCODING raises UnsupportedTracknameField if the format string contains invalid template fields""" if format is None: format = "track%(track_number)2.2d.wav" return AudioFile.track_name(file_path, track_metadata, format, suffix=cls.SUFFIX)
def track_name(cls, file_path, track_metadata=None, format=None): """Constructs a new filename string. Given a plain string to an existing path, a MetaData-compatible object (or None), a UTF-8-encoded Python format string and an ASCII-encoded suffix string (such as "mp3") returns a plain string of a new filename with format's fields filled-in and encoded as FS_ENCODING. Raises UnsupportedTracknameField if the format string contains invalid template fields.""" if (format is None): format = "track%(track_number)2.2d.wav" return AudioFile.track_name(file_path, track_metadata, format, suffix=cls.SUFFIX)
def verify(self, progress=None): """verifies the current file for correctness returns True if the file is okay raises an InvalidFile with an error message if there is some problem with the file""" # Checking for a truncated Ogg stream typically involves # verifying that the "end of stream" flag is set on the last # Ogg page in the stream in the event that one or more whole # pages is lost. But since the OpusFile decoder doesn't perform # this check and doesn't provide any access to its internal # Ogg decoder (unlike Vorbis), we'll perform that check externally. # # And since it's a fast check, we won't bother to update progress. from audiotools.ogg import PageReader import os.path try: f = open(self.filename, "rb") except IOError as err: raise InvalidOpus(str(err)) try: reader = PageReader(f) except IOError as err: f.close() raise InvalidOpus(str(err)) try: page = reader.read() while not page.stream_end: page = reader.read() except (IOError, ValueError) as err: raise InvalidOpus(str(err)) finally: reader.close() return AudioFile.verify(self, progress)
def __init__(self, filename): AudioFile.__init__(self, filename)
def __init__(self, filename): """filename is a plain string""" AudioFile.__init__(self, filename) from audiotools.bitstream import parse try: mp3file = open(filename, "rb") except IOError as msg: raise InvalidMP3(str(msg)) try: try: header_bytes = MP3Audio.__find_next_mp3_frame__(mp3file) except IOError: from audiotools.text import ERR_MP3_FRAME_NOT_FOUND raise InvalidMP3(ERR_MP3_FRAME_NOT_FOUND) (frame_sync, mpeg_id, layer, bit_rate, sample_rate, pad, channels) = parse("11u 2u 2u 1p 4u 2u 1u 1p 2u 6p", False, mp3file.read(4)) self.__samplerate__ = self.SAMPLE_RATE[mpeg_id][sample_rate] if self.__samplerate__ is None: from audiotools.text import ERR_MP3_INVALID_SAMPLE_RATE raise InvalidMP3(ERR_MP3_INVALID_SAMPLE_RATE) if channels in (0, 1, 2): self.__channels__ = 2 else: self.__channels__ = 1 first_frame = mp3file.read( self.frame_length(mpeg_id, layer, bit_rate, sample_rate, pad) - 4) if ((b"Xing" in first_frame) and (len(first_frame[first_frame. index(b"Xing"):first_frame.index(b"Xing") + 160]) == 160)): # pull length from Xing header, if present self.__pcm_frames__ = (parse( "32p 32p 32u 32p 832p", 0, first_frame[first_frame.index( b"Xing"):first_frame.index(b"Xing") + 160])[0] * self.PCM_FRAMES_PER_MPEG_FRAME[layer]) else: # otherwise, bounce through file frames from audiotools.bitstream import BitstreamReader reader = BitstreamReader(mp3file, False) self.__pcm_frames__ = 0 try: (frame_sync, mpeg_id, layer, bit_rate, sample_rate, pad) = reader.parse("11u 2u 2u 1p 4u 2u 1u 9p") while frame_sync == 0x7FF: self.__pcm_frames__ += \ self.PCM_FRAMES_PER_MPEG_FRAME[layer] reader.skip_bytes( self.frame_length(mpeg_id, layer, bit_rate, sample_rate, pad) - 4) (frame_sync, mpeg_id, layer, bit_rate, sample_rate, pad) = reader.parse("11u 2u 2u 1p 4u 2u 1u 9p") except IOError: pass except ValueError as err: raise InvalidMP3(err) finally: mp3file.close()
def __init__(self, filename): """filename is a plain string""" from audiotools.bitstream import BitstreamReader AudioFile.__init__(self, filename) # first, fetch the mdia atom # which is the parent of both the alac and mdhd atoms try: with BitstreamReader(open(filename, "rb"), False) as reader: mdia = get_m4a_atom(reader, b"moov", b"trak", b"mdia")[1] mdia_start = mdia.getpos() except IOError: from audiotools.text import ERR_ALAC_IOERROR raise InvalidALAC(ERR_ALAC_IOERROR) except KeyError: from audiotools.text import ERR_M4A_MISSING_MDIA raise InvalidALAC(ERR_M4A_MISSING_MDIA) try: stsd = get_m4a_atom(mdia, b"minf", b"stbl", b"stsd")[1] except KeyError: from audiotools.text import ERR_M4A_MISSING_STSD raise InvalidALAC(ERR_M4A_MISSING_STSD) # then, fetch the alac atom for bps, channels and sample rate try: # though some of these fields are parsed redundantly # in .to_pcm(), we still need to parse them here # to fetch values for .bits_per_sample(), etc. (stsd_version, descriptions) = stsd.parse("8u 24p 32u") (alac1, alac2, self.__max_samples_per_frame__, self.__bits_per_sample__, self.__history_multiplier__, self.__initial_history__, self.__maximum_k__, self.__channels__, self.__sample_rate__) = stsd.parse( # ignore much of the stuff in the "high" ALAC atom "32p 4b 6P 16p 16p 16p 4P 16p 16p 16p 16p 4P" + # and use the attributes in the "low" ALAC atom instead "32p 4b 4P 32u 8p 8u 8u 8u 8u 8u 16p 32p 32p 32u") except IOError: from audiotools.text import ERR_ALAC_INVALID_ALAC raise InvalidALAC(ERR_ALAC_INVALID_ALAC) if (alac1 != b'alac') or (alac2 != b'alac'): from audiotools.text import ERR_ALAC_INVALID_ALAC raise InvalidALAC(ERR_ALAC_INVALID_ALAC) # finally, fetch the mdhd atom for total track length mdia.setpos(mdia_start) try: mdhd = get_m4a_atom(mdia, b"mdhd")[1] except KeyError: from audiotools.text import ERR_M4A_MISSING_MDHD raise InvalidALAC(ERR_M4A_MISSING_MDHD) try: (version, ) = mdhd.parse("8u 24p") if version == 0: (self.__length__, ) = mdhd.parse("32p 32p 32p 32u 2P 16p") elif version == 1: (self.__length__, ) = mdhd.parse("64p 64p 32p 64U 2P 16p") else: from audiotools.text import ERR_M4A_UNSUPPORTED_MDHD raise InvalidALAC(ERR_M4A_UNSUPPORTED_MDHD) except IOError: from audiotools.text import ERR_M4A_INVALID_MDHD raise InvalidALAC(ERR_M4A_INVALID_MDHD)
def __init__(self, filename): AudioFile.__init__(self, filename) self.__read_metadata__()
import os.path try: reader = PageReader(open(self.filename, "rb")) except IOError, err: raise InvalidOpus(str(err)) try: page = reader.read() while (not page.stream_end): page = reader.read() reader.close() except (IOError, ValueError), err: raise InvalidOpus(str(err)) return AudioFile.verify(self, progress) @classmethod def available(cls, system_binaries): """returns True if all necessary compenents are available to support format""" try: from audiotools.decoders import OpusDecoder from audiotools.encoders import encode_opus return True except ImportError: return False @classmethod
def __init__(self, filename): AudioFile.__init__(self, filename) (self.__samplespersec__, self.__channels__, self.__bitspersample__, self.__totalsamples__) = ApeAudio.__ape_info__(filename)
def __init__(self, filename): """filename is a plain string""" AudioFile.__init__(self, filename) self.__channels__ = 0 self.__channel_mask__ = 0 # get channel count and channel mask from first packet from audiotools.bitstream import BitstreamReader try: with BitstreamReader(open(filename, "rb"), True) as ogg_reader: (magic_number, version, header_type, granule_position, self.__serial_number__, page_sequence_number, checksum, segment_count) = ogg_reader.parse( "4b 8u 8u 64S 32u 32u 32u 8u") if magic_number != b'OggS': from audiotools.text import ERR_OGG_INVALID_MAGIC_NUMBER raise InvalidOpus(ERR_OGG_INVALID_MAGIC_NUMBER) if version != 0: from audiotools.text import ERR_OGG_INVALID_VERSION raise InvalidOpus(ERR_OGG_INVALID_VERSION) segment_length = ogg_reader.read(8) (opushead, version, self.__channels__, pre_skip, input_sample_rate, output_gain, mapping_family) = ogg_reader.parse( "8b 8u 8u 16u 32u 16s 8u") if opushead != b"OpusHead": from audiotools.text import ERR_OPUS_INVALID_TYPE raise InvalidOpus(ERR_OPUS_INVALID_TYPE) if version != 1: from audiotools.text import ERR_OPUS_INVALID_VERSION raise InvalidOpus(ERR_OPUS_INVALID_VERSION) if self.__channels__ == 0: from audiotools.text import ERR_OPUS_INVALID_CHANNELS raise InvalidOpus(ERR_OPUS_INVALID_CHANNELS) # FIXME - assign channel mask from mapping family if mapping_family == 0: if self.__channels__ == 1: self.__channel_mask__ = VorbisChannelMask(0x4) elif self.__channels__ == 2: self.__channel_mask__ = VorbisChannelMask(0x3) else: self.__channel_mask__ = VorbisChannelMask(0) else: (stream_count, coupled_stream_count) = ogg_reader.parse("8u 8u") if (self.__channels__ != ((coupled_stream_count * 2) + (stream_count - coupled_stream_count))): from audiotools.text import ERR_OPUS_INVALID_CHANNELS raise InvalidOpus(ERR_OPUS_INVALID_CHANNELS) channel_mapping = [ogg_reader.read(8) for i in range(self.__channels__)] except IOError as msg: raise InvalidOpus(str(msg))
def __init__(self, filename): """filename is a plain string""" AudioFile.__init__(self, filename) from audiotools.bitstream import parse try: mp3file = open(filename, "rb") except IOError as msg: raise InvalidMP3(str(msg)) try: try: header_bytes = MP3Audio.__find_next_mp3_frame__(mp3file) except IOError: from audiotools.text import ERR_MP3_FRAME_NOT_FOUND raise InvalidMP3(ERR_MP3_FRAME_NOT_FOUND) (frame_sync, mpeg_id, layer, bit_rate, sample_rate, pad, channels) = parse("11u 2u 2u 1p 4u 2u 1u 1p 2u 6p", False, mp3file.read(4)) self.__samplerate__ = self.SAMPLE_RATE[mpeg_id][sample_rate] if self.__samplerate__ is None: from audiotools.text import ERR_MP3_INVALID_SAMPLE_RATE raise InvalidMP3(ERR_MP3_INVALID_SAMPLE_RATE) if channels in (0, 1, 2): self.__channels__ = 2 else: self.__channels__ = 1 first_frame = mp3file.read(self.frame_length(mpeg_id, layer, bit_rate, sample_rate, pad) - 4) if ((b"Xing" in first_frame) and (len(first_frame[first_frame.index(b"Xing"): first_frame.index(b"Xing") + 160]) == 160)): # pull length from Xing header, if present self.__pcm_frames__ = ( parse("32p 32p 32u 32p 832p", 0, first_frame[first_frame.index(b"Xing"): first_frame.index(b"Xing") + 160])[0] * self.PCM_FRAMES_PER_MPEG_FRAME[layer]) else: # otherwise, bounce through file frames from audiotools.bitstream import BitstreamReader reader = BitstreamReader(mp3file, False) self.__pcm_frames__ = 0 try: (frame_sync, mpeg_id, layer, bit_rate, sample_rate, pad) = reader.parse("11u 2u 2u 1p 4u 2u 1u 9p") while frame_sync == 0x7FF: self.__pcm_frames__ += \ self.PCM_FRAMES_PER_MPEG_FRAME[layer] reader.skip_bytes(self.frame_length(mpeg_id, layer, bit_rate, sample_rate, pad) - 4) (frame_sync, mpeg_id, layer, bit_rate, sample_rate, pad) = reader.parse("11u 2u 2u 1p 4u 2u 1u 9p") except IOError: pass except ValueError as err: raise InvalidMP3(err) finally: mp3file.close()
def __init__(self, filename): """filename is a plain string""" AudioFile.__init__(self, filename) self.__channels__ = 0 self.__channel_mask__ = 0 # get channel count and channel mask from first packet from audiotools.bitstream import BitstreamReader try: f = open(filename, "rb") try: ogg_reader = BitstreamReader(f, 1) (magic_number, version, header_type, granule_position, self.__serial_number__, page_sequence_number, checksum, segment_count ) = ogg_reader.parse("4b 8u 8u 64S 32u 32u 32u 8u") if (magic_number != 'OggS'): from audiotools.text import ERR_OGG_INVALID_MAGIC_NUMBER raise InvalidOpus(ERR_OGG_INVALID_MAGIC_NUMBER) if (version != 0): from audiotools.text import ERR_OGG_INVALID_VERSION raise InvalidOpus(ERR_OGG_INVALID_VERSION) segment_length = ogg_reader.read(8) (opushead, version, self.__channels__, pre_skip, input_sample_rate, output_gain, mapping_family) = ogg_reader.parse("8b 8u 8u 16u 32u 16s 8u") if (opushead != "OpusHead"): from audiotools.text import ERR_OPUS_INVALID_TYPE raise InvalidOpus(ERR_OPUS_INVALID_TYPE) if (version != 1): from audiotools.text import ERR_OPUS_INVALID_VERSION raise InvalidOpus(ERR_OPUS_INVALID_VERSION) if (self.__channels__ == 0): from audiotools.text import ERR_OPUS_INVALID_CHANNELS raise InvalidOpus(ERR_OPUS_INVALID_CHANNELS) # FIXME - assign channel mask from mapping family if (mapping_family == 0): if (self.__channels__ == 1): self.__channel_mask__ = VorbisChannelMask(0x4) elif (self.__channels__ == 2): self.__channel_mask__ = VorbisChannelMask(0x3) else: self.__channel_mask__ = VorbisChannelMask(0) else: (stream_count, coupled_stream_count) = ogg_reader.parse("8u 8u") if (self.__channels__ != ((coupled_stream_count * 2) + (stream_count - coupled_stream_count))): from audiotools.text import ERR_OPUS_INVALID_CHANNELS raise InvalidOpus(ERR_OPUS_INVALID_CHANNELS) channel_mapping = [ ogg_reader.read(8) for i in range(self.__channels__) ] finally: f.close() except IOError as msg: raise InvalidOpus(str(msg))
def __init__(self, filename): """filename is a plain string""" from audiotools.bitstream import BitstreamReader AudioFile.__init__(self, filename) # first, fetch the mdia atom # which is the parent of both the alac and mdhd atoms try: with BitstreamReader(open(filename, "rb"), False) as reader: mdia = get_m4a_atom(reader, b"moov", b"trak", b"mdia")[1] mdia_start = mdia.getpos() except IOError: from audiotools.text import ERR_ALAC_IOERROR raise InvalidALAC(ERR_ALAC_IOERROR) except KeyError: from audiotools.text import ERR_M4A_MISSING_MDIA raise InvalidALAC(ERR_M4A_MISSING_MDIA) try: stsd = get_m4a_atom(mdia, b"minf", b"stbl", b"stsd")[1] except KeyError: from audiotools.text import ERR_M4A_MISSING_STSD raise InvalidALAC(ERR_M4A_MISSING_STSD) # then, fetch the alac atom for bps, channels and sample rate try: # though some of these fields are parsed redundantly # in .to_pcm(), we still need to parse them here # to fetch values for .bits_per_sample(), etc. (stsd_version, descriptions) = stsd.parse("8u 24p 32u") (alac1, alac2, self.__max_samples_per_frame__, self.__bits_per_sample__, self.__history_multiplier__, self.__initial_history__, self.__maximum_k__, self.__channels__, self.__sample_rate__) = stsd.parse( # ignore much of the stuff in the "high" ALAC atom "32p 4b 6P 16p 16p 16p 4P 16p 16p 16p 16p 4P" + # and use the attributes in the "low" ALAC atom instead "32p 4b 4P 32u 8p 8u 8u 8u 8u 8u 16p 32p 32p 32u") except IOError: from audiotools.text import ERR_ALAC_INVALID_ALAC raise InvalidALAC(ERR_ALAC_INVALID_ALAC) if (alac1 != b'alac') or (alac2 != b'alac'): from audiotools.text import ERR_ALAC_INVALID_ALAC raise InvalidALAC(ERR_ALAC_INVALID_ALAC) # finally, fetch the mdhd atom for total track length mdia.setpos(mdia_start) try: mdhd = get_m4a_atom(mdia, b"mdhd")[1] except KeyError: from audiotools.text import ERR_M4A_MISSING_MDHD raise InvalidALAC(ERR_M4A_MISSING_MDHD) try: (version, ) = mdhd.parse("8u 24p") if version == 0: (self.__length__,) = mdhd.parse("32p 32p 32p 32u 2P 16p") elif version == 1: (self.__length__,) = mdhd.parse("64p 64p 32p 64U 2P 16p") else: from audiotools.text import ERR_M4A_UNSUPPORTED_MDHD raise InvalidALAC(ERR_M4A_UNSUPPORTED_MDHD) except IOError: from audiotools.text import ERR_M4A_INVALID_MDHD raise InvalidALAC(ERR_M4A_INVALID_MDHD)