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, 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 MP2Audio object""" from audiotools import (PCMConverter, BufferedPCMReader, ChannelMask, __default_quality__, EncodingError) from audiotools.encoders import encode_mp2 import bisect if (((compression is None) or (compression not in cls.COMPRESSION_MODES))): compression = __default_quality__(cls.NAME) if pcmreader.sample_rate in (32000, 48000, 44100): sample_rate = pcmreader.sample_rate else: sample_rate = [32000, 32000, 44100, 48000][bisect.bisect([32000, 44100, 48000], pcmreader.sample_rate)] if total_pcm_frames is not None: from audiotools import CounterPCMReader pcmreader = CounterPCMReader(pcmreader) try: encode_mp2(filename, PCMConverter(pcmreader, sample_rate=sample_rate, channels=min(pcmreader.channels, 2), channel_mask=ChannelMask.from_channels( min(pcmreader.channels, 2)), bits_per_sample=16), int(compression)) if ((total_pcm_frames is not None) and (total_pcm_frames != pcmreader.frames_written)): from audiotools.text import ERR_TOTAL_PCM_FRAMES_MISMATCH cls.__unlink__(filename) raise EncodingError(ERR_TOTAL_PCM_FRAMES_MISMATCH) return MP2Audio(filename) except (ValueError, IOError) as err: cls.__unlink__(filename) raise EncodingError(str(err)) finally: pcmreader.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 VorbisAudio object""" from audiotools import (BufferedPCMReader, __default_quality__, EncodingError) from audiotools.encoders import encode_vorbis 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) and (pcmreader.channels <= 8): channel_mask = int(pcmreader.channel_mask) if ((channel_mask != 0) and (channel_mask not 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 from audiotools import UnsupportedChannelMask pcmreader.close() raise UnsupportedChannelMask(filename, channel_mask) if total_pcm_frames is not None: from audiotools import CounterPCMReader pcmreader = CounterPCMReader(pcmreader) try: encode_vorbis(filename, pcmreader, float(compression) / 10) if ((total_pcm_frames is not None) and (total_pcm_frames != pcmreader.frames_written)): from audiotools.text import ERR_TOTAL_PCM_FRAMES_MISMATCH cls.__unlink__(filename) raise EncodingError(ERR_TOTAL_PCM_FRAMES_MISMATCH) return VorbisAudio(filename) except (ValueError, IOError) as err: cls.__unlink__(filename) raise EncodingError(str(err)) finally: pcmreader.close()
def from_pcm(cls, filename, pcmreader, compression=None, total_pcm_frames=None, encoding_function=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 WavPackAudio object""" from audiotools.encoders import encode_wavpack from audiotools import BufferedPCMReader from audiotools import CounterPCMReader from audiotools import EncodingError from audiotools import __default_quality__ if pcmreader.bits_per_sample not in (8, 16, 24): # WavPack technically supports up to 32 bits-per-sample # but nothing else does # so I'll treat it as unsupported for now from audiotools import UnsupportedBitsPerSample pcmreader.close() raise UnsupportedBitsPerSample(filename, pcmreader.bits_per_sample) if (((compression is None) or (compression not in cls.COMPRESSION_MODES))): compression = __default_quality__(cls.NAME) counter = CounterPCMReader(pcmreader) try: (encode_wavpack if encoding_function is None else encoding_function)( filename=filename, pcmreader=counter, total_pcm_frames=(total_pcm_frames if total_pcm_frames is not None else 0), compression=compression) counter.close() except (ValueError, IOError) as msg: counter.close() cls.__unlink__(filename) raise EncodingError(str(msg)) except Exception: counter.close() cls.__unlink__(filename) raise # ensure actual total PCM frames matches argument, if any if (((total_pcm_frames is not None) and (counter.frames_written != total_pcm_frames))): cls.__unlink__(filename) from audiotools.text import ERR_TOTAL_PCM_FRAMES_MISMATCH raise EncodingError(ERR_TOTAL_PCM_FRAMES_MISMATCH) return cls(filename)
def from_pcm(cls, filename, pcmreader, compression=None, total_pcm_frames=None, encoding_function=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 may raise EncodingError if some problem occurs when encoding the input file. This includes an error in the input stream, a problem writing the output file, or even an EncodingError subclass such as "UnsupportedBitsPerSample" if the input stream is formatted in a way this class is unable to support """ from audiotools import (BufferedPCMReader, CounterPCMReader, transfer_data, EncodingError) # from audiotools.py_encoders import encode_tta from audiotools.encoders import encode_tta from audiotools.bitstream import BitstreamWriter if pcmreader.bits_per_sample not in {8, 16, 24}: from audiotools import UnsupportedBitsPerSample pcmreader.close() raise UnsupportedBitsPerSample(filename, pcmreader.bits_per_sample) # open output file right away # so we can fail as soon as possible try: file = open(filename, "wb") except IOError as err: pcmreader.close() raise EncodingError(str(err)) try: encode_tta(file=file, pcmreader=pcmreader, total_pcm_frames=(total_pcm_frames if total_pcm_frames is not None else 0)) return cls(filename) except (IOError, ValueError) as err: cls.__unlink__(filename) raise EncodingError(str(err)) except: cls.__unlink__(filename) raise finally: file.close()
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 from_pcm(cls, filename, pcmreader, compression=None, total_pcm_frames=None, encoding_function=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 WavPackAudio object""" from audiotools.encoders import encode_wavpack from audiotools import BufferedPCMReader from audiotools import CounterPCMReader from audiotools import EncodingError from audiotools import __default_quality__ if (((compression is None) or (compression not in cls.COMPRESSION_MODES))): compression = __default_quality__(cls.NAME) counter = CounterPCMReader(pcmreader) try: (encode_wavpack if encoding_function is None else encoding_function)( filename, BufferedPCMReader(counter), total_pcm_frames=(total_pcm_frames if total_pcm_frames is not None else 0), **cls.__options__[compression]) counter.close() except (ValueError, IOError) as msg: counter.close() cls.__unlink__(filename) raise EncodingError(str(msg)) except Exception: counter.close() cls.__unlink__(filename) raise # ensure actual total PCM frames matches argument, if any if (((total_pcm_frames is not None) and (counter.frames_written != total_pcm_frames))): cls.__unlink__(filename) from audiotools.text import ERR_TOTAL_PCM_FRAMES_MISMATCH raise EncodingError(ERR_TOTAL_PCM_FRAMES_MISMATCH) return cls(filename)
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=None): if (pcmreader.bits_per_sample not in (8, 16, 24)): raise InvalidFormat( _(u"Unsupported bits per sample %s") % (pcmreader.bits_per_sample)) bytes_per_sample = pcmreader.bits_per_sample / 8 header = construct.Container(magic_number='.snd', data_offset=0, data_size=0, encoding_format={ 8: 2, 16: 3, 24: 4 }[pcmreader.bits_per_sample], sample_rate=pcmreader.sample_rate, channels=pcmreader.channels) try: f = file(filename, 'wb') except IOError: raise EncodingError(None) try: #send out a dummy header f.write(AuAudio.AU_HEADER.build(header)) header.data_offset = f.tell() #send our big-endian PCM data #d will be a list of ints, so we can't use transfer_data framelist = pcmreader.read(BUFFER_SIZE) while (len(framelist) > 0): bytes = framelist.to_bytes(True, True) f.write(bytes) header.data_size += len(bytes) framelist = pcmreader.read(BUFFER_SIZE) #send out a complete header f.seek(0, 0) f.write(AuAudio.AU_HEADER.build(header)) finally: f.close() try: pcmreader.close() except DecodingError: raise EncodingError() return AuAudio(filename)
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 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 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() (head, tail) = wave.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=wave.to_pcm(), block_size=block_size, verbatim_chunks=blocks) return cls(filename) except IOError, err: cls.__unlink__(filename) raise EncodingError(str(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=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 AuAudio object.""" if (pcmreader.bits_per_sample not in (8, 16, 24)): raise InvalidFormat( _(u"Unsupported bits per sample %s") % (pcmreader.bits_per_sample)) bytes_per_sample = pcmreader.bits_per_sample / 8 header = Con.Container(magic_number='.snd', data_offset=0, data_size=0, encoding_format={ 8: 2, 16: 3, 24: 4 }[pcmreader.bits_per_sample], sample_rate=pcmreader.sample_rate, channels=pcmreader.channels) try: f = file(filename, 'wb') except IOError, err: raise EncodingError(str(err))
def from_wave(cls, filename, wave_filename, compression=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() #FIXME - check errors here try: encoders.encode_wavpack(filename, wave.to_pcm(), wave_header=head, wave_footer=tail, **cls.__options__[compression]) return cls(filename) except (ValueError, IOError), msg: cls.__unlink__(filename) raise EncodingError(str(msg))
def to_wave(self, wave_filename): devnull = file(os.devnull, 'ab') #WavPack stupidly refuses to run if the filename doesn't end with .wv if (self.filename.endswith(".wv")): sub = subprocess.Popen([ BIN['wvunpack'], '-q', '-y', self.filename, '-o', wave_filename ], stdout=devnull, stderr=devnull) if (sub.wait() != 0): raise EncodingError() else: #create a temporary symlink to the current file #rather than rewrite the whole thing import tempfile tempdir = tempfile.mkdtemp() symlink = os.path.join(tempdir, os.path.basename(self.filename) + ".wv") try: os.symlink(os.path.abspath(self.filename), symlink) WavPackAudio(symlink).to_wave(wave_filename) finally: os.unlink(symlink) os.rmdir(tempdir)
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 may raise EncodingError if some problem occurs when encoding the input file. This includes an error in the input stream, a problem writing the output file, or even an EncodingError subclass such as "UnsupportedBitsPerSample" if the input stream is formatted in a way this class is unable to support """ from audiotools import (BufferedPCMReader, PCMConverter, __default_quality__, EncodingError) from audiotools.encoders import encode_opus if (((compression is None) or (compression not in cls.COMPRESSION_MODES))): compression = __default_quality__(cls.NAME) if ((pcmreader.channels > 2) and (pcmreader.channels <= 8)): channel_mask = int(pcmreader.channel_mask) if ((channel_mask != 0) and (channel_mask not 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 raise UnsupportedChannelMask(filename, channel_mask) try: encode_opus(filename, BufferedPCMReader( PCMConverter(pcmreader, sample_rate=48000, channels=pcmreader.channels, channel_mask=pcmreader.channel_mask, bits_per_sample=16)), quality=int(compression), original_sample_rate=pcmreader.sample_rate) return cls(filename) except (ValueError, IOError), err: cls.__unlink__(filename) raise EncodingError(err)
def to_wave(self, wave_filename): """Writes the contents of this file to the given .wav filename string. Raises EncodingError if some error occurs during decoding.""" if (not hasattr(self, "__format__")): try: self.__populate_metadata__() except IOError, msg: raise EncodingError(str(msg))
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 to_wave(self, wave_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))
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 AiffAudio object.""" try: f = open(filename, 'wb') except IOError, msg: raise EncodingError(str(msg))
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 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_wave__(cls, filename, wave_filename, compression=None): if (str(compression) not in cls.COMPRESSION_MODES): compression = cls.DEFAULT_COMPRESSION #mppenc requires files to end with .mpc for some reason if (not filename.endswith(".mpc")): import tempfile actual_filename = filename tempfile = tempfile.NamedTemporaryFile(suffix=".mpc") filename = tempfile.name else: actual_filename = tempfile = None ###Musepack SV7### #sub = subprocess.Popen([BIN['mppenc'], # "--silent", # "--overwrite", # "--%s" % (compression), # wave_filename, # filename], # preexec_fn=ignore_sigint) ###Musepack SV8### sub = subprocess.Popen([BIN['mpcenc'], "--silent", "--overwrite", "--%s" % (compression), wave_filename, filename]) if (sub.wait() == 0): if (tempfile is not None): filename = actual_filename f = file(filename, 'wb') tempfile.seek(0, 0) transfer_data(tempfile.read, f.write) f.close() tempfile.close() return MusepackAudio(filename) else: if (tempfile is not None): tempfile.close() raise EncodingError(u"error encoding file with mpcenc")
def __from_wave__(cls, filename, wave_filename, compression): import subprocess import os from audiotools import EncodingError sub = subprocess.Popen( [ BIN["neroAacEnc"], "-q", compression, "-if", wave_filename, "-of", filename ], stdout=subprocess.DEVNULL if hasattr(subprocess, "DEVNULL") else open(os.devnull, "wb"), stderr=subprocess.DEVNULL if hasattr(subprocess, "DEVNULL") else open(os.devnull, "wb")) if sub.wait() != 0: raise EncodingError(u"neroAacEnc unable to write file") else: return cls(filename)
def from_wave(cls, filename, wave_filename, compression=None): if (str(compression) not in cls.COMPRESSION_MODES): compression = cls.DEFAULT_COMPRESSION compression_param = { "fast": ["-f"], "standard": [], "high": ["-h"], "veryhigh": ["-hh"] } #wavpack will add a .wv suffix if there isn't one #this isn't desired behavior if (filename.endswith(".wv")): devnull = file(os.devnull, 'ab') sub = subprocess.Popen([BIN['wavpack'], wave_filename] + \ compression_param[compression] + \ ['-q','-y','-o', filename], stdout=devnull, stderr=devnull, preexec_fn=ignore_sigint) devnull.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_wave(symlink, wave_filename, compression) return WavPackAudio(filename) finally: os.unlink(symlink) os.rmdir(tempdir)
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 VorbisAudio object""" from audiotools import (BufferedPCMReader, __default_quality__, EncodingError) from audiotools.encoders import encode_vorbis if (((compression is None) or (compression not in cls.COMPRESSION_MODES))): compression = __default_quality__(cls.NAME) if ((pcmreader.channels > 2) and (pcmreader.channels <= 8)): channel_mask = int(pcmreader.channel_mask) if ((channel_mask != 0) and (channel_mask not 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 raise UnsupportedChannelMask(filename, channel_mask) try: encode_vorbis(filename, BufferedPCMReader(pcmreader), float(compression) / 10) return VorbisAudio(filename) except (ValueError, IOError), err: cls.__unlink__(filename) raise EncodingError(str(err))
def from_wave(cls, filename, wave_filename, compression=None): wave = WaveAudio(wave_filename) if (wave.bits_per_sample() not in (8,16)): raise UnsupportedBitsPerSample() (head,tail) = wave.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=wave.to_pcm(), block_size=256, verbatim_chunks=blocks) return cls(filename) except IOError: raise EncodingError("shn")
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 WavPackAudio object.""" from . import encoders if ((compression is None) or (compression not in cls.COMPRESSION_MODES)): compression = __default_quality__(cls.NAME) try: encoders.encode_wavpack(filename, BufferedPCMReader(pcmreader), **cls.__options__[compression]) return cls(filename) except (ValueError, IOError), msg: cls.__unlink__(filename) raise EncodingError(str(msg))
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 MP3Audio object""" from audiotools import (PCMConverter, BufferedPCMReader, ChannelMask, __default_quality__, EncodingError) from audiotools.encoders import encode_mp3 if (((compression is None) or (compression not in cls.COMPRESSION_MODES))): compression = __default_quality__(cls.NAME) try: encode_mp3( filename, BufferedPCMReader( PCMConverter(pcmreader, sample_rate=pcmreader.sample_rate, channels=min(pcmreader.channels, 2), channel_mask=ChannelMask.from_channels( min(pcmreader.channels, 2)), bits_per_sample=16)), compression) return MP3Audio(filename) except (ValueError, IOError), err: cls.__unlink__(filename) raise EncodingError(str(err))
def from_wave(cls, filename, header, pcmreader, footer, compression=None, encoding_function=None): """encodes a new file from wave data takes a filename string, header string, PCMReader object, footer string 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 WaveAudio object header + pcm data + footer should always result in the original wave file being restored without need for any padding bytes may raise EncodingError if some problem occurs when encoding the input file""" from audiotools.encoders import encode_wavpack from audiotools import BufferedPCMReader from audiotools import CounterPCMReader from audiotools.wav import (validate_header, validate_footer) from audiotools import EncodingError from audiotools import __default_quality__ if (((compression is None) or (compression not in cls.COMPRESSION_MODES))): compression = __default_quality__(cls.NAME) # ensure header is valid try: (total_size, data_size) = validate_header(header) except ValueError as err: raise EncodingError(str(err)) counter = CounterPCMReader(pcmreader) try: (encode_wavpack if encoding_function is None else encoding_function)(filename, BufferedPCMReader(counter), wave_header=header, wave_footer=footer, **cls.__options__[compression]) counter.close() 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 EncodingError(ERR_WAV_TRUNCATED_DATA_CHUNK) # ensure footer validates correctly try: validate_footer(footer, data_bytes_written) except ValueError as err: raise EncodingError(str(err)) # ensure total size is correct if ((len(header) + data_size + len(footer)) != total_size): from audiotools.text import ERR_WAV_INVALID_SIZE raise EncodingError(ERR_WAV_INVALID_SIZE) return cls(filename) except (ValueError, IOError) as msg: counter.close() cls.__unlink__(filename) raise EncodingError(str(msg)) except Exception as err: counter.close() cls.__unlink__(filename) raise err