def from_pcm(cls, filename, pcmreader, compression=None): """Returns a PCMReader object containing the track's PCM data.""" if ((compression is None) or (compression not in cls.COMPRESSION_MODES)): compression = __default_quality__(cls.NAME) devnull = file(os.devnull, 'ab') sub = subprocess.Popen([ BIN['oggenc'], '-Q', '-r', '-B', str(pcmreader.bits_per_sample), '-C', str(pcmreader.channels), '-R', str(pcmreader.sample_rate), '--raw-endianness', str(0), '-q', compression, '-o', filename, '-' ], stdin=subprocess.PIPE, stdout=devnull, stderr=devnull, preexec_fn=ignore_sigint) if ((pcmreader.channels <= 2) or (int(pcmreader.channel_mask) == 0)): try: transfer_framelist_data(pcmreader, sub.stdin.write) except (IOError, ValueError), err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise EncodingError(str(err)) except Exception, err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise err
def from_pcm(cls, filename, pcmreader, compression=None): """Returns a PCMReader object containing the track's PCM data.""" if ((compression is None) or (compression not in cls.COMPRESSION_MODES)): compression = __default_quality__(cls.NAME) devnull = file(os.devnull, 'ab') sub = subprocess.Popen([BIN['oggenc'], '-Q', '-r', '-B', str(pcmreader.bits_per_sample), '-C', str(pcmreader.channels), '-R', str(pcmreader.sample_rate), '--raw-endianness', str(0), '-q', compression, '-o', filename, '-'], stdin=subprocess.PIPE, stdout=devnull, stderr=devnull, preexec_fn=ignore_sigint) if ((pcmreader.channels <= 2) or (int(pcmreader.channel_mask) == 0)): try: transfer_framelist_data(pcmreader, sub.stdin.write) except (IOError, ValueError), err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise EncodingError(str(err)) except Exception, err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise err
def from_pcm(cls, filename, pcmreader, compression="2"): import decimal,bisect if (compression not in cls.COMPRESSION_MODES): compression = cls.DEFAULT_COMPRESSION if ((pcmreader.channels > 2) or (pcmreader.sample_rate not in (32000,48000,44100))): pcmreader = PCMConverter( pcmreader, sample_rate=[32000,32000,44100,48000][bisect.bisect( [32000,44100,48000],pcmreader.sample_rate)], channels=min(pcmreader.channels,2), channel_mask=ChannelMask.from_channels(min(pcmreader.channels,2)), bits_per_sample=16) if (pcmreader.channels > 1): mode = "j" else: mode = "m" #FIXME - not sure if all LAME versions support "--little-endian" # #LAME 3.98 (and up, presumably) handle the byteswap correctly # #LAME 3.97 always uses -x # if (BIG_ENDIAN or (cls.__lame_version__() < (3,98))): # endian = ['-x'] # else: # endian = [] devnull = file(os.devnull,'ab') sub = subprocess.Popen([BIN['lame'],"--quiet", "-r", "-s",str(decimal.Decimal(pcmreader.sample_rate) / 1000), "--bitwidth",str(pcmreader.bits_per_sample), "--signed","--little-endian", "-m",mode, "-V" + str(compression), "-", filename], stdin=subprocess.PIPE, stdout=devnull, stderr=devnull, preexec_fn=ignore_sigint) transfer_framelist_data(pcmreader,sub.stdin.write) try: pcmreader.close() except DecodingError: raise EncodingError() sub.stdin.close() devnull.close() if (sub.wait() == 0): return MP3Audio(filename) else: raise EncodingError(BIN['lame'])
def from_pcm(cls, filename, pcmreader, compression=None): """Encodes a new file from PCM data. Takes a filename string, PCMReader object and optional compression level string. Encodes a new audio file from pcmreader's data at the given filename with the specified compression level and returns a new SpeexAudio object.""" import bisect if ((compression is None) or (compression not in cls.COMPRESSION_MODES)): compression = __default_quality__(cls.NAME) if ((pcmreader.bits_per_sample not in (8, 16)) or (pcmreader.channels > 2) or (pcmreader.sample_rate not in (8000, 16000, 32000, 44100))): pcmreader = PCMConverter( pcmreader, sample_rate=[8000, 8000, 16000, 32000, 44100][bisect.bisect([8000, 16000, 32000, 44100], pcmreader.sample_rate)], channels=min(pcmreader.channels, 2), channel_mask=ChannelMask.from_channels( min(pcmreader.channels, 2)), bits_per_sample=min(pcmreader.bits_per_sample, 16)) BITS_PER_SAMPLE = { 8: ['--8bit'], 16: ['--16bit'] }[pcmreader.bits_per_sample] CHANNELS = {1: [], 2: ['--stereo']}[pcmreader.channels] devnull = file(os.devnull, "ab") sub = subprocess.Popen([BIN['speexenc'], '--quality', str(compression), '--rate', str(pcmreader.sample_rate), '--le'] + \ BITS_PER_SAMPLE + \ CHANNELS + \ ['-', filename], stdin=subprocess.PIPE, stderr=devnull, preexec_fn=ignore_sigint) try: transfer_framelist_data(pcmreader, sub.stdin.write) except (IOError, ValueError), err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise EncodingError(str(err))
def from_pcm(cls, filename, pcmreader, compression=None): if (compression not in cls.COMPRESSION_MODES): compression = cls.DEFAULT_COMPRESSION devnull = file(os.devnull, 'ab') sub = subprocess.Popen([ BIN['oggenc'], '-Q', '-r', '-B', str(pcmreader.bits_per_sample), '-C', str(pcmreader.channels), '-R', str(pcmreader.sample_rate), '--raw-endianness', str(0), '-q', compression, '-o', filename, '-' ], stdin=subprocess.PIPE, stdout=devnull, stderr=devnull, preexec_fn=ignore_sigint) if ((pcmreader.channels <= 2) or (int(pcmreader.channel_mask) == 0)): transfer_framelist_data(pcmreader, sub.stdin.write) elif (pcmreader.channels <= 8): if (int(pcmreader.channel_mask) in ( 0x7, #FR, FC, FL 0x33, #FR, FL, BR, BL 0x37, #FR, FC, FL, BL, BR 0x3f, #FR, FC, FL, BL, BR, LFE 0x70f, #FL, FC, FR, SL, SR, BC, LFE 0x63f) #FL, FC, FR, SL, SR, BL, BR, LFE ): standard_channel_mask = ChannelMask(pcmreader.channel_mask) vorbis_channel_mask = VorbisChannelMask(standard_channel_mask) else: raise UnsupportedChannelMask() transfer_framelist_data( ReorderedPCMReader(pcmreader, [ standard_channel_mask.channels().index(channel) for channel in vorbis_channel_mask.channels() ]), sub.stdin.write) else: raise UnsupportedChannelMask() try: pcmreader.close() except DecodingError: raise EncodingError() sub.stdin.close() devnull.close() if (sub.wait() == 0): return VorbisAudio(filename) else: raise EncodingError(BIN['oggenc'])
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 from_pcm(cls, filename, pcmreader, compression=None): """Encodes a new file from PCM data. Takes a filename string, PCMReader object and optional compression level string. Encodes a new audio file from pcmreader's data at the given filename with the specified compression level and returns a new SpeexAudio object.""" import bisect if ((compression is None) or (compression not in cls.COMPRESSION_MODES)): compression = __default_quality__(cls.NAME) if ((pcmreader.bits_per_sample not in (8, 16)) or (pcmreader.channels > 2) or (pcmreader.sample_rate not in (8000, 16000, 32000, 44100))): pcmreader = PCMConverter( pcmreader, sample_rate=[8000, 8000, 16000, 32000, 44100][bisect.bisect( [8000, 16000, 32000, 44100], pcmreader.sample_rate)], channels=min(pcmreader.channels, 2), channel_mask=ChannelMask.from_channels( min(pcmreader.channels, 2)), bits_per_sample=min(pcmreader.bits_per_sample, 16)) BITS_PER_SAMPLE = {8: ['--8bit'], 16: ['--16bit']}[pcmreader.bits_per_sample] CHANNELS = {1: [], 2: ['--stereo']}[pcmreader.channels] devnull = file(os.devnull, "ab") sub = subprocess.Popen([BIN['speexenc'], '--quality', str(compression), '--rate', str(pcmreader.sample_rate), '--le'] + \ BITS_PER_SAMPLE + \ CHANNELS + \ ['-', filename], stdin=subprocess.PIPE, stderr=devnull, preexec_fn=ignore_sigint) try: transfer_framelist_data(pcmreader, sub.stdin.write) except (IOError, ValueError), err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise EncodingError(str(err))
def from_pcm(cls, filename, pcmreader, compression=None): """Encodes a new file from PCM data. Takes a filename string, PCMReader object and optional compression level string. Encodes a new audio file from pcmreader's data at the given filename with the specified compression level and returns a new MP2Audio object.""" import decimal import bisect if ((compression is None) or (compression not in cls.COMPRESSION_MODES)): compression = __default_quality__(cls.NAME) if ((pcmreader.channels > 2) or (pcmreader.sample_rate not in (32000, 48000, 44100)) or (pcmreader.bits_per_sample != 16)): pcmreader = PCMConverter( pcmreader, sample_rate=[32000, 32000, 44100, 48000][bisect.bisect( [32000, 44100, 48000], pcmreader.sample_rate)], channels=min(pcmreader.channels, 2), channel_mask=pcmreader.channel_mask, bits_per_sample=16) devnull = file(os.devnull, 'ab') sub = subprocess.Popen([BIN['twolame'], "--quiet", "-r", "-s", str(pcmreader.sample_rate), "--samplesize", str(pcmreader.bits_per_sample), "-N", str(pcmreader.channels), "-m", "a", "-b", compression, "-", filename], stdin=subprocess.PIPE, stdout=devnull, stderr=devnull, preexec_fn=ignore_sigint) try: transfer_framelist_data(pcmreader, sub.stdin.write) except (ValueError, IOError), err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise EncodingError(str(err))
def _md5_audio_data(audio_data): hasher = hashlib.md5() def update_md5(audio_data): hasher.update(audio_data) try: audiotools.transfer_framelist_data(audio_data, update_md5) except (IOError, ValueError) as e: logging.error('Failed to _md5_audio_data: %s', e.args[0]) return None else: return str(hasher.hexdigest())
def from_pcm(cls, filename, pcmreader, compression=None): import bisect if (compression not in cls.COMPRESSION_MODES): compression = cls.DEFAULT_COMPRESSION if ((pcmreader.bits_per_sample not in (8,16)) or (pcmreader.channels > 2) or (pcmreader.sample_rate not in (8000,16000,32000,44100))): pcmreader = PCMConverter( pcmreader, sample_rate=[8000,8000,16000,32000,44100][bisect.bisect( [8000,16000,32000,44100],pcmreader.sample_rate)], channels=min(pcmreader.channels,2), channel_mask=ChannelMask.from_channels(min(pcmreader.channels,2)), bits_per_sample=min(pcmreader.bits_per_sample,16)) BITS_PER_SAMPLE = {8:['--8bit'], 16:['--16bit']}[pcmreader.bits_per_sample] CHANNELS = {1:[],2:['--stereo']}[pcmreader.channels] devnull = file(os.devnull,"ab") sub = subprocess.Popen([BIN['speexenc'], '--quality',str(compression), '--rate',str(pcmreader.sample_rate), '--le'] + \ BITS_PER_SAMPLE + \ CHANNELS + \ ['-',filename], stdin=subprocess.PIPE, stderr=devnull, preexec_fn=ignore_sigint) transfer_framelist_data(pcmreader,sub.stdin.write) try: pcmreader.close() except DecodingError: raise EncodingError() sub.stdin.close() result = sub.wait() devnull.close() if (result == 0): return SpeexAudio(filename) else: raise EncodingError(BIN['speexenc'])
def from_pcm(cls, filename, pcmreader, compression="192"): import decimal,bisect if (compression not in cls.COMPRESSION_MODES): compression = cls.DEFAULT_COMPRESSION if ((pcmreader.channels > 2) or (pcmreader.sample_rate not in (32000,48000,44100)) or (pcmreader.bits_per_sample != 16)): pcmreader = PCMConverter( pcmreader, sample_rate=[32000,32000,44100,48000][bisect.bisect( [32000,44100,48000],pcmreader.sample_rate)], channels=min(pcmreader.channels,2), channel_mask=pcmreader.channel_mask, bits_per_sample=16) devnull = file(os.devnull,'ab') sub = subprocess.Popen([BIN['twolame'],"--quiet", "-r", "-s",str(pcmreader.sample_rate), "--samplesize",str(pcmreader.bits_per_sample), "-N",str(pcmreader.channels), "-m","a", "-b",compression, "-", filename], stdin=subprocess.PIPE, stdout=devnull, stderr=devnull, preexec_fn=ignore_sigint) transfer_framelist_data(pcmreader,sub.stdin.write) try: pcmreader.close() except DecodingError: raise EncodingError() sub.stdin.close() devnull.close() if (sub.wait() == 0): return MP2Audio(filename) else: raise EncodingError(BIN['twolame'])
def to_wave(self, wave_filename): if (not hasattr(self,"__format__")): self.__populate_metadata__() if (self.__format__ is WaveAudio): try: f = open(wave_filename,'wb') except IOError: raise EncodingError() for block in self.__blocks__: if (block is not None): f.write(block) else: transfer_framelist_data( audiotools.decoders.SHNDecoder(self.filename), f.write) else: WaveAudio.from_pcm(wave_filename,self.to_pcm())
def from_pcm(cls, filename, pcmreader, compression=None): """returns a PCMReader object containing the track's PCM data""" if (compression is None) or (compression not in cls.COMPRESSION_MODES): compression = __default_quality__(cls.NAME) devnull = file(os.devnull, "ab") sub = subprocess.Popen( [ BIN["oggenc"], "-Q", "-r", "-B", str(pcmreader.bits_per_sample), "-C", str(pcmreader.channels), "-R", str(pcmreader.sample_rate), "--raw-endianness", str(0), "-q", compression, "-o", filename, "-", ], stdin=subprocess.PIPE, stdout=devnull, stderr=devnull, preexec_fn=ignore_sigint, ) if (pcmreader.channels <= 2) or (int(pcmreader.channel_mask) == 0): try: transfer_framelist_data(pcmreader, sub.stdin.write) except (IOError, ValueError), err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise EncodingError(str(err)) except Exception, err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise err
try: self.__populate_metadata__() except IOError, msg: raise EncodingError(str(msg)) if (self.__format__ is WaveAudio): try: f = open(wave_filename, 'wb') except IOError, msg: raise EncodingError(str(msg)) for block in self.__blocks__: if (block is not None): f.write(block) else: try: transfer_framelist_data( audiotools.decoders.SHNDecoder(self.filename), f.write) except IOError, msg: raise EncodingError(str(msg)) else: WaveAudio.from_pcm(wave_filename, self.to_pcm()) @classmethod def from_wave(cls, filename, wave_filename, compression=None, block_size=256): """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
def from_pcm(cls, filename, pcmreader, compression=None, total_pcm_frames=None): """encodes a new file from PCM data takes a filename string, PCMReader object optional compression level string, and optional total_pcm_frames integer encodes a new audio file from pcmreader's data at the given filename with the specified compression level and returns a new AudioFile-compatible object specifying total_pcm_frames, when the number is known in advance, may allow the encoder to work more efficiently but is never required """ import bisect import os import subprocess from audiotools import __default_quality__ from audiotools import transfer_framelist_data from audiotools import EncodingError from audiotools import PCMConverter from audiotools import ChannelMask if ((compression is None) or (compression not in cls.COMPRESSION_MODES)): compression = __default_quality__(cls.NAME) if pcmreader.bits_per_sample not in (8, 16, 24): from audiotools import UnsupportedBitsPerSample raise UnsupportedBitsPerSample( filename, pcmreader.bits_per_sample) if total_pcm_frames is not None: from audiotools import CounterPCMReader counter_reader = CounterPCMReader(pcmreader) else: counter_reader = pcmreader pcmreader = PCMConverter( counter_reader, sample_rate=[8000, 8000, 16000, 32000][bisect.bisect( [8000, 16000, 32000], pcmreader.sample_rate)], channels=min(pcmreader.channels, 2), channel_mask=ChannelMask.from_channels( min(pcmreader.channels, 2)), bits_per_sample=min(pcmreader.bits_per_sample, 16)) BITS_PER_SAMPLE = {8: ['--8bit'], 16: ['--16bit']}[pcmreader.bits_per_sample] CHANNELS = {1: [], 2: ['--stereo']}[pcmreader.channels] sub = subprocess.Popen( [BIN['speexenc'], '--quality', str(compression), '--rate', str(pcmreader.sample_rate), '--le'] + \ BITS_PER_SAMPLE + \ CHANNELS + \ ['-', filename], stdin=subprocess.PIPE, stderr=subprocess.DEVNULL if hasattr(subprocess, "DEVNULL") else open(os.devnull, "wb")) try: transfer_framelist_data(pcmreader, sub.stdin.write) except (IOError, ValueError) as err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise EncodingError(str(err)) except Exception as err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise err sub.stdin.close() if sub.wait() == 0: if ((total_pcm_frames is None) or (total_pcm_frames == counter_reader.frames_written)): return SpeexAudio(filename) else: from audiotools.text import ERR_TOTAL_PCM_FRAMES_MISMATCH cls.__unlink__(filename) raise EncodingError(ERR_TOTAL_PCM_FRAMES_MISMATCH) else: raise EncodingError(u"unable to encode file with speexenc")
def from_pcm(cls, filename, pcmreader, compression=None, total_pcm_frames=None): """encodes a new file from PCM data takes a filename string, PCMReader object optional compression level string, and optional total_pcm_frames integer encodes a new audio file from pcmreader's data at the given filename with the specified compression level and returns a new AudioFile-compatible object specifying total_pcm_frames, when the number is known in advance, may allow the encoder to work more efficiently but is never required """ import bisect import os import subprocess from audiotools import __default_quality__ from audiotools import transfer_framelist_data from audiotools import EncodingError from audiotools import PCMConverter from audiotools import ChannelMask if ((compression is None) or (compression not in cls.COMPRESSION_MODES)): compression = __default_quality__(cls.NAME) if pcmreader.bits_per_sample not in (8, 16, 24): from audiotools import UnsupportedBitsPerSample raise UnsupportedBitsPerSample(filename, pcmreader.bits_per_sample) if total_pcm_frames is not None: from audiotools import CounterPCMReader counter_reader = CounterPCMReader(pcmreader) else: counter_reader = pcmreader pcmreader = PCMConverter( counter_reader, sample_rate=[8000, 8000, 16000, 32000][bisect.bisect([8000, 16000, 32000], pcmreader.sample_rate)], channels=min(pcmreader.channels, 2), channel_mask=ChannelMask.from_channels(min(pcmreader.channels, 2)), bits_per_sample=min(pcmreader.bits_per_sample, 16)) BITS_PER_SAMPLE = { 8: ['--8bit'], 16: ['--16bit'] }[pcmreader.bits_per_sample] CHANNELS = {1: [], 2: ['--stereo']}[pcmreader.channels] sub = subprocess.Popen( [BIN['speexenc'], '--quality', str(compression), '--rate', str(pcmreader.sample_rate), '--le'] + \ BITS_PER_SAMPLE + \ CHANNELS + \ ['-', filename], stdin=subprocess.PIPE, stderr=subprocess.DEVNULL if hasattr(subprocess, "DEVNULL") else open(os.devnull, "wb")) try: transfer_framelist_data(pcmreader, sub.stdin.write) except (IOError, ValueError) as err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise EncodingError(str(err)) except Exception as err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise err sub.stdin.close() if sub.wait() == 0: if ((total_pcm_frames is None) or (total_pcm_frames == counter_reader.frames_written)): return SpeexAudio(filename) else: from audiotools.text import ERR_TOTAL_PCM_FRAMES_MISMATCH cls.__unlink__(filename) raise EncodingError(ERR_TOTAL_PCM_FRAMES_MISMATCH) else: raise EncodingError(u"unable to encode file with speexenc")
def from_pcm(cls, filename, pcmreader, compression=None, total_pcm_frames=None): """encodes a new file from PCM data takes a filename string, PCMReader object, optional compression level string and optional total_pcm_frames integer encodes a new audio file from pcmreader's data at the given filename with the specified compression level and returns a new AuAudio object""" from audiotools import EncodingError from audiotools import DecodingError from audiotools import CounterPCMReader from audiotools import transfer_framelist_data if (pcmreader.bits_per_sample not in (8, 16, 24)): from audiotools import Filename from audiotools import UnsupportedBitsPerSample from audiotools.text import ERR_UNSUPPORTED_BITS_PER_SAMPLE raise UnsupportedBitsPerSample( ERR_UNSUPPORTED_BITS_PER_SAMPLE % { "target_filename": Filename(filename), "bps": pcmreader.bits_per_sample }) try: header = au_header( pcmreader.sample_rate, pcmreader.channels, pcmreader.bits_per_sample, total_pcm_frames if total_pcm_frames is not None else 0) except ValueError as err: raise EncodingError(str(err)) try: f = open(filename, "wb") except IOError as err: raise EncodingError(str(err)) counter = CounterPCMReader(pcmreader) f.write(header) try: transfer_framelist_data(counter, f.write, True, True) except (IOError, ValueError) as err: cls.__unlink__(filename) raise EncodingError(str(err)) if (total_pcm_frames is not None): if (total_pcm_frames != counter.frames_written): # ensure written number of PCM frames # matches total_pcm_frames argument from audiotools.text import ERR_TOTAL_PCM_FRAMES_MISMATCH cls.__unlink__(filename) raise EncodingError(ERR_TOTAL_PCM_FRAMES_MISMATCH) else: f.close() else: # go back and rewrite populated header # with counted number of PCM frames f.seek(0, 0) f.write( au_header(pcmreader.sample_rate, pcmreader.channels, pcmreader.bits_per_sample, counter.frames_written)) f.close() return AuAudio(filename)
0x37, # FR, FC, FL, BL, BR 0x3F, # FR, FC, FL, BL, BR, LFE 0x70F, # FL, FC, FR, SL, SR, BC, LFE 0x63F, ): # FL, FC, FR, SL, SR, BL, BR, LFE standard_channel_mask = ChannelMask(pcmreader.channel_mask) vorbis_channel_mask = VorbisChannelMask(standard_channel_mask) else: raise UnsupportedChannelMask(filename, int(pcmreader.channel_mask)) try: transfer_framelist_data( ReorderedPCMReader( pcmreader, [standard_channel_mask.channels().index(channel) for channel in vorbis_channel_mask.channels()], ), sub.stdin.write, ) except (IOError, ValueError), err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise EncodingError(str(err)) except Exception, err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise err else:
def from_pcm(cls, filename, pcmreader, compression=None, total_pcm_frames=None): """encodes a new file from PCM data takes a filename string, PCMReader object, optional compression level string and optional total_pcm_frames integer encodes a new audio file from pcmreader's data at the given filename with the specified compression level and returns a new M4AAudio object""" import subprocess import os from audiotools import PCMConverter from audiotools import transfer_data from audiotools import transfer_framelist_data from audiotools import ignore_sigint from audiotools import EncodingError from audiotools import DecodingError from audiotools import ChannelMask from audiotools import __default_quality__ if ((compression is None) or (compression not in cls.COMPRESSION_MODES)): compression = __default_quality__(cls.NAME) if pcmreader.bits_per_sample not in {8, 16, 24}: from audiotools import UnsupportedBitsPerSample pcmreader.close() raise UnsupportedBitsPerSample(filename, pcmreader.bits_per_sample) if pcmreader.channels > 2: pcmreader = PCMConverter(pcmreader, sample_rate=pcmreader.sample_rate, channels=2, channel_mask=ChannelMask.from_channels(2), bits_per_sample=pcmreader.bits_per_sample) # faac requires files to end with .m4a for some reason if not filename.endswith(".m4a"): import tempfile actual_filename = filename tempfile = tempfile.NamedTemporaryFile(suffix=".m4a") filename = tempfile.name else: actual_filename = tempfile = None sub = subprocess.Popen( [BIN['faac'], "-q", compression, "-P", "-R", str(pcmreader.sample_rate), "-B", str(pcmreader.bits_per_sample), "-C", str(pcmreader.channels), "-X", "-o", filename, "-"], stdin=subprocess.PIPE, stderr=subprocess.DEVNULL if hasattr(subprocess, "DEVNULL") else open(os.devnull, "wb"), stdout=subprocess.DEVNULL if hasattr(subprocess, "DEVNULL") else open(os.devnull, "wb"), preexec_fn=ignore_sigint) # Note: faac handles SIGINT on its own, # so trying to ignore it doesn't work like on most other encoders. try: if total_pcm_frames is not None: from audiotools import CounterPCMReader pcmreader = CounterPCMReader(pcmreader) transfer_framelist_data(pcmreader, sub.stdin.write) if ((total_pcm_frames is not None) and (total_pcm_frames != pcmreader.frames_written)): from audiotools.text import ERR_TOTAL_PCM_FRAMES_MISMATCH raise EncodingError(ERR_TOTAL_PCM_FRAMES_MISMATCH) except (ValueError, IOError) as err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise EncodingError(str(err)) except Exception: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise sub.stdin.close() if sub.wait() == 0: if tempfile is not None: filename = actual_filename f = open(filename, 'wb') tempfile.seek(0, 0) transfer_data(tempfile.read, f.write) f.close() tempfile.close() return M4AAudio(filename) else: if tempfile is not None: tempfile.close() raise EncodingError(u"unable to write file with faac")
def from_pcm(cls, filename, pcmreader, compression=None): """Encodes a new file from PCM data. Takes a filename string, PCMReader object and optional compression level string. Encodes a new audio file from pcmreader's data at the given filename with the specified compression level and returns a new MP3Audio object.""" import decimal import bisect if ((compression is None) or (compression not in cls.COMPRESSION_MODES)): compression = __default_quality__(cls.NAME) if ((pcmreader.channels > 2) or (pcmreader.sample_rate not in (32000, 48000, 44100))): pcmreader = PCMConverter( pcmreader, sample_rate=[32000, 32000, 44100, 48000][bisect.bisect( [32000, 44100, 48000], pcmreader.sample_rate)], channels=min(pcmreader.channels, 2), channel_mask=ChannelMask.from_channels( min(pcmreader.channels, 2)), bits_per_sample=16) if (pcmreader.channels > 1): mode = "j" else: mode = "m" #FIXME - not sure if all LAME versions support "--little-endian" # #LAME 3.98 (and up, presumably) handle the byteswap correctly # #LAME 3.97 always uses -x # if (BIG_ENDIAN or (cls.__lame_version__() < (3,98))): # endian = ['-x'] # else: # endian = [] devnull = file(os.devnull, 'ab') sub = subprocess.Popen([ BIN['lame'], "--quiet", "-r", "-s", str(decimal.Decimal(pcmreader.sample_rate) / 1000), "--bitwidth", str(pcmreader.bits_per_sample), "--signed", "--little-endian", "-m", mode, "-V" + str(compression), "-", filename], stdin=subprocess.PIPE, stdout=devnull, stderr=devnull, preexec_fn=ignore_sigint) try: transfer_framelist_data(pcmreader, sub.stdin.write) except (IOError, ValueError), err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise EncodingError(str(err))
def from_pcm(cls, filename, pcmreader, compression=None, total_pcm_frames=None): """encodes a new file from PCM data takes a filename string, PCMReader object, optional compression level string and optional total_pcm_frames integer encodes a new audio file from pcmreader's data at the given filename with the specified compression level and returns a new AiffAudio object""" from audiotools import EncodingError from audiotools import DecodingError from audiotools import CounterPCMReader from audiotools import transfer_framelist_data try: header = aiff_header(pcmreader.sample_rate, pcmreader.channels, pcmreader.bits_per_sample, total_pcm_frames if total_pcm_frames is not None else 0) except ValueError as err: raise EncodingError(str(err)) try: f = open(filename, "wb") except IOError as msg: raise EncodingError(str(msg)) counter = CounterPCMReader(pcmreader) f.write(header) try: transfer_framelist_data(counter, f.write, True, True) except (IOError, ValueError) as err: cls.__unlink__(filename) raise EncodingError(str(err)) # handle odd-sized SSND chunks if (counter.frames_written % 2): f.write(chr(0)) if (total_pcm_frames is not None): if (total_pcm_frames != counter.frames_written): # ensure written number of PCM frames # matches total_pcm_frames argument from audiotools.text import ERR_TOTAL_PCM_FRAMES_MISMATCH cls.__unlink__(filename) raise EncodingError(ERR_TOTAL_PCM_FRAMES_MISMATCH) else: f.close() else: # go back and rewrite populated header # with counted number of PCM frames f.seek(0, 0) f.write(aiff_header(pcmreader.sample_rate, pcmreader.channels, pcmreader.bits_per_sample, counter.frames_written)) f.close() return AiffAudio(filename)
def from_pcm(cls, filename, pcmreader, compression=None, total_pcm_frames=None): """encodes a new file from PCM data takes a filename string, PCMReader object, optional compression level string and optional total_pcm_frames integer encodes a new audio file from pcmreader's data at the given filename with the specified compression level and returns a new AiffAudio object""" from audiotools import EncodingError from audiotools import DecodingError from audiotools import CounterPCMReader from audiotools import transfer_framelist_data try: header = aiff_header( pcmreader.sample_rate, pcmreader.channels, pcmreader.bits_per_sample, total_pcm_frames if total_pcm_frames is not None else 0) except ValueError as err: raise EncodingError(str(err)) try: f = open(filename, "wb") except IOError as msg: raise EncodingError(str(msg)) counter = CounterPCMReader(pcmreader) f.write(header) try: transfer_framelist_data(counter, f.write, True, True) except (IOError, ValueError) as err: cls.__unlink__(filename) raise EncodingError(str(err)) # handle odd-sized SSND chunks if (counter.frames_written % 2): f.write(chr(0)) if (total_pcm_frames is not None): if (total_pcm_frames != counter.frames_written): # ensure written number of PCM frames # matches total_pcm_frames argument from audiotools.text import ERR_TOTAL_PCM_FRAMES_MISMATCH cls.__unlink__(filename) raise EncodingError(ERR_TOTAL_PCM_FRAMES_MISMATCH) else: f.close() else: # go back and rewrite populated header # with counted number of PCM frames f.seek(0, 0) f.write( aiff_header(pcmreader.sample_rate, pcmreader.channels, pcmreader.bits_per_sample, counter.frames_written)) f.close() return AiffAudio(filename)
"""Writes the contents of this file to the given .wav filename string. Raises EncodingError if some error occurs during decoding.""" from . import decoders try: f = open(wave_filename, 'wb') except IOError, msg: raise EncodingError(str(msg)) (head, tail) = self.pcm_split() try: f.write(head) transfer_framelist_data(decoders.WavPackDecoder(self.filename), f.write) f.write(tail) f.close() except IOError, msg: self.__unlink__(wave_filename) raise EncodingError(str(msg)) def to_pcm(self): """Returns a PCMReader object containing the track's PCM data.""" from . import decoders try: return decoders.WavPackDecoder(self.filename) except (IOError, ValueError), msg: return PCMReaderError(error_message=str(msg),
# Example showing use of python audio tools library # to grab all the pcm data and shove it through md5 # obtaining an md5 of just the audio data import sys import hashlib import audiotools def update_md5(data): md5er.update(data) # open input file from argument 1 pcm_data = audiotools.open(sys.argv[1]).to_pcm() # init an md5 obj md5er = hashlib.md5() # pass all the raw pcm audio data to the update_md5() func audiotools.transfer_framelist_data(pcm_data, update_md5) pcm_data.close() print(str(md5er.hexdigest()))
def from_pcm(cls, filename, pcmreader, compression=None): """Encodes a new file from PCM data. Takes a filename string, PCMReader object and optional compression level string. Encodes a new audio file from pcmreader'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) if pcmreader.channels > 2: pcmreader = PCMConverter( pcmreader, sample_rate=pcmreader.sample_rate, channels=2, channel_mask=ChannelMask.from_channels(2), bits_per_sample=pcmreader.bits_per_sample, ) # faac requires files to end with .m4a for some reason if not filename.endswith(".m4a"): import tempfile actual_filename = filename tempfile = tempfile.NamedTemporaryFile(suffix=".m4a") filename = tempfile.name else: actual_filename = tempfile = None devnull = file(os.devnull, "ab") sub = subprocess.Popen( [ BIN["faac"], "-q", compression, "-P", "-R", str(pcmreader.sample_rate), "-B", str(pcmreader.bits_per_sample), "-C", str(pcmreader.channels), "-X", "-o", filename, "-", ], stdin=subprocess.PIPE, stderr=devnull, stdout=devnull, preexec_fn=ignore_sigint, ) # Note: faac handles SIGINT on its own, # so trying to ignore it doesn't work like on most other encoders. try: transfer_framelist_data(pcmreader, sub.stdin.write) except (ValueError, IOError), err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise EncodingError(str(err))
def from_pcm(cls, filename, pcmreader, compression=None, total_pcm_frames=None): """encodes a new file from PCM data takes a filename string, PCMReader object, optional compression level string and optional total_pcm_frames integer encodes a new audio file from pcmreader's data at the given filename with the specified compression level and returns a new WaveAudio object""" from audiotools import EncodingError from audiotools import DecodingError from audiotools import CounterPCMReader from audiotools import transfer_framelist_data if pcmreader.bits_per_sample not in {8, 16, 24}: from audiotools import UnsupportedBitsPerSample pcmreader.close() raise UnsupportedBitsPerSample(filename, pcmreader.bits_per_sample) try: header = wave_header(pcmreader.sample_rate, pcmreader.channels, pcmreader.channel_mask, pcmreader.bits_per_sample, total_pcm_frames if total_pcm_frames is not None else 0) except ValueError as err: pcmreader.close() raise EncodingError(str(err)) try: f = open(filename, "wb") except IOError as err: pcmreader.close() raise EncodingError(str(err)) counter = CounterPCMReader(pcmreader) f.write(header) try: transfer_framelist_data(counter, f.write, pcmreader.bits_per_sample > 8, False) except (IOError, ValueError) as err: f.close() cls.__unlink__(filename) raise EncodingError(str(err)) except Exception as err: f.close() cls.__unlink__(filename) raise err # handle odd-sized "data" chunks if counter.frames_written % 2: f.write(b"\x00") if total_pcm_frames is not None: f.close() if total_pcm_frames != counter.frames_written: # ensure written number of PCM frames # matches total_pcm_frames argument from audiotools.text import ERR_TOTAL_PCM_FRAMES_MISMATCH cls.__unlink__(filename) raise EncodingError(ERR_TOTAL_PCM_FRAMES_MISMATCH) else: # go back and rewrite populated header # with counted number of PCM frames f.seek(0, 0) f.write(wave_header(pcmreader.sample_rate, pcmreader.channels, pcmreader.channel_mask, pcmreader.bits_per_sample, counter.frames_written)) f.close() return WaveAudio(filename)
def from_pcm(cls, filename, pcmreader, compression=None): compression_param = { "fast": ["-f"], "standard": [], "high": ["-h"], "veryhigh": ["-hh"] } if (str(compression) not in cls.COMPRESSION_MODES): compression = cls.DEFAULT_COMPRESSION if ('--raw-pcm' in cls.__wavpack_help__()): if (filename.endswith(".wv")): devnull = file(os.devnull, 'ab') if (pcmreader.channels > 18): raise UnsupportedChannelMask() elif (pcmreader.channels > 2): order_map = { "front_left": "FL", "front_right": "FR", "front_center": "FC", "low_frequency": "LFE", "back_left": "BL", "back_right": "BR", "front_left_of_center": "FLC", "front_right_of_center": "FRC", "back_center": "BC", "side_left": "SL", "side_right": "SR", "top_center": "TC", "top_front_left": "TFL", "top_front_center": "TFC", "top_front_right": "TFR", "top_back_left": "TBL", "top_back_center": "TBC", "top_back_right": "TBR" } channel_order = [ "--channel-order=%s" % (",".join([ order_map[channel] for channel in ChannelMask( pcmreader.channel_mask).channels() ])) ] else: channel_order = [] sub = subprocess.Popen([BIN['wavpack']] + \ compression_param[compression] + \ ['-q','-y', "--raw-pcm=%(sr)s,%(bps)s,%(ch)s"%\ {"sr":pcmreader.sample_rate, "bps":pcmreader.bits_per_sample, "ch":pcmreader.channels}] + \ channel_order + \ ['-','-o',filename], stdout=devnull, stderr=devnull, stdin=subprocess.PIPE, preexec_fn=ignore_sigint) transfer_framelist_data(pcmreader, sub.stdin.write) devnull.close() sub.stdin.close() if (sub.wait() == 0): return WavPackAudio(filename) else: raise EncodingError(BIN['wavpack']) else: import tempfile tempdir = tempfile.mkdtemp() symlink = os.path.join(tempdir, os.path.basename(filename) + ".wv") try: os.symlink(os.path.abspath(filename), symlink) cls.from_pcm(symlink, pcmreader, compression) return WavPackAudio(filename) finally: os.unlink(symlink) os.rmdir(tempdir) else: import tempfile f = tempfile.NamedTemporaryFile(suffix=".wav") w = WaveAudio.from_pcm(f.name, pcmreader) try: return cls.from_wave(filename, w.filename, compression) finally: del (w) f.close()
def from_pcm(cls, filename, pcmreader, compression=None, total_pcm_frames=None): """encodes a new file from PCM data takes a filename string, PCMReader object, optional compression level string and optional total_pcm_frames integer encodes a new audio file from pcmreader's data at the given filename with the specified compression level and returns a new M4AAudio object""" import subprocess import os from audiotools import PCMConverter from audiotools import transfer_data from audiotools import transfer_framelist_data from audiotools import ignore_sigint from audiotools import EncodingError from audiotools import DecodingError from audiotools import ChannelMask from audiotools import __default_quality__ if ((compression is None) or (compression not in cls.COMPRESSION_MODES)): compression = __default_quality__(cls.NAME) if pcmreader.channels > 2: pcmreader = PCMConverter(pcmreader, sample_rate=pcmreader.sample_rate, channels=2, channel_mask=ChannelMask.from_channels(2), bits_per_sample=pcmreader.bits_per_sample) # faac requires files to end with .m4a for some reason if not filename.endswith(".m4a"): import tempfile actual_filename = filename tempfile = tempfile.NamedTemporaryFile(suffix=".m4a") filename = tempfile.name else: actual_filename = tempfile = None sub = subprocess.Popen( [ BIN['faac'], "-q", compression, "-P", "-R", str(pcmreader.sample_rate), "-B", str(pcmreader.bits_per_sample), "-C", str(pcmreader.channels), "-X", "-o", filename, "-" ], stdin=subprocess.PIPE, stderr=subprocess.DEVNULL if hasattr(subprocess, "DEVNULL") else open(os.devnull, "wb"), stdout=subprocess.DEVNULL if hasattr(subprocess, "DEVNULL") else open(os.devnull, "wb"), preexec_fn=ignore_sigint) # Note: faac handles SIGINT on its own, # so trying to ignore it doesn't work like on most other encoders. try: if total_pcm_frames is not None: from audiotools import CounterPCMReader pcmreader = CounterPCMReader(pcmreader) transfer_framelist_data(pcmreader, sub.stdin.write) if ((total_pcm_frames is not None) and (total_pcm_frames != pcmreader.frames_written)): from audiotools.text import ERR_TOTAL_PCM_FRAMES_MISMATCH raise EncodingError(ERR_TOTAL_PCM_FRAMES_MISMATCH) except (ValueError, IOError) as err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise EncodingError(str(err)) except Exception: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise sub.stdin.close() if sub.wait() == 0: if tempfile is not None: filename = actual_filename f = open(filename, 'wb') tempfile.seek(0, 0) transfer_data(tempfile.read, f.write) f.close() tempfile.close() return M4AAudio(filename) else: if tempfile is not None: tempfile.close() raise EncodingError(u"unable to write file with faac")
0x7, # FR, FC, FL 0x33, # FR, FL, BR, BL 0x37, # FR, FC, FL, BL, BR 0x3f, # FR, FC, FL, BL, BR, LFE 0x70f, # FL, FC, FR, SL, SR, BC, LFE 0x63f)): # FL, FC, FR, SL, SR, BL, BR, LFE standard_channel_mask = ChannelMask(pcmreader.channel_mask) vorbis_channel_mask = VorbisChannelMask(standard_channel_mask) else: raise UnsupportedChannelMask() try: transfer_framelist_data( ReorderedPCMReader(pcmreader, [ standard_channel_mask.channels().index(channel) for channel in vorbis_channel_mask.channels() ]), sub.stdin.write) except (IOError, ValueError), err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise EncodingError(str(err)) except Exception, err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise err else: raise UnsupportedChannelMask()
def from_pcm(cls, filename, pcmreader, compression=None, total_pcm_frames=None): """encodes a new file from PCM data takes a filename string, PCMReader object, optional compression level string and optional total_pcm_frames integer encodes a new audio file from pcmreader's data at the given filename with the specified compression level and returns a new AuAudio object""" from audiotools import EncodingError from audiotools import DecodingError from audiotools import CounterPCMReader from audiotools import transfer_framelist_data if pcmreader.bits_per_sample not in (8, 16, 24): from audiotools import Filename from audiotools import UnsupportedBitsPerSample from audiotools.text import ERR_UNSUPPORTED_BITS_PER_SAMPLE pcmreader.close() raise UnsupportedBitsPerSample( ERR_UNSUPPORTED_BITS_PER_SAMPLE % {"target_filename": Filename(filename), "bps": pcmreader.bits_per_sample}) try: header = au_header(pcmreader.sample_rate, pcmreader.channels, pcmreader.bits_per_sample, total_pcm_frames if total_pcm_frames is not None else 0) except ValueError as err: raise EncodingError(str(err)) try: f = open(filename, "wb") except IOError as err: pcmreader.close() raise EncodingError(str(err)) counter = CounterPCMReader(pcmreader) f.write(header) try: transfer_framelist_data(counter, f.write, True, True) except (IOError, ValueError) as err: f.close() cls.__unlink__(filename) raise EncodingError(str(err)) if total_pcm_frames is not None: f.close() if total_pcm_frames != counter.frames_written: # ensure written number of PCM frames # matches total_pcm_frames argument from audiotools.text import ERR_TOTAL_PCM_FRAMES_MISMATCH cls.__unlink__(filename) raise EncodingError(ERR_TOTAL_PCM_FRAMES_MISMATCH) else: # go back and rewrite populated header # with counted number of PCM frames f.seek(0, 0) f.write(au_header(pcmreader.sample_rate, pcmreader.channels, pcmreader.bits_per_sample, counter.frames_written)) f.close() return AuAudio(filename)
def from_pcm(cls, filename, pcmreader, compression=None): """Encodes a new file from PCM data. Takes a filename string, PCMReader object and optional compression level string. Encodes a new audio file from pcmreader's data at the given filename with the specified compression level and returns a new MP3Audio object.""" import decimal import bisect if ((compression is None) or (compression not in cls.COMPRESSION_MODES)): compression = __default_quality__(cls.NAME) if ((pcmreader.channels > 2) or (pcmreader.sample_rate not in (32000, 48000, 44100))): pcmreader = PCMConverter( pcmreader, sample_rate=[32000, 32000, 44100, 48000][bisect.bisect( [32000, 44100, 48000], pcmreader.sample_rate)], channels=min(pcmreader.channels, 2), channel_mask=ChannelMask.from_channels( min(pcmreader.channels, 2)), bits_per_sample=16) if (pcmreader.channels > 1): mode = "j" else: mode = "m" #FIXME - not sure if all LAME versions support "--little-endian" # #LAME 3.98 (and up, presumably) handle the byteswap correctly # #LAME 3.97 always uses -x # if (BIG_ENDIAN or (cls.__lame_version__() < (3,98))): # endian = ['-x'] # else: # endian = [] devnull = file(os.devnull, 'ab') if (str(compression) in map(str, range(0, 10))): compression = ["-V" + str(compression)] else: compression = ["--preset", str(compression)] sub = subprocess.Popen([ BIN['lame'], "--quiet", "-r", "-s", str(decimal.Decimal(pcmreader.sample_rate) / 1000), "--bitwidth", str(pcmreader.bits_per_sample), "--signed", "--little-endian", "-m", mode] + compression + ["-", filename], stdin=subprocess.PIPE, stdout=devnull, stderr=devnull, preexec_fn=ignore_sigint) try: transfer_framelist_data(pcmreader, sub.stdin.write) except (IOError, ValueError), err: sub.stdin.close() sub.wait() cls.__unlink__(filename) raise EncodingError(str(err))