def from_wave(cls, filename, wave_filename, compression=None, progress=None): """Encodes a new AudioFile from an existing .wav file. Takes a filename string, wave_filename string of an existing WaveAudio file and an optional compression level string. Encodes a new audio file from the wave's data at the given filename with the specified compression level and returns a new WavPackAudio object.""" from . import encoders if ((compression is None) or (compression not in cls.COMPRESSION_MODES)): compression = __default_quality__(cls.NAME) wave = WaveAudio(wave_filename) (head, tail) = wave.pcm_split() try: encoders.encode_wavpack(filename, to_pcm_progress(wave, progress), wave_header=head, wave_footer=tail, **cls.__options__[compression]) return cls(filename) except (ValueError, IOError), msg: cls.__unlink__(filename) raise EncodingError(str(msg))
def convert(self, target_path, target_class, compression=None, progress=None): """encodes a new AudioFile from existing AudioFile take a filename string, target class and optional compression string encodes a new AudioFile in the target class and returns the resulting object may raise EncodingError if some problem occurs during encoding""" # A Shorten file cannot contain both RIFF and AIFF chunks # at the same time. from audiotools import WaveAudio from audiotools import AiffAudio from audiotools import to_pcm_progress if ((self.has_foreign_wave_chunks() and hasattr(target_class, "from_wave") and callable(target_class.from_wave))): return WaveContainer.convert(self, target_path, target_class, compression, progress) elif (self.has_foreign_aiff_chunks() and hasattr(target_class, "from_aiff") and callable(target_class.from_aiff)): return AiffContainer.convert(self, target_path, target_class, compression, progress) else: return target_class.from_pcm(target_path, to_pcm_progress(self, progress), compression, total_pcm_frames=self.total_frames())
def from_aiff(cls, filename, aiff_filename, compression=None, block_size=256, progress=None): """encodes a new AudioFile from an existing .aiff file takes a filename string, aiff_filename string of an existing WaveAudio file and an optional compression level string encodes a new audio file from the aiff's data at the given filename with the specified compression level and returns a new ShortenAudio object""" aiff = AiffAudio(aiff_filename) if aiff.bits_per_sample() not in (8, 16): raise UnsupportedBitsPerSample(filename, aiff.bits_per_sample()) (head, tail) = aiff.pcm_split() from .encoders import encode_shn try: if len(tail) == 0: encode_shn( filename=filename, pcmreader=to_pcm_progress(aiff, progress), is_big_endian=True, signed_samples=True, header_data=head, block_size=block_size, ) else: encode_shn( filename=filename, pcmreader=to_pcm_progress(aiff, progress), is_big_endian=True, signed_samples=True, header_data=head, footer_data=tail, block_size=block_size, ) return cls(filename) except IOError, err: cls.__unlink__(filename) raise EncodingError(str(err))
def from_wave(cls, filename, wave_filename, compression=None, block_size=256, progress=None): """Encodes a new AudioFile from an existing .wav file. Takes a filename string, wave_filename string of an existing WaveAudio file and an optional compression level string. Encodes a new audio file from the wave's data at the given filename with the specified compression level and returns a new ShortenAudio object.""" wave = WaveAudio(wave_filename) if (wave.bits_per_sample() not in (8, 16)): raise UnsupportedBitsPerSample(filename, wave.bits_per_sample()) (head, tail) = wave.pcm_split() from .encoders import encode_shn try: if (len(tail) == 0): encode_shn(filename=filename, pcmreader=to_pcm_progress(wave, progress), is_big_endian=False, signed_samples=wave.bits_per_sample() == 16, header_data=head, block_size=block_size) else: encode_shn(filename=filename, pcmreader=to_pcm_progress(wave, progress), is_big_endian=False, signed_samples=wave.bits_per_sample() == 16, header_data=head, footer_data=tail, block_size=block_size) return cls(filename) except IOError, err: cls.__unlink__(filename) raise EncodingError(str(err))
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""" from audiotools import CounterPCMReader from audiotools import transfer_framelist_data from audiotools import to_pcm_progress try: (header, footer) = self.wave_header_footer() except IOError as err: raise InvalidWave(err) except ValueError as err: raise InvalidWave(err) # ensure header is valid try: (total_size, data_size) = validate_header(header) except ValueError as err: raise InvalidWave(err) # ensure "data" chunk has all its data counter = CounterPCMReader(to_pcm_progress(self, progress)) try: transfer_framelist_data(counter, lambda f: f) except (IOError, ValueError): from audiotools.text import ERR_WAV_TRUNCATED_DATA_CHUNK raise InvalidWave(ERR_WAV_TRUNCATED_DATA_CHUNK) data_bytes_written = counter.bytes_written() # ensure output data size matches the "data" chunk's size if data_size != data_bytes_written: from audiotools.text import ERR_WAV_TRUNCATED_DATA_CHUNK raise InvalidWave(ERR_WAV_TRUNCATED_DATA_CHUNK) # ensure footer validates correctly try: validate_footer(footer, data_bytes_written) except ValueError as err: from audiotools.text import ERR_WAV_INVALID_SIZE raise InvalidWave(ERR_WAV_INVALID_SIZE) # ensure total size is correct if (len(header) + data_size + len(footer)) != total_size: from audiotools.text import ERR_WAV_INVALID_SIZE raise InvalidWave(ERR_WAV_INVALID_SIZE) return True
def convert(self, target_path, target_class, compression=None, progress=None): """encodes a new AudioFile from existing AudioFile take a filename string, target class and optional compression string encodes a new AudioFile in the target class and returns the resulting object metadata is not copied during conversion, but embedded RIFF chunks are (if any) may raise EncodingError if some problem occurs during encoding""" #Note that a Shorten file cannot contain #both RIFF chunks and AIFF chunks at the same time. import tempfile if (target_class == WaveAudio): self.to_wave(target_path, progress=progress) return WaveAudio(target_path) elif (target_class == AiffAudio): self.to_aiff(target_path, progress=progress) return AiffAudio(target_path) elif (self.has_foreign_riff_chunks() and hasattr(target_class, "from_wave")): temp_wave = tempfile.NamedTemporaryFile(suffix=".wav") try: #we'll only log the second leg of conversion, #since that's likely to be the slower portion self.to_wave(temp_wave.name) return target_class.from_wave(target_path, temp_wave.name, compression, progress=progress) finally: temp_wave.close() elif (self.has_foreign_aiff_chunks() and hasattr(target_class, "from_aiff")): temp_aiff = tempfile.NamedTemporaryFile(suffix=".aiff") try: self.to_aiff(temp_aiff.name) return target_class.from_aiff(target_path, temp_aiff.name, compression, progress=progress) finally: temp_aiff.close() else: return target_class.from_pcm(target_path, to_pcm_progress(self, progress), compression)
def convert(self, target_path, target_class, compression=None, progress=None): """Encodes a new AudioFile from existing AudioFile. Take a filename string, target class and optional compression string. Encodes a new AudioFile in the target class and returns the resulting object. May raise EncodingError if some problem occurs during encoding.""" if (hasattr(target_class, "from_wave")): return target_class.from_wave(target_path, self.filename, compression=compression, progress=progress) else: return target_class.from_pcm(target_path, to_pcm_progress(self, progress), compression)
def from_wave(cls, filename, wave_filename, compression=None, progress=None): """Encodes a new AudioFile from an existing .wav file. Takes a filename string, wave_filename string of an existing WaveAudio file and an optional compression level string. Encodes a new audio file from the wave's data at the given filename with the specified compression level and returns a new M4AAudio object.""" if (compression is None) or (compression not in cls.COMPRESSION_MODES): compression = __default_quality__(cls.NAME) try: wave = WaveAudio(wave_filename) wave.verify() except InvalidFile: raise EncodingError(u"invalid wave file") if wave.sample_rate > 96000: # convert through PCMConverter if sample rate is too high import tempfile tempwavefile = tempfile.NamedTemporaryFile(suffix=".wav") try: tempwave = WaveAudio.from_pcm( tempwavefile.name, PCMConverter( to_pcm_progress(wave, progress), sample_rate=96000, channels=wave.channels(), channel_mask=wave.channel_mask(), bits_per_sample=wave.bits_per_sample(), ), ) return cls.__from_wave__(filename, tempwave.filename, compression) finally: if os.path.isfile(tempwavefile.name): tempwavefile.close() else: tempwavefile.close_called = True else: return cls.__from_wave__(filename, wave_filename, compression)
def convert(self, target_path, target_class, compression=None, progress=None): """encodes a new AudioFile from existing AudioFile take a filename string, target class and optional compression string encodes a new AudioFile in the target class and returns the resulting object may raise EncodingError if some problem occurs during encoding""" # A Shorten file cannot contain both RIFF and AIFF chunks # at the same time. from audiotools import WaveAudio from audiotools import AiffAudio from audiotools import to_pcm_progress if ((self.has_foreign_wave_chunks() and hasattr(target_class, "from_wave") and callable(target_class.from_wave))): return WaveContainer.convert(self, target_path, target_class, compression, progress) elif (self.has_foreign_aiff_chunks() and hasattr(target_class, "from_aiff") and callable(target_class.from_aiff)): return AiffContainer.convert(self, target_path, target_class, compression, progress) else: return target_class.from_pcm( target_path, to_pcm_progress(self, progress), compression, total_pcm_frames=self.total_frames())
def from_aiff(cls, filename, aiff_filename, compression=None, block_size=256, progress=None): """Encodes a new AudioFile from an existing .aiff file. Takes a filename string, aiff_filename string of an existing WaveAudio file and an optional compression level string. Encodes a new audio file from the aiff's data at the given filename with the specified compression level and returns a new ShortenAudio object.""" aiff = AiffAudio(aiff_filename) if (aiff.bits_per_sample() not in (8, 16)): raise UnsupportedBitsPerSample(filename, aiff.bits_per_sample()) (head, tail) = aiff.pcm_split() if (len(tail) > 0): blocks = [head, None, tail] else: blocks = [head, None] import audiotools.encoders try: audiotools.encoders.encode_shn( filename=filename, pcmreader=to_pcm_progress(aiff, progress), block_size=block_size, file_type={8: 1, # 8-bit AIFF seems to be signed 16: 3}[aiff.bits_per_sample()], verbatim_chunks=blocks) return cls(filename) except IOError, err: cls.__unlink__(filename) raise EncodingError(str(err))
current_frames = 0 decoder = decoders.SHNDecoder(self.filename) frame = decoder.read(4096) while (len(frame) > 0): f.write(frame.to_bytes(False, self.bits_per_sample() > 8)) current_frames += frame.frames if (progress is not None): progress(current_frames, total_frames) frame = decoder.read(4096) f.write(tail) f.close() except IOError, msg: self.__unlink__(wave_filename) raise EncodingError(str(msg)) else: WaveAudio.from_pcm(wave_filename, to_pcm_progress(self, progress)) def to_aiff(self, aiff_filename, progress=None): """writes the contents of this file to the given .aiff filename string raises EncodingError if some error occurs during decoding""" from . import decoders try: (head, tail) = decoders.SHNDecoder(self.filename).pcm_split() except IOError: raise EncodingError(str(msg)) if ((head[0:4] == 'FORM') and (head[8:12] == 'AIFF')): try: