def VersionLength(name): """A struct for 32 or 64 bit fields, depending on version field.""" return Con.IfThenElse(name, lambda ctx: ctx["version"] == 0, Con.UBInt32(None), Con.UBInt64(None))
class WavPackAudio(ApeTaggedAudio, AudioFile): """A WavPack audio file.""" SUFFIX = "wv" NAME = SUFFIX DEFAULT_COMPRESSION = "standard" COMPRESSION_MODES = ("veryfast", "fast", "standard", "high", "veryhigh") APE_TAG_CLASS = WavPackAPEv2 HEADER = Con.Struct( "wavpackheader", Con.Const(Con.String("id", 4), 'wvpk'), Con.ULInt32("block_size"), Con.ULInt16("version"), Con.ULInt8("track_number"), Con.ULInt8("index_number"), Con.ULInt32("total_samples"), Con.ULInt32("block_index"), Con.ULInt32("block_samples"), Con.Embed( Con.BitStruct("flags", Con.Flag("floating_point_data"), Con.Flag("hybrid_noise_shaping"), Con.Flag("cross_channel_decorrelation"), Con.Flag("joint_stereo"), Con.Flag("hybrid_mode"), Con.Flag("mono_output"), Con.Bits("bits_per_sample", 2), Con.Bits("left_shift_data_low", 3), Con.Flag("final_block_in_sequence"), Con.Flag("initial_block_in_sequence"), Con.Flag("hybrid_noise_balanced"), Con.Flag("hybrid_mode_control_bitrate"), Con.Flag("extended_size_integers"), Con.Bit("sampling_rate_low"), Con.Bits("maximum_magnitude", 5), Con.Bits("left_shift_data_high", 2), Con.Flag("reserved2"), Con.Flag("false_stereo"), Con.Flag("use_IIR"), Con.Bits("reserved1", 2), Con.Bits("sampling_rate_high", 3))), Con.ULInt32("crc")) SUB_HEADER = Con.Struct( "wavpacksubheader", Con.Embed( Con.BitStruct("flags", Con.Flag("large_block"), Con.Flag("actual_size_1_less"), Con.Flag("nondecoder_data"), Con.Bits("metadata_function", 5))), Con.IfThenElse('size', lambda ctx: ctx['large_block'], ULInt24('s'), Con.Byte('s'))) BITS_PER_SAMPLE = (8, 16, 24, 32) SAMPLING_RATE = (6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 192000, 0) __options__ = { "veryfast": { "block_size": 44100, "joint_stereo": True, "false_stereo": True, "wasted_bits": True, "decorrelation_passes": 1 }, "fast": { "block_size": 44100, "joint_stereo": True, "false_stereo": True, "wasted_bit": True, "decorrelation_passes": 2 }, "standard": { "block_size": 44100, "joint_stereo": True, "false_stereo": True, "wasted_bits": True, "decorrelation_passes": 5 }, "high": { "block_size": 44100, "joint_stereo": True, "false_stereo": True, "wasted_bits": True, "decorrelation_passes": 10 }, "veryhigh": { "block_size": 44100, "joint_stereo": True, "false_stereo": True, "wasted_bits": True, "decorrelation_passes": 16 } } def __init__(self, filename): """filename is a plain string.""" self.filename = filename self.__samplerate__ = 0 self.__channels__ = 0 self.__bitspersample__ = 0 self.__total_frames__ = 0 try: self.__read_info__() except IOError, msg: raise InvalidWavPack(str(msg))