Extending doubleTwist's device support

 
Note: if you are looking for source code, please see the Source Code page.

Overview


doubleTwist has the ability to customize the way in which it interacts with devices. Most of the knowledge about a device is declared in an external XML file. These external XML files contain "device declarations" and allow customization of device identification, the folders to which media is synced, folders to search when browsing media, decoder capabilities, and encoder settings.

A "catch-all" device declaration exists to provide base support for any device that isn't explicitly identified and customized by other device declarations. It is limited to audio support and defines the following behavior:

  • The entire file system of the largest storage card is searched for media when browsing the device in doubleTwist.
  • MP3 and M4A/AAC files can by synced to the device without incurring a transcode (bitrate: 20 - 320 kb/s, 1 or 2 channels).
  • Audio files that require transcoding will be transcoded to mp3 at 128 kb/s, 2 channels.
  • Video and photos are not supported.
Note that not all interaction with a device is customizable. Most notably, the way in which playlists are written to a device is something that cannot be changed. The storage card used in the sync process also cannot be customized: the card with the largest capacity is used.

Benefits


The primary reason to define a device declaration is to add video and photo support for a device. Unlike audio, there is no industry standard video encoding for portable media devices today. Resolution capabilities can also vary greatly from device to device. For this reason, the catch-all device declaration does not provide support for video and photos. Creating a device declaration for a specific device or class of devices can enable doubleTwist to sync video and photos accordingly.

Another reason to define a device declaration is to realize gains in browsing efficiency, sync efficiency, and media quality. For example, rather than searching a device's entire file system for media when browsing, a set of sub-folders can be specified to limit the search. When syncing media to a device, if the device is known to support formats other than mp3, alternative decoders can be specified to avoid unnecessary transcoding. Lastly, alternative encode settings can be specified to transcode media into a format better suited for a particular device.

Distribution


On Windows, device declaration files live in a folder called "Devices" under the install folder of the application, which is typically C:\Program Files\doubleTwist.

On Mac OS X, device declaration files live in the folder ~/Library/Application Support/doubleTwist/DeviceAdapters.

Any file in these folders with an extension of ".xml" will be treated as a device declaration file and parsed when the application launches, which allows for device declarations to be made across multiple XML files. If there are user-generated device declarations that conflict with doubleTwist's declarations for a given device then the user-generated ones will take precedence.

Implementation


  • Identifying a device

  • A device can be identified by its manufacturer name, model name, and/or USB identifier (VID/PID). A device declaration contains zero or more device identifiers. If any device identifier succeeds then the device declaration is considered to be a match for the device (much like an OR operation). All match conditions within a single device identifier (manufacturer, model, USB ID) must be satisfied in order to succeed (much like an AND operation). Strings representing names and identifiers are regular expressions, which allows for considerable flexibility when defining match criteria. No manipulation is done on strings that come from devices, so case-insensitive comparisons have to be accomplished via regular expressions.

  • Specifying sync folders

  • A device declaration must define where media files will be copied during the sync process. Different folders can be specified for audio, video, and photo file types. If the folder does not exist on the device, it will be created on the first sync operation. The "catch-all" device declaration copies audio files to a folder called Music under the root folder of the device ("/Music"). Within the audio sync folder, doubleTwist will organize music into sub-folders by album and artist, if that metadata is available.

  • Specifying additional browse folders

  • When a device is selected, doubleTwist searches a set of folders for media. Sync folders are automatically included in the search. Additional folders can be specified to broaden the search, if desired. For example, many devices have dedicated folders for video, audio, and photos.

  • Specifying decoder capabilities

  • A device can be capable of decoding multiple encoding types. Specifying what decoders are available and their constraints will allow doubleTwist to sync files that are compatible with the device without transcoding them first. By avoiding the transcode step, the sync will go faster and the quality of the media will not degrade. Specifiable decoder constraints are file format, encoding scheme, bit rate, sample rate, sample size, and number of channels.

  • Specifying encoder parameters

  • During the sync process, if doubleTwist determines that a file is not compatible with the device then it will use the encode parameters found in the matching device declaration to determine how to transcode the file before copying it over. Only one set of encode parameters for each media type (audio / video / photo) is allowed within a device declaration.

  • Overriding doubleTwist device declarations

  • There is one parameter within a device declaration that is relevant only when overriding an existing doubleTwist device declaration. The parameter is the OperationSystem parameter, which is used within a device identifier. Currently, there are only two possible values generated by a device: an empty string and "Windows Mobile". Any Windows Mobile device should match the latter value. All others will return an empty string.

    On Windows, support for the Sony PSP does not come from device declaration files and, therefore, cannot be customized at this time.

Reference


Value types

The device declaration XML parser expects leaf nodes to be of predetermined types. Allowable types are as follows:

  • integer
  • float
  • string
  • regular_expression: a regular expression.
  • folder_path: a string representing a folder on the device. The separation character is '/'. Example: "/mobile/Music".
  • frame_rate: float or "ntsc" or "pal"
  • file_format: enum (mp4, asf, avi, divx, flv, mpg, wav, psp, 3gp, jpg, gif, png, bmp)
  • video_encoding: enum (mp4, h263, h264, wmv7, wmv8, wmv9, vc1, dv, mpg1, mpg2, h263spark, vp6, xvid)
  • audio_encoding: enum (amrnb, amrwb, aac, mp3, wma1, wma2, dv, pcm)
  • image_encoding: enum (jpg, bmp, gif, png)
  • list_of_ranges: specifies a list of ranges for the given type. v1[:v1End],v2[:v2End],...,vN[:vNEnd]. This type is used by decoder declarations when specifying constraints. Example integer list_of_ranges: 2,5,7:11,23,100:200
XML structure

Devices
type: parent_node
description: This is the root node. It contains a list of Device nodes.

Devices/Device
type: parent_node
description: A device declaration

Devices/Device/Name
type: string
description: The user-friendly name presented within doubleTwist for the device. If this node is not defined then the name will come from the device itself.

Devices/Device/Identifiers
type: parent_node
description: Contains a list of Identifier nodes.

Devices/Device/Identifiers/Identifier
type: parent_node
description: Specifies the conditions for matching this device declaration to a device.

Devices/Device/Identifiers/Identifier/UsbVid
type: string
description: The USB VID identifier for the device

Devices/Device/Identifiers/Identifier/UsbPid
type: string
description: The USB PID identifier for the device

Devices/Device/Identifiers/Identifier/Manufacturer
type: regular_expression
description: Matched against the manufacturer name reported by the device.

Devices/Device/Identifiers/Identifier/Model
type: regular_expression
description: Matched against the model name reported by the device.

Devices/Device/Identifiers/Identifier/OperatingSystem
type: regular_expression
description: Empty string or Windows Mobile. Only relevant when overriding doubleTwist's Windows Mobile device declaration.

Devices/Device/MusicFolder
type: folder_path
description: The folder to which audio files are copied during a sync operation.

Devices/Device/ImageFolder
type: folder_path
description: The folder to which image files are copied during a sync operation.

Devices/Device/VideoFolder
type: folder_path
description: The folder to which video files are copied during a sync operation.

Devices/Device/BrowseFolders
type: parent_node
description: Contains a list of Folder nodes.

Devices/Device/BrowseFolders/Folder
type: folder_path
description: Specifies an additional folder to search for media when browsing a device in doubleTwist.

Devices/Device/Decoders
type: parent_node
description: Contains a list of Decoder nodes.

Devices/Device/Decoders/Decoder
type: parent_node
description: Specifies capabilities and constraints for a given decoder on the device.

Devices/Device/Decoders/Decoder/FileFormat
type: file_format
description: The file format supported by this decoder.

Devices/Device/Decoders/Decoder/Audio
type: parent_node
description: Specifies audio constraints for this decoder.

Devices/Device/Decoders/Decoder/Audio/Encoding
type: audio_encoding
description: Specifies the audio encoding supported by this decoder.

Devices/Device/Decoders/Decoder/Audio/Bitrate
type: integer list_of_ranges
description: Specifies, in bits per second, the minimum and maximum bitrates.

Devices/Device/Decoders/Decoder/Audio/SampleRate
type: integer list_of_ranges
description: Specifies, in samples per second, the minimum and maximum sample rates.

Devices/Device/Decoders/Decoder/Audio/Channels
type: integer list_of_ranges
description: Specifies the number of channels supported. Valid values are 1 and 2.

Devices/Device/Decoders/Decoder/Video
type: parent_node
description: Specifies video constraints for this decoder.

Devices/Device/Decoders/Decoder/Video/Encoding
type: video_encoding
description: Specifies the video encoding supported by this decoder.

Devices/Device/Decoders/Decoder/Video/Width
type: integer list_of_ranges
description: Specifies the range of frame widths supported by this decoder.

Devices/Device/Decoders/Decoder/Video/Height
type: integer list_of_ranges
description: Specifies the range of frame heights supported by this decoder.

Devices/Device/Decoders/Decoder/Video/FrameRate
type: frame_rate list_of_ranges
description: Specifies, in frames per second, the range of frame rates supported by this decoder.

Devices/Device/Decoders/Decoder/Video/Bitrate
type: integer list_of_ranges
description: Specifies, in bits per second, the maximum bitrate supported by the decoder. Note that the actual peak bitrate is usually not available for a given video file. Instead, the average bitrate is used as an approximation when comparing against this constraint.

Devices/Device/Decoders/Decoder/Video/Profile
type: integer list_of_ranges
description: Specifies the profiles supported by the decoder. The meaning of this value depends on the encoding and is commonly specific to MPEG.

Devices/Device/Decoders/Decoder/Video/Level
type: integer list_of_ranges
description: Specifies the levels supported by the decoder. The meaning of this value depends on the encoding and is commonly specific to MPEG.

Devices/Device/Decoders/Decoder/Image
type: parent_node
description: Specifies image constraints for this decoder.

Devices/Device/Decoders/Decoder/Image/Encoding
type: image_encoding
description: Specifies the image encoding supported by this decoder.

Devices/Device/Decoders/Decoder/Image/Width
type: integer list_of_ranges
description: Specifies the range of frame widths supported by this decoder.

Devices/Device/Decoders/Decoder/Image/Height
type: integer list_of_ranges
description: Specifies the range of frame heights supported by this decoder.

Devices/Device/AudioEncodeProfile
type: parent_node
description: Specifies encode settings when transcoding audio for this device.

Devices/Device/VideoEncodeProfile
type: parent_node
description: Specifies encode settings when transcoding video for this device.

Devices/Device/ImageEncodeProfile
type: parent_node
description: Specifies encode settings when transcoding images for this device.

{parent_node}/EncodeProfile
type: parent_node
description: Common node type among audio, video, and image encode profiles.

{parent_node}/EncodeProfile/FileFormat
type: file_format
description: Target file format.

{parent_node}/EncodeProfile/Audio
type: parent_node
description: Specifies audio encode settings.

{parent_node}/EncodeProfile/Audio/Encoding
type: audio_encoding
description: Target encoding.

{parent_node}/EncodeProfile/Audio/Bitrate
type: integer
description: Specifies, in bits per second, the target bitrate.

{parent_node}/EncodeProfile/Audio/SampleRate
type: integer
description: Specifies, in samples per second, the target sample rate.

{parent_node}/EncodeProfile/Audio/Channels
type: integer
description: Specifies number of channels. Valid values are 1 and 2.

{parent_node}/EncodeProfile/Video
type: parent_node
description: Specifies video encode settings.

{parent_node}/EncodeProfile/Video/Encoding
type: video_encoding
description: Target encoding.

{parent_node}/EncodeProfile/Video/Width
type: integer
description: Video frame width

{parent_node}/EncodeProfile/Video/Height
type: integer
description: Video frame height

{parent_node}/EncodeProfile/Video/AverageBitrate
type: integer
description: Average bitrate

{parent_node}/EncodeProfile/Video/MaxBitrate
type: integer
description: Max bitrate

{parent_node}/EncodeProfile/Video/FrameRate
type: frame_rate
description: Frame rate

{parent_node}/EncodeProfile/Video/VbvBufferSize
type: integer
description: VBV buffer size

{parent_node}/EncodeProfile/Video/MinQuantizerScale
type: integer
description: Minimum quantizer scale

{parent_node}/EncodeProfile/Video/MaxQuantizerScale
type: integer
description: Maximum quantizer scale

{parent_node}/EncodeProfile/Video/GopSize
type: integer
description: Group of pictures size

{parent_node}/EncodeProfile/Video/RequiresAccompanyingAudio
type: bool
description: Set to true if a decoder requires audio to be present with a video stream. When true and no audio is present then doubleTwist will insert silent audio.

{parent_node}/EncodeProfile/Video/RenderPadding
type: bool
description: Set to true to use left/right or top/bottom black bars to maintain aspect ratio. If false, an aspect ratio flag may be used instead.

{parent_node}/EncodeProfile/Image
type: parent_node
description: Specifies image encode settings.

{parent_node}/EncodeProfile/Image/Encoding
type: video_encoding
description: Target encoding.

{parent_node}/EncodeProfile/Image/Width
type: integer
description: Image frame width

{parent_node}/EncodeProfile/Image/Height
type: integer
description: Image frame height

Example


<?xml version="1.0" encoding="utf-8" ?>
<Devices>
  <Device>
    <Name>Acme</Name>
    <Identifiers>
      <Identifier>
        <Manufacturer>.*[aA][cC][mM][eE].*</Manufacturer>
        <Model>.*[pP][hH][oO][nN][eE].*</Model>
      </Identifier>
      <Identifier>
        <UsbVid>0401</UsbVid>
        <UsbPid>04AF</UsbPid>
      </Identifier>
    </Identifiers>
    <MusicFolder>/Music</MusicFolder>
    <ImageFolder>/Photos</ImageFolder>
    <VideoFolder>/Video</VideoFolder>
    <Decoders>
      <Decoder>
        <FileFormat>mp4</FileFormat>
        <Video>
          <Encoding>mp4</Encoding>
          <Width>1:320</Width>
          <Height>1:240</Height>
          <FrameRate>1:15</FrameRate>
        </Video>
        <Audio>
          <Encoding>aac</Encoding>
          <Bitrate>16000:576000</Bitrate>
          <SampleRate>8000:48000</SampleRate>
          <Channels>1,2</Channels>
        </Audio>
      </Decoder>
      <Decoder>
        <Audio>
          <Encoding>mp3</Encoding>
          <Bitrate>20000:320000</Bitrate>
          <Channels>1,2</Channels>
        </Audio>
      </Decoder>
      <Decoder>
        <Audio>
          <Encoding>aac</Encoding>
          <Bitrate>16000:576000</Bitrate>
          <SampleRate>8000:48000</SampleRate>
          <Channels>1,2</Channels>
        </Audio>
      </Decoder>
      <Decoder>
        <Image>
          <Encoding>jpg</Encoding>
          <Width>1:320</Width>
          <Height>1:240</Height>
        </Image>
      </Decoder>
    </Decoders>
    <VideoEncodeProfile>
      <EncodeProfile>
        <FileFormat>mp4</FileFormat>
        <Video>
          <Encoding>mp4</Encoding>
          <Width>320</Width>
          <Height>240</Height>
          <FrameRate>15</FrameRate>
          <AverageBitrate>256000</AverageBitrate>
          <RenderPadding>1</RenderPadding>
        </Video>
        <Audio>
          <Encoding>aac</Encoding>
          <SampleRate>48000</SampleRate>
          <Bitrate>128000</Bitrate>
          <Channels>2</Channels>
        </Audio>
      </EncodeProfile>
    </VideoEncodeProfile>
    <AudioEncodeProfile>
      <EncodeProfile>
        <FileFormat>mp4</FileFormat>
        <Audio>
          <Encoding>aac</Encoding>
          <SampleRate>48000</SampleRate>
          <Bitrate>128000</Bitrate>
          <Channels>2</Channels>
        </Audio>
      </EncodeProfile>
    </AudioEncodeProfile>
    <ImageEncodeProfile>
      <EncodeProfile>
        <FileFormat>jpg</FileFormat>
        <Image>
          <Encoding>jpg</Encoding>
          <Width>320</Width>
          <Height>240</Height>
        </Image>
      </EncodeProfile>
    </ImageEncodeProfile>
  </Device>
</Devices>