Ejemplo n.º 1
0
    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))
Ejemplo n.º 2
0
    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 tempfile
        import os
        import os.path
        from audiotools import PCMConverter
        from audiotools import WaveAudio
        from audiotools import __default_quality__

        if ((compression is None)
                or (compression not in cls.COMPRESSION_MODES)):
            compression = __default_quality__(cls.NAME)

        tempwavefile = tempfile.NamedTemporaryFile(suffix=".wav", delete=False)
        tempwave_name = tempwavefile.name
        try:
            if pcmreader.sample_rate > 96000:
                tempwave = WaveAudio.from_pcm(
                    tempwave_name,
                    PCMConverter(pcmreader,
                                 sample_rate=96000,
                                 channels=pcmreader.channels,
                                 channel_mask=pcmreader.channel_mask,
                                 bits_per_sample=pcmreader.bits_per_sample),
                    total_pcm_frames=total_pcm_frames)
            else:
                tempwave = WaveAudio.from_pcm(
                    tempwave_name,
                    pcmreader,
                    total_pcm_frames=total_pcm_frames)

            cls.__from_wave__(filename, tempwave.filename, compression)
            return cls(filename)
        finally:
            tempwavefile.close()
            if os.path.isfile(tempwave_name):
                os.unlink(tempwave_name)
Ejemplo n.º 3
0
 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())
Ejemplo n.º 4
0
    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 tempfile
        import os
        import os.path
        from audiotools import PCMConverter
        from audiotools import WaveAudio
        from audiotools import __default_quality__

        if ((compression is None) or (compression not in
                                      cls.COMPRESSION_MODES)):
            compression = __default_quality__(cls.NAME)

        tempwavefile = tempfile.NamedTemporaryFile(suffix=".wav", delete=False)
        tempwave_name = tempwavefile.name
        try:
            if pcmreader.sample_rate > 96000:
                tempwave = WaveAudio.from_pcm(
                    tempwave_name,
                    PCMConverter(pcmreader,
                                 sample_rate=96000,
                                 channels=pcmreader.channels,
                                 channel_mask=pcmreader.channel_mask,
                                 bits_per_sample=pcmreader.bits_per_sample),
                    total_pcm_frames=total_pcm_frames)
            else:
                tempwave = WaveAudio.from_pcm(
                    tempwave_name,
                    pcmreader,
                    total_pcm_frames=total_pcm_frames)

            cls.__from_wave__(filename, tempwave.filename, compression)
            return cls(filename)
        finally:
            tempwavefile.close()
            if os.path.isfile(tempwave_name):
                os.unlink(tempwave_name)
Ejemplo n.º 5
0
    def __populate_metadata__(self):
        #set up some default values
        self.__bits_per_sample__ = 16
        self.__channels__ = 2
        self.__channel_mask__ = 0x3
        self.__sample_rate__ = 44100
        self.__total_frames__ = 0
        self.__blocks__ = []
        self.__format__ = None

        #grab a few pieces of technical metadata from the Shorten file itself
        #which requires a dry-run through the decoder
        try:
            decoder = audiotools.decoders.SHNDecoder(self.filename)
            try:

                self.__bits_per_sample__ = decoder.bits_per_sample
                self.__channels__ = decoder.channels
                (self.__total_frames__,
                 self.__blocks__) = decoder.metadata()
            finally:
                decoder.close()

            try:
                self.__channel_mask__ = ChannelMask.from_channels(
                    self.__channels__)
            except ValueError:
                self.__channel_mask__ = 0
        except (ValueError, IOError):
            #if we hit an error in SHNDecoder while reading
            #technical metadata, the default values will have to do
            return

        #the remainder requires parsing the file's VERBATIM blocks
        #which may contain Wave, AIFF or Sun AU info
        if (self.__blocks__[0] is not None):
            header = cStringIO.StringIO(self.__blocks__[0])
            for format in WaveAudio, AiffAudio:
                header.seek(0, 0)
                if (format.is_type(header)):
                    self.__format__ = format
                    break
            if (self.__format__ is WaveAudio):
                for (chunk_id, chunk_data) in self.__wave_chunks__():
                    if (chunk_id == 'fmt '):
                        fmt_chunk = WaveAudio.FMT_CHUNK.parse(chunk_data)
                        self.__sample_rate__ = fmt_chunk.sample_rate
                        if (fmt_chunk.compression == 0xFFFE):
                            self.__channel_mask__ = \
                                WaveAudio.fmt_chunk_to_channel_mask(
                                fmt_chunk.channel_mask)
            elif (self.__format__ is AiffAudio):
                for (chunk_id, chunk_data) in self.__aiff_chunks__():
                    if (chunk_id == 'COMM'):
                        comm_chunk = AiffAudio.COMM_CHUNK.parse(chunk_data)
                        self.__sample_rate__ = comm_chunk.sample_rate
Ejemplo n.º 6
0
    def __populate_metadata__(self):
        #set up some default values
        self.__bits_per_sample__ = 16
        self.__channels__ = 2
        self.__channel_mask__ = 0x3
        self.__sample_rate__ = 44100
        self.__total_frames__ = 0
        self.__blocks__ = []
        self.__format__ = None

        #grab a few pieces of technical metadata from the Shorten file itself
        #which requires a dry-run through the decoder
        try:
            decoder = audiotools.decoders.SHNDecoder(self.filename)
            try:

                self.__bits_per_sample__ = decoder.bits_per_sample
                self.__channels__ = decoder.channels
                (self.__total_frames__,
                 self.__blocks__) = decoder.metadata()
            finally:
                decoder.close()

            try:
                self.__channel_mask__ = ChannelMask.from_channels(
                    self.__channels__)
            except ValueError:
                self.__channel_mask__ = 0
        except (ValueError, IOError):
            #if we hit an error in SHNDecoder while reading
            #technical metadata, the default values will have to do
            return

        #the remainder requires parsing the file's VERBATIM blocks
        #which may contain Wave, AIFF or Sun AU info
        if (self.__blocks__[0] is not None):
            header = cStringIO.StringIO(self.__blocks__[0])
            for format in WaveAudio, AiffAudio:
                header.seek(0, 0)
                if (format.is_type(header)):
                    self.__format__ = format
                    break
            if (self.__format__ is WaveAudio):
                for (chunk_id, chunk_data) in self.__wave_chunks__():
                    if (chunk_id == 'fmt '):
                        fmt_chunk = WaveAudio.FMT_CHUNK.parse(chunk_data)
                        self.__sample_rate__ = fmt_chunk.sample_rate
                        if (fmt_chunk.compression == 0xFFFE):
                            self.__channel_mask__ = \
                                WaveAudio.fmt_chunk_to_channel_mask(
                                fmt_chunk.channel_mask)
            elif (self.__format__ is AiffAudio):
                for (chunk_id, chunk_data) in self.__aiff_chunks__():
                    if (chunk_id == 'COMM'):
                        comm_chunk = AiffAudio.COMM_CHUNK.parse(chunk_data)
                        self.__sample_rate__ = comm_chunk.sample_rate
Ejemplo n.º 7
0
    def from_pcm(cls,
                 filename,
                 pcmreader,
                 compression=None,
                 total_pcm_frames=None,
                 block_size=256,
                 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 ShortenAudio object"""

        # can't build artificial header because we don't know
        # how long the PCMReader will be and there's no way
        # to go back and write one later because all the byte values
        # are stored variable-sized
        # so we have to build a temporary Wave file instead

        from audiotools import UnsupportedBitsPerSample

        if (pcmreader.bits_per_sample not in (8, 16)):
            raise UnsupportedBitsPerSample(filename, pcmreader.bits_per_sample)

        if (total_pcm_frames is not None):
            from audiotools.wav import wave_header

            return cls.from_wave(
                filename,
                wave_header(pcmreader.sample_rate, pcmreader.channels,
                            pcmreader.channel_mask, pcmreader.bits_per_sample,
                            total_pcm_frames), pcmreader,
                chr(0) * (((pcmreader.bits_per_sample // 8) *
                           pcmreader.channels * total_pcm_frames) % 2),
                compression, block_size, encoding_function)
        else:
            from audiotools import WaveAudio
            import tempfile

            f = tempfile.NamedTemporaryFile(suffix=".wav")
            try:
                w = WaveAudio.from_pcm(f.name, pcmreader)
                (header, footer) = w.wave_header_footer()
                return cls.from_wave(filename, header, w.to_pcm(), footer,
                                     compression, block_size,
                                     encoding_function)
            finally:
                if (os.path.isfile(f.name)):
                    f.close()
                else:
                    f.close_called = True
Ejemplo n.º 8
0
    def from_pcm(cls, filename, pcmreader, compression=None):
        if (pcmreader.bits_per_sample not in (8,16)):
            raise UnsupportedBitsPerSample()

        import tempfile

        f = tempfile.NamedTemporaryFile(suffix=".wav")
        w = WaveAudio.from_pcm(f.name, pcmreader)
        try:
            return cls.from_wave(filename,f.name,compression)
        finally:
            f.close()
Ejemplo n.º 9
0
    def __populate_metadata__(self):
        # Alteration for BootTunes:
        # Since the vast majority of files will match the defaults, and because this method crashes
        # Windows 7 and locks up Mac, just go with the defaults.          
        self.__bits_per_sample__ = 16
        self.__channels__ = 2
        self.__channel_mask__ = 0x3
        self.__sample_rate__ = 44100
        self.__total_frames__ = 0
        self.__blocks__ = []
        self.__format__ = None
        return        

        #grab a few pieces of technical metadata from the Shorten file itself
        #which requires a dry-run through the decoder
        decoder = audiotools.decoders.SHNDecoder(self.filename)
        self.__bits_per_sample__ = decoder.bits_per_sample
        self.__channels__ = decoder.channels
        (self.__total_frames__,
         self.__blocks__) = decoder.metadata()
        decoder.close()

        #set up some default values
        self.__sample_rate__ = 44100
        try:
            self.__channel_mask__ = ChannelMask.from_channels(self.__channels__)
        except ValueError:
            self.__channel_mask__ = 0
        self.__format__ = None

        #the remainder requires parsing the file's VERBATIM blocks
        #which may contain Wave, AIFF or Sun AU info
        if (self.__blocks__[0] is not None):
            header = cStringIO.StringIO(self.__blocks__[0])
            for format in WaveAudio,AiffAudio:
                header.seek(0,0)
                if (format.is_type(header)):
                    self.__format__ = format
                    break
            if (self.__format__ is WaveAudio):
                for (chunk_id,chunk_data) in self.__wave_chunks__():
                    if (chunk_id == 'fmt '):
                        fmt_chunk = WaveAudio.FMT_CHUNK.parse(chunk_data)
                        self.__sample_rate__ = fmt_chunk.sample_rate
                        if (fmt_chunk.compression == 0xFFFE):
                            self.__channel_mask__ = WaveAudio.fmt_chunk_to_channel_mask(fmt_chunk.channel_mask)
            elif (self.__format__ is AiffAudio):
                for (chunk_id,chunk_data) in self.__aiff_chunks__():
                    if (chunk_id == 'COMM'):
                        comm_chunk = AiffAudio.COMM_CHUNK.parse(chunk_data)
                        self.__sample_rate__ = comm_chunk.sample_rate
Ejemplo n.º 10
0
    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")
Ejemplo n.º 11
0
    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)

        import tempfile

        tempwavefile = tempfile.NamedTemporaryFile(suffix=".wav")
        try:
            if pcmreader.sample_rate > 96000:
                tempwave = WaveAudio.from_pcm(
                    tempwavefile.name,
                    PCMConverter(
                        pcmreader,
                        sample_rate=96000,
                        channels=pcmreader.channels,
                        channel_mask=pcmreader.channel_mask,
                        bits_per_sample=pcmreader.bits_per_sample,
                    ),
                )
            else:
                tempwave = WaveAudio.from_pcm(tempwavefile.name, pcmreader)

            cls.__from_wave__(filename, tempwave.filename, compression)
            return cls(filename)
        finally:
            if os.path.isfile(tempwavefile.name):
                tempwavefile.close()
            else:
                tempwavefile.close_called = True
Ejemplo n.º 12
0
    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()
        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(wave, progress),
                block_size=block_size,
                file_type={8: 2,
                           16: 5}[wave.bits_per_sample()],
                verbatim_chunks=blocks)

            return cls(filename)
        except IOError, err:
            cls.__unlink__(filename)
            raise EncodingError(str(err))
Ejemplo n.º 13
0
    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)
Ejemplo n.º 14
0
    def from_pcm(cls, filename, pcmreader, compression=None, block_size=256):
        """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 ShortenAudio object"""

        if pcmreader.bits_per_sample not in (8, 16):
            raise UnsupportedBitsPerSample(filename, pcmreader.bits_per_sample)

        import tempfile

        f = tempfile.NamedTemporaryFile(suffix=".wav")
        try:
            w = WaveAudio.from_pcm(f.name, pcmreader)
            return cls.from_wave(filename, f.name, compression, block_size)
        finally:
            if os.path.isfile(f.name):
                f.close()
            else:
                f.close_called = True
Ejemplo n.º 15
0
    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))
Ejemplo n.º 16
0
    def from_pcm(cls, filename, pcmreader, compression=None,
                 block_size=256):
        """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 ShortenAudio object."""

        if (pcmreader.bits_per_sample not in (8, 16)):
            raise UnsupportedBitsPerSample()

        import tempfile

        f = tempfile.NamedTemporaryFile(suffix=".wav")
        try:
            w = WaveAudio.from_pcm(f.name, pcmreader)
            return cls.from_wave(filename, f.name, compression, block_size)
        finally:
            if (os.path.isfile(f.name)):
                f.close()
            else:
                f.close_called = True
Ejemplo n.º 17
0
 def play_wave(self, stream):
     """
     @param stream: A pyaudio.Stream object
     """
     pcm = self.to_pcm()
     WaveAudio.from_pcm_to_stream(pcm, stream)
Ejemplo n.º 18
0
                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:
Ejemplo n.º 19
0
    def from_pcm(cls, filename, pcmreader,
                 compression=None,
                 total_pcm_frames=None,
                 block_size=256,
                 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 ShortenAudio object"""

        # can't build artificial header because we don't know
        # how long the PCMReader will be and there's no way
        # to go back and write one later because all the byte values
        # are stored variable-sized
        # so we have to build a temporary Wave file instead

        from audiotools import UnsupportedBitsPerSample

        if (pcmreader.bits_per_sample not in (8, 16)):
            raise UnsupportedBitsPerSample(filename, pcmreader.bits_per_sample)

        if (total_pcm_frames is not None):
            from audiotools.wav import wave_header

            return cls.from_wave(filename,
                                 wave_header(pcmreader.sample_rate,
                                             pcmreader.channels,
                                             pcmreader.channel_mask,
                                             pcmreader.bits_per_sample,
                                             total_pcm_frames),
                                 pcmreader,
                                 chr(0) * (((pcmreader.bits_per_sample // 8) *
                                            pcmreader.channels *
                                            total_pcm_frames) % 2),
                                 compression,
                                 block_size,
                                 encoding_function)
        else:
            from audiotools import WaveAudio
            import tempfile

            f = tempfile.NamedTemporaryFile(suffix=".wav")
            try:
                w = WaveAudio.from_pcm(f.name, pcmreader)
                (header, footer) = w.wave_header_footer()
                return cls.from_wave(filename,
                                     header,
                                     w.to_pcm(),
                                     footer,
                                     compression,
                                     block_size,
                                     encoding_function)
            finally:
                if (os.path.isfile(f.name)):
                    f.close()
                else:
                    f.close_called = True
Ejemplo n.º 20
0
            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
        at the given filename with the specified compression level
        and returns a new ShortenAudio object."""

        wave = WaveAudio(wave_filename)