The audiotools module contains a number of useful base classes and functions upon which all of the other modules depend.
The current Python Audio Tools version as a plain string.
A tuple of AudioFile-compatible classes of available audio types. Note these are types available to audiotools, not necessarily available to the user - depending on whether the required binaries are installed or not.
Class | Format |
AACAudio | AAC in ADTS container |
AiffAudio | Audio Interchange File Format |
ALACAudio | Apple Lossless |
AuAudio | Sun Au |
FlacAudio | Native Free Lossless Audio Codec |
M4AAudio | AAC in M4A container |
MP3Audio | MPEG-1 Layer 3 |
MP2Audio | MPEG-1 Layer 2 |
OggFlacAudio | Ogg Free Lossless Audio Codec |
OpusAudio | Opus Audio Codec |
ShortenAudio | Shorten |
SpeexAudio | Ogg Speex |
VorbisAudio | Ogg Vorbis |
WaveAudio | Waveform Audio File Format |
WavPackAudio | WavPack |
The default type to use as a plain string, such as 'wav' or 'flac'.
A dict of type name strings -> quality value strings indicating the default compression quality value for the given type name suitable for AudioFile.from_pcm() and AudioFile.convert() method calls.
The default CD-ROM device to use for CD audio and DVD-Audio extraction as a plain string.
A dictionary of type name strings -> AudioFile values containing only types which have all required binaries installed.
The default format string to use for newly created files.
A dictionary-like class for performing lookups of system binaries. This checks the system and user’s config files and ensures that any redirected binaries are called from their proper location. For example, if the user has configured flac(1) to be run from /opt/flac/bin/flac
>>> BIN["flac"]
"/opt/flac/bin/flac"
This class also has a can_execute() method which returns True if the given binary is executable.
>>> BIN.can_execute(BIN["flac"])
True
The defined encoding to use for output to the screen as a plain string. This is typically 'utf-8'.
The defined encoding to use for filenames read and written to disk as a plain string. This is typically 'utf-8'.
The maximum number of simultaneous jobs to run at once by default as an integer. This may be defined from the user’s config file. Otherwise, if Python’s multiprocessing module is available, this is set to the user’s CPU count. If neither is available, this is set to 1.
Given a seekable file object returns an AudioFile-compatible class of the stream’s detected type, or None if the stream’s type is unknown.
The AudioFile class may not be available for use and so its AudioFile.available() classmethod may need to be checked separately.
Opens the given filename string and returns an AudioFile-compatible object. Raises UnsupportedFile if the file cannot identified or is not supported. Raises IOError if the file cannot be opened at all.
Given a list of filename strings, returns a list of AudioFile-compatible objects which are successfully opened. By default, they are returned sorted by album number and track number.
If sorted is False, they are returned in the same order as they appear in the filenames list.
If messenger is given, use that Messenger object to for warnings if files cannot be opened. Otherwise, such warnings are sent to stdout.
If no_duplicates is True, attempting to open the same file twice raises a DuplicateFile exception.
If no_duplicates is False and warn_duplicates is True, attempting to open the same file twice results in a warning to messenger, if present.
opened_files, if present, is a set of previously opened Filename objects for the purpose of detecting duplicates. Any opened files are added to that set.
Given a root directory, returns an iterator of all the AudioFile-compatible objects found via a recursive search of that directory. sorted, and messenger work as in open_files().
Given a list of AudioFile objects, returns a new list of those objects sorted by album number and track number, if present. If album number and track number aren’t present, objects are sorted by base filename.
Given an iterable collection of AudioFile-compatible objects, returns an iterator of objects grouped into lists by album. That is, all objects with the same album_name and album_number metadata fields will be returned in the same list on each pass.
Given a path, try to guess its AudioFile class based on its filename suffix. Raises UnknownAudioType if the suffix is unrecognized. Raises AmbiguousAudioType if more than one type of audio shares the same suffix.
This function takes two functions, presumably analogous to write() and read() functions, respectively. It calls to_function on the object returned by calling from_function with an integer argument (presumably a string) until that object’s length is 0.
>>> infile = open("input.txt", "r")
>>> outfile = open("output.txt", "w")
>>> transfer_data(infile.read, outfile.write)
>>> infile.close()
>>> outfile.close()
A natural progression of transfer_data(), this function takes a PCMReader object and transfers the pcm.FrameList objects returned by its PCMReader.read() method to to_function after converting them to plain strings.
The pcmreader is closed once decoding is complete.
May raise IOError or ValueError if a problem occurs during decoding.
>>> pcm_data = audiotools.open("file.wav").to_pcm()
>>> outfile = open("output.pcm","wb")
>>> transfer_framelist_data(pcm_data,outfile)
>>> pcm_data.close()
>>> outfile.close()
This function takes two PCMReader objects and compares their PCM output. Returns True if that output matches exactly, False if not.
Both streams are closed once comparison is completed.
May raise IOError or ValueError if problems occur during reading.
This function takes two PCMReader objects and compares their PCM frame output. It returns the frame number of the first mismatch as an integer which begins at frame number 0. If the two streams match completely, it returns None.
Both streams are closed once comparison is completed.
May raise IOError or ValueError if problems occur during reading.
Takes a PCMReader object and list of PCM sample length integers. Returns an iterator of new PCMReader objects, each limited to the given lengths. The original pcmreader is closed upon the iterator’s completion.
Takes a list of AudioFile-compatible objects. Returns an iterator of (audiofile, track_gain, track_peak, album_gain, album_peak) tuples or raises ValueError if a problem occurs during calculation.
Given a .cue or .toc filename, returns a Sheet of that file’s cuesheet data. May raise SheetException if the file cannot be read or parsed correctly.
Given an AudioFile-compatible object and progress function, returns a PCMReaderProgress object of that object’s PCM stream.
If progress is None, the audiofile’s PCM stream is returned as-is.
Filename is a file which may or may not exist on disk. filename is a raw string of the actual filename. Filename objects are immutable and hashable, which means they can be used as dictionary keys or placed in sets.
The purpose of Filename objects is for easier conversion of raw string filename paths to Unicode, and to make it easier to detect filenames which point to the same file on disk.
The former case is used by utilities to display output about file operations in progress. The latter case is for utilities which need to avoid overwriting input files with output files.
Returns the raw string of the actual filename after being normalized.
Returns a Unicode string of the filename after being decoded through FS_ENCODING.
Filename objects which exist on disk hash and compare equally if their device ID and inode number values match (the st_dev and st_ino fields according to stat(2)). Filename objects which don’t exist on disk hash and compare equally if their filename string matches.
Returns a file object of this filename opened with the given mode.
Returns True if the file currently exists on disk.
The AudioFile class represents an audio file on disk, such as a FLAC file, MP3 file, WAVE file and so forth. It is not meant to be instantiated directly. Instead, functions such as open() will return AudioFile-compatible objects with the following attributes and methods.
The name of the format as a string. This is how the format is referenced by utilities via the -t option, and must be unique among all formats.
The default file suffix as a string. This is used by the %(suffix)s format field in the track_name() classmethod, and by the filename_to_type() function for inferring the file format from its name. However, it need not be unique among all formats.
A longer, descriptive name for the audio type as a Unicode string. This is meant to be human-readable.
A tuple of valid compression level strings, for use with the from_pcm() and convert() methods. If the format has no compression levels, this tuple will be empty.
A string of the default compression level to use with from_pcm() and convert(), if none is given. This is not the default compression indicated in the user’s configuration file; it is a hard-coded value of last resort.
A dict of compression descriptions, as Unicode strings. The key is a valid compression mode string. Not all compression modes need have a description; some may be left blank.
A tuple of binary strings required by the format. For example, the Vorbis format may require "oggenc" and "oggdec" in order to be available for the user.
A tuple of binary strings required for ReplayGain application. For example, the Vorbis format may require "vorbisgain" in order to use the add_replay_gain() classmethod. This tuple may be empty if the format requires no binaries or has no ReplayGain support.
Returns the number of bits-per-sample in this audio file as a positive integer.
Returns the number of channels in this audio file as a positive integer.
Returns a ChannelMask object representing the channel assignment of this audio file. If the channel assignment is unknown or undefined, that ChannelMask object may have an undefined value.
Returns the sample rate of this audio file, in Hz, as a positive integer.
Returns the total number of PCM frames in this audio file, as a non-negative integer.
Returns the total number of CD frames in this audio file, as a non-negative integer. Each CD frame is 1/75th of a second.
Returns the length of this audio file as a fractions.Fraction number of seconds.
Returns True if the data in the audio file has been stored losslessly. Returns False if not.
Returns True is this audio type supports metadata. If not, AudioFile.get_metadata() will always return None and the metadata updating routines will do nothing.
Takes a MetaData object and sets this audio file’s metadata to that value, if possible. Setting metadata to None is the same as calling AudioFile.delete_metadata(). Raises IOError if a problem occurs when writing the file.
Takes the MetaData-compatible object returned by this audio file’s AudioFile.get_metadata() method and sets this audiofile’s metadata to that value, if possible. Raises IOError if a problem occurs when writing the file.
Note
What’s the difference between AudioFile.set_metadata() and AudioFile.update_metadata()?
Metadata implementations may also contain side information such as track length, file encoder, and so forth. AudioFile.set_metadata() presumes the MetaData object is from a different AudioFile object or has been built from scratch. Therefore, it will update the newly added metadata side info as needed so as to not break the file.
AudioFile.update_metadata() presumes the MetaData object is either taken from the original AudioFile object or has been carefully constructed to not break anything when applied to the file. It is a lower-level routine which does not update metadata side info (which may be necessary when modifying that side info is required).
Returns a MetaData-compatible object representing this audio file’s metadata, or None if this file contains no metadata. Raises IOError if a problem occurs when reading the file.
Deletes the audio file’s metadata, removing or unsetting tags as necessary. Raises IOError if a problem occurs when writing the file.
Returns this audio file’s PCM data as a PCMReader-compatible object. May return a PCMReaderError if an error occurs initializing the decoder.
Returns True if the necessary libraries or binaries are installed to support decoding this format.
Takes a filename string, PCMReader-compatible object, optional compression level string and optional total_pcm_frames integer. Creates a new audio file as the same format as this audio class and returns a new AudioFile-compatible object. The PCMReader.close() method is called once encoding is complete.
Raises EncodingError if a problem occurs during encoding.
Specifying the total number of PCM frames to be encoded, when the number is known in advance, may allow the encoder to work more efficiently but is never required.
In this example, we’ll transcode track.flac to track.mp3 at the default compression level:
>>> audiotools.MP3Audio.from_pcm("track.mp3",
... audiotools.open("track.flac").to_pcm())
Returns True if the necessary libraries or binaries are installed to support encoding this format.
Takes a filename string, AudioFile subclass and optional compression level string. Creates a new audio file and returns an object of the same class. Raises EncodingError if a problem occurs during encoding.
In this example, we’ll transcode track.flac to track.mp3 at the default compression level:
>>> audiotools.open("track.flac").convert("track.mp3",
... audiotools.MP3Audio)
Why have both a convert method as well as to_pcm/from_pcm methods? Although the former is often implemented using the latter, the pcm methods alone contain only raw audio data. By comparison, the convert method has information about what is the file is being converted to and can transfer other side data if necessary.
For example, if .wav file with non-audio RIFF chunks is converted to WavPack, this method will preserve those chunks:
>>> audiotools.open("chunks.wav").convert("chunks.wv",
... audiotools.WavPackAudio)
whereas the to_pcm/from_pcm method alone will not.
The optional progress argument is a function which takes a single Fraction argument which is the current progress between 0 and 1, inclusive. If supplied, this function is called at regular intervals during the conversion process and may be used to indicate the current status to the user.
Returns True if the file is seekable. That is, if its PCMReader has a .seek() method and that method supports some fine-grained seeking when the PCMReader is working from on-disk files.
Verifies the track for correctness. Returns True if verification is successful. Raises an InvalidFile subclass if some problem is detected. If the file has built-in checksums or other error detection capabilities, this method checks those values to ensure it has not been damaged in some way.
The optional progress argument functions identically to the one provided to convert().
Given a file path string, optional MetaData-compatible object, optional Python format string, and optional suffix string, returns a filename string with the format string fields filled-in. Raises UnsupportedTracknameField if the format string contains unsupported fields.
Currently supported fields are:
Field | Value |
%(album_name)s | track_metadata.album_name |
%(album_number)s | track_metadata.album_number |
%(album_total)s | track_metadata.album_total |
%(album_track_number)s | album_number combined with track_number |
%(artist_name)s | track_metadata.artist_name |
%(catalog)s | track_metadata.catalog |
%(comment)s | track_metadata.comment |
%(composer_name)s | track_metadata.composer_name |
%(conductor_name)s | track_metadata.conductor_name |
%(copyright)s | track_metadata.copyright |
%(date)s | track_metadata.date |
%(ISRC)s | track_metadata.ISRC |
%(media)s | track_metadata.year |
%(performer_name)s | track_metadata.performer_name |
%(publisher)s | track_metadata.publisher |
%(suffix)s | the AudioFile suffix |
%(track_name)s | track_metadata.track_name |
%(track_number)2.2d | track_metadata.track_number |
%(track_total)s | track_metadata.track_total |
%(year)s | track_metadata.year |
%(basename)s | file_path basename without suffix |
Returns True if this class supports ReplayGain metadata.
Returns this audio file’s ReplayGain values as a ReplayGain object, or None if this audio file has no values.
Given a ReplayGain object, sets the audio file’s gain values.
Raises IOError if unable to modify the file.
Removes any gain values from the file.
Raises IOError if unable to modify the file.
Returns True if the audio format supports embedded Sheet objects.
Given a Sheet object, embeds a cuesheet in the track. This is for tracks which represent a whole CD image and wish to store track break data internally. May raise IOError if an error occurs writing the file.
Returns a Sheet object of a track’s embedded cuesheet, or None if the track contains no cuesheet. May raise IOError if an error occurs reading the file.
Deletes embedded Sheet object, if any. May raise IOError if an error occurs updating the file.
Cleans the audio file of known data and metadata problems.
output_filename is an optional string in which the fixed audio file is placed. If omitted, no actual fixes are performed. Note that this method never modifies the original file.
Returns list of fixes performed as Unicode strings.
Raises IOError if some error occurs when writing the new file. Raises ValueError if the file itself is invalid.
This is an abstract AudioFile subclass suitable for extending by formats that store RIFF WAVE chunks internally, such as Wave, FLAC, WavPack and Shorten. It overrides the AudioFile.convert() method such that any stored chunks are transferred properly from one file to the next. This is accomplished by implementing three additional methods.
Returns True if our object has non-audio RIFF WAVE chunks.
Returns (header, footer) tuple of strings where header is everything before the PCM data and footer is everything after the PCM data.
May raise ValueError if there’s a problem with the header or footer data, such as invalid chunk IDs. May raise IOError if there’s a problem reading the header or footer data from the file.
Encodes a new file from wave data. header and footer are binary strings as returned by a WaveContainer.wave_header_footer() method, pcmreader is a PCMReader object and compression is a binary string.
Returns a new AudioFile-compatible object or raises EncodingError if some error occurs when encoding the file.
Much like WaveContainer, this is an abstract AudioFile subclass suitable for extending by formats that store AIFF chunks internally, such as AIFF, FLAC and Shorten. It overrides the AudioFile.convert() method such that any stored chunks are transferred properly from one file to the next. This is accomplished by implementing three additional methods.
Returns True if our object has non-audio AIFF chunks.
Returns (header, footer) tuple of strings where header is everything before the PCM data and footer is everything after the PCM data.
May raise ValueError if there’s a problem with the header or footer data, such as invalid chunk IDs. May raise IOError if there’s a problem reading the header or footer data from the file.
Encodes a new file from wave data. header and footer are binary strings as returned by a AiffContainer.aiff_header_footer() method, pcmreader is a PCMReader object and compression is a binary string.
Returns a new AudioFile-compatible object or raises EncodingError if some error occurs when encoding the file.
The MetaData class represents an AudioFile‘s non-technical metadata. It can be instantiated directly for use by the set_metadata() method. However, the get_metadata() method will typically return MetaData-compatible objects corresponding to the audio file’s low-level metadata implementation rather than actual MetaData objects. Modifying fields within a MetaData-compatible object will modify its underlying representation and those changes will take effect should set_metadata() be called with that updated object.
The images argument, if given, should be an iterable collection of Image-compatible objects.
MetaData attributes may be None, which indicates the low-level implementation has no corresponding entry. For instance, ID3v2.3 tags use the "TALB" frame to indicate the track’s album name. If that frame is present, an audiotools.ID3v23Comment MetaData object will have an album_name field containing a Unicode string of its value. If that frame is not present in the ID3v2.3 tag, its album_name field will be None.
For example, to access a track’s album name field:
>>> metadata = track.get_metadata()
>>> metadata.album_name
u"Album Name"
To change a track’s album name field:
>>> metadata = track.get_metadata()
>>> metadata.album_name = u"Updated Album Name"
>>> track.update_metadata(metadata) # because metadata comes from track's get_metadata() method, one can use update_metadata()
To delete a track’s album name field:
>>> metadata = track.get_metadata()
>>> del(metadata.album_name)
>>> track.update_metadata(metadata)
Or to replace a track’s entire set of metadata:
>>> metadata = MetaData(track_name=u"Track Name",
... album_name=u"Updated Album Name",
... track_number=1,
... track_total=3)
>>> track.set_metadata(metadata) # because metadata is built from scratch, one must use set_metadata()
This individual track’s name as a Unicode string.
This track’s number within the album as an integer.
The total number of tracks on the album as an integer.
The name of this track’s album as a Unicode string.
The name of this track’s original creator/composer as a Unicode string.
The name of this track’s performing artist as a Unicode string.
The name of this track’s composer as a Unicode string.
The name of this track’s conductor as a Unicode string.
The album’s media type, such as u”CD”, u”tape”, u”LP”, etc. as a Unicode string.
This track’s ISRC value as a Unicode string.
This track’s album catalog number as a Unicode string.
This track’s album release year as a Unicode string.
This track’s album recording date as a Unicode string.
This track’s album number if it is one of a series of albums, as an integer.
The total number of albums within the set, as an integer.
This track’s comment as a Unicode string.
Whether this track is part of a compilation, as a boolean.
Yields an (attr, value) tuple per non-blank MetaData field. Non-blank fields are those with a value other than None.
Yields an (attr, value) tuple per blank MetaData field. Blank fields are those with a value of None.
Takes a MetaData-compatible object (or None) and returns a new MetaData object of the same class, or None. For instance, VorbisComment.converted() returns VorbisComment objects. The purpose of this classmethod is to offload metadata conversion to the metadata classes themselves. Therefore, by using the VorbisComment.converted() classmethod, the VorbisAudio class only needs to know how to handle VorbisComment metadata.
Why not simply handle all metadata using this high-level representation and avoid conversion altogether? The reason is that MetaData is often only a subset of what the low-level implementation can support. For example, a VorbisComment may contain the 'FOO' tag which has no analogue in MetaData‘s list of fields. But when passed through the VorbisComment.converted() classmethod, that 'FOO' tag will be preserved as one would expect.
The key is that performing:
>>> track.set_metadata(track.get_metadata())
should always round-trip properly and not lose any metadata values.
Returns True if this MetaData implementation supports images. Returns False if not.
Takes a Image-compatible object and adds it to this metadata’s list of images.
Takes an Image from this class, as returned by images(), and removes it from this metadata’s list of images.
Returns a (MetaData, fixes_performed) tuple where MetaData is an object that’s been cleaned of problems and fixes_performed is a list of unicode strings detailing those problems. Problems include:
Returns a Unicode string of raw metadata information with as little filtering as possible. This is meant to be useful for debugging purposes.
Given a MetaData object, this returns a new MetaData object containing only the fields which match those in this object. It is analagous to a set intersection in that only common fields are preserved.
If both objects are of the same class, an object of the same class will be returned.
If metadata is None, returns None.
This class is a container for image data.
A plain string of raw image bytes.
A Unicode string of this image’s MIME type, such as u’image/jpeg’
This image’s width in pixels as an integer.
This image’s height in pixels as an integer
This image’s color depth in bits as an integer. 24 for JPEG, 8 for GIF, etc.
For palette-based images, this is the number of colors the image contains as an integer. For non-palette images, this value is 0.
A Unicode string of this image’s description.
An integer representing this image’s type.
Value | Type |
0 | front cover |
1 | back cover |
2 | leaflet page |
3 | media |
4 | other |
Returns this image’s typical filename suffix as a plain string. For example, JPEGs return "jpg"
Returns this image’s type as a plain string. For example, an image of type 0 returns "Front Cover"
Given a string of raw image bytes, a Unicode description string and image type integer, returns an Image-compatible object. Raises InvalidImage If unable to determine the image type from the data string.
This is a simple container for ReplayGain values.
A float of a track’s ReplayGain value.
A float of a track’s peak value, from 0.0 to 1.0
A float of an album’s ReplayGain value.
A float of an album’s peak value, from 0.0 to 1.0
This is an abstract base class for streams of audio data which are file-like objects with additional stream parameters. Subclasses are expected to implement read and close.
The sample rate of this audio stream, in Hz, as a positive integer.
The number of channels in this audio stream as a positive integer.
The channel mask of this audio stream as a non-negative integer.
The number of bits-per-sample in this audio stream as a positive integer.
Try to read a pcm.FrameList object with the given number of PCM frames, if possible. This method is not guaranteed to read that amount of frames. It may return less, particularly at the end of an audio stream. It may even return FrameLists larger than requested. However, it must always return a non-empty FrameList until the end of the PCM stream is reached.
Once the end of the stream is reached, subsequent calls will return empty FrameLists.
May raise IOError if there is a problem reading the source file, or ValueError if the source file has some sort of error.
Closes the audio stream. If any subprocesses were used for audio decoding, they will also be closed and waited for their process to finish.
Subsequent calls to PCMReader.read() will raise ValueError exceptions once the stream is closed.
Returns the PCMReader. This is used for implementing context management.
Calls PCMReader.close(). This is used for implementing context management.
This class wraps around file-like objects and generates pcm.FrameList objects on each call to read(). sample_rate, channels, channel_mask and bits_per_sample should be integers. process is a subprocess helper object which generates PCM data. signed is True if the generated PCM data is signed. big_endian is True if the generated PCM data is big-endian.
This is a subclass of PCMReader which always returns empty always raises a ValueError when its read method is called. The purpose of this is to postpone error generation so that all encoding errors, even those caused by unsuccessful decoding, are restricted to the from_pcm() classmethod which can then propagate an EncodingError error message to the user.
This class takes an existing PCMReader-compatible object along with a new set of sample_rate, channels, channel_mask and bits_per_sample values. Data from pcmreader is then automatically converted to the same format as those values.
If the new sample rate differs from pcmreader‘s sample rate, audio data is automatically resampled on each call to read().
If the new number of channels is smaller than pcmreader‘s channel count, existing channels are removed or downmixed as necessary. If the new number of channels is larger, data from the first channel is duplicated as necessary to fill the rest.
If the new channel mask differs from pcmreader‘s channel mask, channels are removed as necessary such that the proper channel only outputs to the proper speaker.
If the new bits-per-sample differs from pcmreader‘s number of bits-per-sample, samples are shrunk or enlarged as necessary to cover the full amount of bits.
This method functions the same as the PCMReader.read() method.
This method functions the same as the PCMReader.close() method.
This class wraps around an existing PCMReader object. Its calls to read() are guaranteed to return pcm.FrameList objects as close to the requested amount of PCM frames as possible without going over by buffering data internally.
The reason such behavior is not required is that we often don’t care about the size of the individual FrameLists being passed from one routine to another. But on occasions when we need pcm.FrameList objects to be of a particular size, this class can accomplish that.
This class wraps around an existing PCMReader object and keeps track of the number of bytes and frames written upon each call to read.
The number of PCM frames written thus far.
The number of bytes written thus far.
This class wraps around an existing PCMReader object. It takes a list of channel number integers (which should be the same as pcmreader‘s channel count) and reorders channels upon each call to read().
For example, to swap channels 0 and 1 in a stereo stream, one could do the following:
>>> reordered = ReorderedPCMReader(original, [1, 0])
Calls to reordered.read() will then have the left channel on the right side and vice versa.
This class wraps around an existing PCMReader object and truncates or extends its samples as needed. initial_offset, if positive, indicates how many PCM frames to truncate from the beginning of the stream. If negative, the beginning of the stream is padded by that many PCM frames - all of which have a value of 0. total_pcm_frames indicates the total length of the stream as a non-negative number of PCM frames. If shorter than the actual length of the PCM reader’s stream, the reader is truncated. If longer, the stream is extended by as many PCM frames as needed. Again, padding frames have a value of 0.
If forward_close is True, calls to PCMReaderWindow.close() are passed along to the wrapped PCMReader object. Otherwise, the close is confined to the PCMReaderWindow object. This may be necessary when encoding sub-streams from a larger stream in which closing the larger stream after each encode isn’t desirable.
This class wraps around an existing BufferedPCMReader and ensures that no more than total_pcm_frames will be read from that stream by limiting reads to it.
Note
PCMReaderWindow is designed primarily for handling sample offset values in a CDTrackReader, or for skipping a potentially large number of samples in a stream. LimitedPCMReader is designed for splitting a stream into several smaller streams without losing any PCM frames.
Which to use for a given situation depends on whether one cares about consuming the samples outside of the sub-reader or not.
This class wraps around an existing PCMReader object and generates periodic updates to a given progress function. total_frames indicates the total number of PCM frames in the PCM stream.
>>> progress_display = SingleProgressDisplay(Messenger("audiotools"), u"encoding file")
>>> pcmreader = source_audiofile.to_pcm()
>>> source_frames = source_audiofile.total_frames()
>>> target_audiofile = AudioType.from_pcm("target_filename",
... PCMReaderProgress(pcmreader,
... source_frames,
... progress_display.update))
This class is for incrementally calculating ReplayGain for an album during decoding. All tracks calculated must have the same sample rate which may mean resampling them to that rate if necessary.
Given a PCMReader object, returns a ReplayGainCalculatorReader linked to this calculator.
Yields (title_gain, title_peak, album_gain, album_peak) tuples for each PCMReader processed with ReplayGainCalculator.to_pcm() in the order in which they were processed.
These objects are typically returned from ReplayGainCalculator.to_pcm() rather than instantiated directly. They function as PCMReader objects which process the pcm.FrameList objects returned by read prior to returning them.
Returns the title gain of the whole track as a floating point value.
Returns the title peak of the whole track as a floating point value.
This is an integer-like class that abstracts channel assignments into a set of bit fields.
Mask | Speaker |
0x1 | front_left |
0x2 | front_right |
0x4 | front_center |
0x8 | low_frequency |
0x10 | back_left |
0x20 | back_right |
0x40 | front_left_of_center |
0x80 | front_right_of_center |
0x100 | back_center |
0x200 | side_left |
0x400 | side_right |
0x800 | top_center |
0x1000 | top_front_left |
0x2000 | top_front_center |
0x4000 | top_front_right |
0x8000 | top_back_left |
0x10000 | top_back_center |
0x20000 | top_back_right |
All channels in a pcm.FrameList will be in RIFF WAVE order as a sensible convention. But which channel corresponds to which speaker is decided by this mask. For example, a 4 channel PCMReader with the channel mask 0x33 corresponds to the bits 00110011
Reading those bits from right to left (least significant first) the front_left, front_right, back_left, back_right speakers are set. Therefore, the PCMReader’s 4 channel FrameLists are laid out as follows:
Since the front_center and low_frequency bits are not set, those channels are skipped in the returned FrameLists.
Many formats store their channels internally in a different order. Their PCMReader objects will be expected to reorder channels and set a ChannelMask matching this convention. And, their from_pcm() classmethods will be expected to reverse the process.
A ChannelMask of 0 is “undefined”, which means that channels aren’t assigned to any speaker. This is an ugly last resort for handling formats where multi-channel assignments aren’t properly defined. In this case, a from_pcm() classmethod is free to assign the undefined channels any way it likes, and is under no obligation to keep them undefined when passing back out to to_pcm()
Returns True if this mask is defined.
Returns True if this mask is undefined.
Returns the speakers this mask contains as a list of strings in the order they appear in the PCM stream.
Given a channel name string, returns the index of that channel within the PCM stream. For example:
>>> mask = ChannelMask(0xB) #fL, fR, LFE, but no fC
>>> mask.index("low_frequency")
2
Takes channel names as function arguments and returns a ChannelMask object.
>>> mask = ChannelMask.from_fields(front_right=True,
... front_left=True,
... front_center=True)
>>> int(mask)
7
Takes a channel count integer and returns a ChannelMask object.
Warning
from_channels() only works for 1 and 2 channel counts and is meant purely as a convenience method for mono or stereo streams. All other values will trigger a ValueError
Given a audiotools.musicbrainz.DiscID and audiotools.freedb.DiscID, returns a metadata[c][t] list of lists where c is a possible choice and t is the MetaData for a given track (starting from 0).
This will always return a list of MetaData objects for at least one choice. In the event that no matches for the CD can be found, those objects will only contain track_number and track_total fields.
Given a cdio.CDDAReader object, returns metadata[c][t] list of lists where c is a possible choice and t is the MetaData for a given track (starting from 0).
This will always return a list of MetaData objects for at least one choice. In the event that no matches for the CD can be found, those objects will only contain track_number and track_total fields.
Given a sorted list of AudioFile objects, returns metadata[c][t] list of lists where c is a possible choice and t is the MetaData for a given track (starting from 0).
This will always return a list of MetaData objects for at least one choice. In the event that no matches for the CD can be found, those objects will only contain track_number and track_total fields.
Given a Sheet object, total number of PCM frames and the disc’s sample rate, returns metadata[c][t] list of lists where c is a possible choice and t is the MetaData for a given track (starting from 0).
This will always return a list of MetaData objects for at least one choice. In the event that no matches for the CD can be found, those objects will only contain track_number and track_total fields.
Given a list of AudioFile objects sorted by track number, returns a {track_number:[(confidence, checksum, alt), ...], ...} dict of values retrieved from the AccurateRip database where track_number is an int starting from 1, confidence is the number of people with the same people with a matching checksum of the track.
May return a dict of empty lists if no AccurateRip entry is found.
May return urllib2.HTTPError if an error occurs querying the server.
Given a Sheet object, total number of PCM frames and sample rate, returns a {track_number:[(confidence, checksum, alt), ...], ...} dict of values retrieved from the AccurateRip database where track_number is an int starting from 1, confidence is the number of people with the same people with a matching checksum of the track.
May return a dict of empty lists if no AccurateRip entry is found.
May return urllib2.HTTPError if an error occurs querying the server.
These objects represent a CDDA layout such as provided by a .cue or .toc file. This can be used to recreate the exact layout of the disc when burning a set of tracks back to CD.
sheet_tracks is a list of SheetTrack objects, one per track on the CD. metadata is a MetaData object or None
Returns the number of tracks in the sheet.
Given a track index (starting from 0), returns a SheetTrack object. Raises IndexError if the track cannot be found.
Returns a list of all track numbers in the sheet.
Given a track number (often starting from 1), returns a SheetTrack object with that number. Raises KeyError if the track cannot be found.
Returns the disc’s pre-gap (the amount of empty samples before the first track) as a Fraction number of seconds. This number is often zero.
Given a track number (often starting from 1), returns the offset to that track as a Fraction number of seconds.
May raise KeyError if the track cannot be found.
Given a track number (often starting from 1), returns the length of that track as a Fraction number of seconds.
May return None if the track is to use the remainder of the samples in the stream. This is typical of the last track in an album.
May raise KeyError if the track cannot be found.
These objects represent a track on a given cuesheet.
argument | type | value |
number | int | track number, starting from 1 |
track_indexes | [SheetIndex] | list of SheetIndex objects |
metadata | MetaData | track’s metadata, or None |
filename | unicode | track’s filename on disc |
is_audio | boolean | whether track contains audio data |
pre_emphasis | boolean | whether track has pre-emphasis |
copy_permitted | boolean | whether copying is permitted |
Given a SheetTrack-compatible object, returns a SheetTrack.
Returns the number of SheetIndex objects in the track.
Given an index (starting from 0), returns a track’s SheetIndex object. Raises IndexError if the index cannot be found.
Returns a list of all index numbers in the track.
Given an index number (often starting from 1), returns a track’s SheetIndex object. Raises KeyError if the index is not present.
Returns the track’s number, typically starting from 1.
Returns the track’s metadata such as ISRC and CD-TEXT information as a MetaData object. May return None if it has no metadata.
Returns the track’s filename as a Unicode string.
Returns whether the track contains audio data.
Returns whether the track has pre-emphasis.
Returns whether copying is permitted.
number is the number of the index in the track, often starting from 1. A number of 0 indicates a pre-gap index. offset is the index’s offset from the start of the stream as a Fraction number of seconds.
Returns the track’s index as an integer.
Returns the index point’s offset from the start of the stream as a Fraction number of seconds.
This class is used to access a DVD-Audio. It contains a collection of titlesets. Each titleset contains a list of audiotools.dvda.DVDATitle objects, and each audiotools.dvda.DVDATitle contains a list of audiotools.dvda.DVDATrack objects. audio_ts_path is the path to the DVD-Audio’s AUDIO_TS directory, such as /media/cdrom/AUDIO_TS. device is the path to the DVD-Audio’s mount device, such as /dev/cdrom.
For example, to access the 3rd DVDATrack object of the 2nd DVDATitle of the first titleset, one can simply perform the following:
>>> track = DVDAudio(path)[0][1][2]
Note
If device is indicated and the AUDIO_TS directory contains a DVDAUDIO.MKB file, unprotection will be performed automatically if supported on the user’s platform. Otherwise, the files are assumed to be unprotected.
This is a class for executing multiple Python functions in parallel across multiple CPUs.
Queues a Python function, list of arguments and optional dictionary of keyword arguments.
Executes all queued Python functions, running max_processes number of functions at a time until the entire queue is empty. This operates by forking a new subprocess per function, executing that function and then, regardless of the function’s result, the child job performs an unconditional exit.
This means that any side effects of executed functions have no effect on ExecQueue’s caller besides those which modify files on disk (encoding an audio file, for example).
This is a class for executing multiple Python functions in parallel across multiple CPUs and receiving results from those functions.
Queues a Python function, list of arguments and optional dictionary of keyword arguments.
Executes all queued Python functions, running max_processes number of functions at a time until the entire queue is empty. Returns an iterator of the returned values of those functions. This operates by forking a new subprocess per function with a pipe between them, executing that function in the child process and then transferring the resulting pickled object back to the parent before performing an unconditional exit.
Queued functions that raise an exception or otherwise exit uncleanly yield None. Likewise, any side effects of the called function have no effect on ExecQueue’s caller.
This class runs multiple jobs in parallel and displays their progress output to the given Messenger object.
Queues a Python function for execution. This function is passed the optional args and kwargs arguments upon execution. However, this function is also passed an additional progress keyword argument which is a function that takes the current progress value as a Fraction object between 0 and 1, inclusive. The executed function can then call that progress function at regular intervals to indicate its progress.
If given, progress_text is a Unicode string to be displayed while the function is being executed.
completion_output is displayed once the executed function is completed. It can be either a Unicode string or a function whose argument is the returned result of the executed function and which must output either a Unicode string or None. If None, no output text is generated for the completed job.
Executes all the queued functions, running max_processes number of functions at a time until the entire queue is empty. Returns the results of the called functions in the order in which they were added for execution. This operates by forking a new subprocess per function in which the running progress and function output are piped to the parent for display to the screen.
If an exception occurs in one of the subprocesses, that exception will be raised by ExecProgressQueue.run() and all the running jobs will be terminated.
>>> def progress_function(progress, filename):
... # perform work here
... progress(Fraction(current, total))
... # more work
... result.a = a
... result.b = b
... result.c = c
... return result
...
>>> def format_result(result):
... return u"%s %s %s" % (result.a, result.b, result.c)
...
>>> queue = ExecProgressQueue(ProgressDisplay(Messenger("executable")))
>>> queue.execute(function=progress_function,
... progress_text=u"%s progress" % (filename1),
... completion_output=format_result,
... filename=filename1)
...
>>> queue.execute(function=progress_function,
... progress_text=u"%s progress" % (filename2),
... completion_output=format_result,
... filename=filename2)
...
>>> queue.run()
This is a helper class for displaying program data, analogous to a primitive logging facility. If silent is True, the output methods will not actually display any output to the screen.
Outputs Unicode string to stdout and adds a newline, unless verbosity level is "silent".
Output Unicode string to stdout and flushes output so it is displayed, but does not add a newline. Does nothing if verbosity level is "silent".
Outputs Unicode string to stdout and adds a newline, unless verbosity level is "silent".
Output Unicode string to stdout and flushes output so it is displayed, but does not add a newline. Does nothing if verbosity level is "silent".
Note
What’s the difference between Messenger.output() and Messenger.info()? Messenger.output() is for a program’s primary data. Messenger.info() is for incidental information. For example, trackinfo uses Messenger.output() for what it displays since that output is its primary function. But track2track uses Messenger.info() for its lines of progress since its primary function is converting audio and tty output is purely incidental.
Outputs warning text, Unicode string and a newline to stderr, unless verbosity level is "silent".
>>> m = audiotools.Messenger()
>>> m.warning(u"Watch Out!")
*** Warning: Watch Out!
Outputs error text, Unicode string and a newline to stderr.
>>> m.error(u"Fatal Error!")
*** Error: Fatal Error!
Given an OSError object, displays it as a properly formatted error message with an appended newline.
Note
This is necessary because of the way OSError handles its embedded filename string. Using this method ensures that filename is properly encoded when displayed. Otherwise, there’s a good chance that non-ASCII filenames will be garbled.
Returns True if the output method sends to a TTY rather than a file.
Returns True if the info method sends to a TTY rather than a file.
Returns True if the error method sends to a TTY rather than a file.
Generates a ANSI escape codes to clear the current line.
This works only if stdout is a TTY, otherwise is does nothing.
>>> msg = Messenger()
>>> msg.partial_output(u"working")
>>> time.sleep(1)
>>> msg.ansi_clearline()
>>> msg.output(u"done")
Moves the cursor upwards by the given number of lines.
Clears all the output below the current line. This is typically used in conjunction with Messenger.ansi_uplines().
>>> msg = Messenger()
>>> msg.output(u"line 1")
>>> msg.output(u"line 2")
>>> msg.output(u"line 3")
>>> msg.output(u"line 4")
>>> time.sleep(2)
>>> msg.ansi_uplines(4)
>>> msg.ansi_cleardown()
>>> msg.output(u"done")
Given a file descriptor integer, or file object with a fileno() method, returns the size of the current terminal as a (height, width) tuple of integers.
This is a class for displaying incremental progress updates to the screen. It takes a Messenger object which is used for generating output. Whether or not sys.stdout is a TTY determines how this class operates. If a TTY is detected, screen updates are performed incrementally with individual rows generated and refreshed as needed using ANSI escape sequences such that the user’s screen need not scroll. If a TTY is not detected, most progress output is omitted.
output_line is a Unicode string indicating what we’re displaying the progress of. Returns a ProgressRow object which can be updated with the current progress for display.
Removes the given row index and frees the slot for reuse.
Outputs the current state of all progress rows.
Clears all previously displayed output rows, if any.
This is used by ProgressDisplay and its subclasses for actual output generation. progress_display is a parent ProgressDisplay object. row_index is this row’s index on the screen. output_line is a unicode string. It is not typically instantiated directly.
Updates the current progress as a Fraction between 0 and 1, inclusive.
Indicate output is finished and the row will no longer be needed.
Returns the output line and its current progress as a Unicode string, formatted to the given width in onscreen characters. Screen width can be determined from the Messenger.terminal_size() method.
This is a subclass of ProgressDisplay used for generating only a single line of progress output. As such, one only specifies a single row of Unicode progress_text at initialization time and can avoid the row management functions entirely.
Updates the status of our output row with the current progress, which is a Fraction between 0 and 1, inclusive.
This is another ProgressDisplay subclass optimized for the display of ReplayGain application progress. messenger is a Messenger object and lossless_replay_gain is a boolean indicating whether ReplayGain is being applied losslessly or not (which can be determined from the AudioFile.lossless_replay_gain() classmethod). Whether or not sys.stdout is a TTY determines how this class behaves.
If operating on a TTY, this does nothing since progress output will be displayed. Otherwise, this indicates that ReplayGain application has begun.
Updates the status of ReplayGain application with the current progress which is a Fraction between 0 and 1, inclusive.
If operating on a TTY, this indicates that ReplayGain application is complete. Otherwise, this does nothing.
>>> rg_progress = ReplayGainProgressDisplay(messenger, AudioType.lossless_replay_gain())
>>> rg_progress.initial_message()
>>> AudioType.add_replay_gain(filename_list, rg_progress.update)
>>> rg_Progress.final_message()
This class is for displaying portions of a Unicode string to the screen and applying formatting such as color via ANSI escape sequences.
The reason this is needed is because not all Unicode characters are the same width when displayed to the screen. So, for example, if one wishes to display a portion of a Unicode string to a screen that’s 80 ASCII characters wide, one can’t simply perform:
>>> messenger.output(unicode_string[0:80])
since some of those Unicode characters might be double width, which would cause the string to wrap.
unicode_string is the text to display. fg_color and bg_color may be one of "black", "red", "green", "yellow", "blue", "magenta", "cyan", or "white". style may be one of "bold", "underline", "blink" or "inverse".
Returns the raw Unicode string.
Returns the width of the text in displayed characters.
Returns the foreground color as a string, or None.
Returns the background color as a string, or None.
Returns the style as a string, or None.
Returns a new output_text object with the given styles.
If formatting is present and is_tty is True, returns a Unicode string with ANSI escape sequences applied. Otherwise, returns the Unicode string with no ANSI formatting.
Returns a new output_text object that’s been truncated up to the given number of display characters, but may return less.
>>> s = u"".join(map(unichr, range(0x30a1, 0x30a1+25)))
>>> len(s)
25
>>> u = unicode(output_text(s).head(40))
>>> len(u)
20
>>> print repr(u)
u'\u30a1\u30a2\u30a3\u30a4\u30a5\u30a6\u30a7\u30a8\u30a9\u30aa\u30ab\u30ac\u30ad\u30ae\u30af\u30b0\u30b1\u30b2\u30b3\u30b4'
Note
Because some characters are double-width, this method along with output_text.tail() and output_text.split() may not return strings that are the same length as requested if the dividing point in the middle of a character.
Returns a new output_text object that’s been truncated up to the given number of display characters.
>>> s = u"".join(map(unichr, range(0x30a1, 0x30a1+25)))
>>> len(s)
25
>>> u = unicode(output_text(s).tail(40))
>>> len(u)
20
>>> print repr(u)
u'\u30a6\u30a7\u30a8\u30a9\u30aa\u30ab\u30ac\u30ad\u30ae\u30af\u30b0\u30b1\u30b2\u30b3\u30b4\u30b5\u30b6\u30b7\u30b8\u30b9'
Returns a tuple of output_text objects. The first is up to display_characters wide, while the second contains the remainder.
>>> s = u"".join(map(unichr, range(0x30a1, 0x30a1+25)))
>>> (head, tail) = display_unicode(s).split(40)
>>> print repr(unicode(head))
u'\u30a1\u30a2\u30a3\u30a4\u30a5\u30a6\u30a7\u30a8\u30a9\u30aa\u30ab\u30ac\u30ad\u30ae\u30af\u30b0\u30b1\u30b2\u30b3\u30b4'
>>> print repr(unicode(tail))
u'\u30b5\u30b6\u30b7\u30b8\u30b9'
Given an iterable collection of output_text objects, returns an output_list joined by our formatted text.
output_list is an output_text subclass for formatting multiple output_text objects as a unit.
output_texts is an iterable collection of output_text or unicode objects. fg_color and bg_color may be one of "black", "red", "green", "yellow", "blue", "magenta", "cyan", or "white". style may be one of "bold", "underline", "blink" or "inverse".
Warning
Formatting is unlikely to nest properly since ANSI is un-escaped to the terminal default. Therefore, if the output_list has formatting, its contained output_text objects should not have formatting. Or if the output_text objects do have formatting, the output_list container should not have formatting.
Returns the foreground color as a string, or None.
Returns the background color as a string, or None.
Returns the style as a string, or None.
Returns a new output_list object with the given formatting.
If formatting is present and is_tty is True, returns a Unicode string with ANSI escape sequences applied. Otherwise, returns the Unicode string with no ANSI formatting.
Returns a new output_list object that’s been truncated up to the given number of display characters, but may return less.
Returns a new output_list object that’s been truncated up to the given number of display characters.
Returns a tuple of output_text objects. The first is up to display_characters wide, while the second contains the remainder.
Given an iterable collection of output_text objects, returns an output_list joined by our formatted text.
output_table is for formatting text into rows and columns.
Adds new row to table and returns output_table_row object which columns may be added to.
Adds empty row to table whose columns will be blank.
Takes a list of Unicode characters, one per column, and generates a row which will expand those characters as needed to fill each column.
Yields one formatted Unicode string per row. If is_tty is True, rows may contain ANSI escape sequences for color and style.
output_table_row is a container for table columns and is returned from output_table.row() rather than instantiated directly.
Returns the total number of columns in the table.
Adds text, which may be a Unicode string or output_text object. alignment may be "left", "center" or "right". If colspan is greater than 1, the column is widened to span that many other non-spanning columns.
Returns the width of the given column in printable characters.
Given a list of column widths, returns the table row as a Unicode string such that each column is padded to the corresponding width depending on its alignment. If is_tty is True, columns may contain ANSI escape sequences for color and style.
Raised by filename_to_type() if the file’s suffix is unknown.
Raised by filename_to_type() if the file’s suffix applies to more than one audio class.
Raised by PCMReader‘s .close() method if a helper subprocess exits with an error, typically indicating a problem decoding the file.
Raised by open_files() if the same file is included more than once and no_duplicates is indicated.
Raised by audiotools.ui.process_output_options() if the same output file is generated more than once.
Raised by AudioFile.from_pcm() and AudioFile.convert() if an error occurs when encoding an input file. This includes errors from the input stream, a problem writing the output file in the given location, or EncodingError subclasses such as UnsupportedBitsPerSample if the input stream is formatted in a way the output class does not support.
Raised by AudioFile.__init__() if the file is invalid in some way.
Raised by AudioFile.track_name() if the format string contains broken fields.
Raised by Image.new() if the image cannot be parsed correctly.
Raised by process_output_options() if an output file is the same as any of the input files.
A parent exception of audiotools.cue.CueException and audiotools.toc.TOCException, to be raised by read_sheet() if a .toc or .cue file is unable to be parsed correctly.
Subclass of EncodingError, indicating the input stream’s bits-per-sample is not supported by the output class.
Subclass of EncodingError, indicating the input stream’s channel count is not supported by the output class.
Subclass of EncodingError, indicating the input stream’s channel mask is not supported by the output class.
Raised by open() if the given file is not something identifiable, or we do not have the installed binaries to support.
Raised by AudioFile.track_name() if a track name field is not supported.