Wikia

Music Player Daemon Community Wiki

GenericDecoder

Talk0
514pages on
this wiki


Generic Decoders Edit

Generic decoder support is an input plugin that allows to call external programs to decode a file or a stream. Since internally files are handled like streams, such a program is expected to read compressed audio data from stdin and send decoded raw PCM output to stdout. The current version of the patch agains MPD can be found at http://lug-owl.de/~jbglaw/mpd/mpd-latest.diff .

Generic Decoder configuration Edit

To call such an external decoder, a new configuration block must be added to mpd.conf, mpd's configuration file, describing the file extension of MIME type of the input audio format, as well as the location of the program and the type of generated raw PCM format.

Each generic decoder is configured with one generic_decoder section in mpd.conf. You have to configure three or four values:

  • suffix and/or mime_type
  • pcm_format
  • program

At least one of suffix and mime_type must be supplied. pcm_format is something like "44100:16:2" for two channel PCM output at 44100Hz with 16bits per sample. The program will be called to decode the stream. It is suggested to not directly call the program, but to wrap it with a script. That way, you can decode different audio types with one central script.

The external program will be called with two arguments, like this:

my_decoder streamrawdecode "suffix_or_mimetype"

For example, when called to decode a HTTP based MP3 stream:

my_decoder streamrawdecode audio/mpeg

Examples for mpd.conf Edit

generic_decoder {
        mime_type       "audio/mpeg"
        suffix          "mp3"
        pcm_format      "44100:16:2"
        program         "/home/jbglaw/src/mpd/scripts/mudo"
}

Example script Edit

The mpd source package contains a script, ./scripts/mudo, that's compatible to be called as an external decoder. It already contains a number of examples to call different external decoders.

Generic Tagreader Edit

Today, a Generic Decoder isn't capable of returning tag information (like interpreter, track number, song title, album title, ...). In the case of local accessible files, a generic tagreading program can be called to read one tag at a time from an audio file.

Each generic tagreader is configured with one generic_tagreader section in mpd.conf. You have to configure three or two values:

  • suffix
  • program

suffix is the file extension, program is the program to be called.

All external tagreading programs are called with four arguments:

external_tagreader gettag tagname filetype filename

For example, when called to read the title tag from a MP3 file:

exernal_tagreader gettag title mp3 /path/to/song.mp3

Following tags are known:

  • artist
  • album
  • title
  • track
  • name
  • genre
  • date
  • composer
  • performer
  • comment
  • disc
  • time

For the time tag, the song's playtime in integral decimal seconds is expected.

Examples for mpd.conf Edit

generic_tagreader {
        suffix          "mp3"
        program         "/home/jbglaw/src/mpd/scripts/mudo"
}

Example script Edit

Again, it is recommended to have all tag reading done in one script. The mpd source distribution contains an example script in ./scripts/mudo.

mudo, an example script Edit

This is an example script to do external decoding and tag reading:

#!/usr/bin/env sh

#
# mudo (like `sudo', but working on music instead of switching users) is a 
# small wrapper script to convert or decode certain audio file types.
#
# © 2006 by Jan-Benedict Glaw <jbglaw@lug-owl.de> under the terms of the
# GNU General Public License Version 2.0.
#
# These programs are called internally and should be installed. There's no
# error checking right now, so you'd better make sure to have these installed
# or just don't work with the file types they support. Package names added
# in braces.
#
#  * lame
#  * flac and metaflac (flac)
#  * vorbis-tools
#  * twolame
#  * wavpack
#  * speex
#  * mpg321
#  * mp3info
#  * sfinfo (libaudiofile-dev)
#
# Missing sound formats:
# ~~~~~~~~~~~~~~~~~~~~~~
# Musepack (*.mpc)
# MOD (*.mod)
#
# Hints:
# ~~~~~~
#  * If you add further sound types, pay attention that you should first
#    supply -r/-s/-w/-c to sox and after that the -t raw (for streamdecode).
#    Otherwise it'll happily ignore those output format options...
#

export LANG=C
export LC_ALL=C

ACTION="${1}"
case "${ACTION}" in
        encode)
                INPUT="${2}"
                OUTPUT="${3}"
                case "${OUTPUT}" in
                        *.aac) faac "${INPUT}" -o "${OUTPUT}" ;;
                        *.flac) flac "${INPUT}" -o "${OUTPUT}" ;;
                        *.mp2) twolame "${INPUT}" "${OUTPUT}" ;;
                        *.mp3) lame "${INPUT}" "${OUTPUT}" ;;
                        *.mp4) faac "${INPUT}" -o "${OUTPUT}" ;;
                        *.ogg) oggenc "${INPUT}" -o "${OUTPUT}" ;;
                        *.spx) speexenc "${INPUT}" "${OUTPUT}" ;;
                        *.wv) wavpack "${INPUT}" -o "${OUTPUT}" ;;
                        *) echo "Unknown target file format: ${OUTPUT}" >&2
                           exit 1 ;;
                esac
                ;;

        decode)
                INPUT="${2}"
                OUTPUT="${3}"
                case "${INPUT}" in
                        *.aac) faad "${INPUT}" -o "${OUTPUT}" ;;
                        *.flac) flac -d "${INPUT}" -o "${OUTPUT}" ;;
                        *.mp2) mpg321 "${INPUT}" -w "${OUTPUT}" ;;
                        *.mp3) mpg321 "${INPUT}" -w "${OUTPUT}" ;;
                        *.mp4) flac -d "${INPUT}" -o "${OUTPUT}" ;;
                        *.ogg) oggdec "${INPUT}" -o "${OUTPUT}" ;;
                        *.spx) speexdec "${INPUT}" "${OUTPUT}" ;;
                        *.wv) wvunpack "${INPUT}" -o "${OUTPUT}" ;;
                        *) echo "Unknown source file format: ${INPUT}" >&2
                           exit 1 ;;
                esac
                ;;

        rawdecode | filerawdecode)
                TYPE="${2}"
                INPUT="${3}"
                case "${TYPE}" in
                        aac) faad -f 2 -b 1 -s 44100 "${INPUT}" -o - 2> /dev/null ;;
                        flac) flac -d "${INPUT}" --endian=little --sign=signed --force-raw-format -o - 2>/dev/null ;;
                        mp2) mpg321 "${INPUT}" -w - 2>/dev/null | sox -t wav - -r 44100 -s -w -c 2 -t raw - ;;
                        mp3) mpg321 "${INPUT}" -w - 2>/dev/null | sox -t wav - -r 44100 -s -w -c 2 -t raw - ;;
                        mp4) flac -d "${INPUT}" --endian=little --sign=signed --force-raw-format -o - 2>/dev/null ;;
                        ogg) oggdec "${INPUT}" -R -s 1 -e 0 -b 16 -o - 2>/dev/null ;;
                        spx) speexdec "${INPUT}" --rate 44100 --stereo - 2>/dev/null ;;
                        wv) wvunpack "${INPUT}" -r -o - 2>/dev/null ;;
                        *) echo "Unknown source file format: ${TYPE}" >&2
                           exit 1 ;;
                esac
                ;;

        streamrawdecode)
                TYPE="${2}"
                case "${TYPE}" in
                        #audio/mpeg | mp3) mpg321 -w - - 2>/dev/null | sox -t wav - -r 44100 -s -w -c 2 -t raw - ;;
                        audio/mpeg | mp3) mplayer -vo null -msglevel all=-1 -quiet -srate 44100 -channels 2 -ao pcm:nowaveheader:fast:file=/dev/stdout - 2>/dev/null ;;
                        audio/wav | wav) sox -t wav - -r 44100 -s -w -c 2 -t raw - ;;
                        flac) flac -d - --endian=little --sign=signed --force-raw-format -o - 2>/dev/null ;;
                        ogg) oggdec - -R -s 1 -e 0 -b 16 -o - 2>/dev/null ;;
                        *) echo "Unknown MIME type ${2}" >&2
                           exit 1 ;;
                esac ;;

        gettag)
                TAGNAME="${2}"
                TYPE="${3}"
                INPUT="${4}"
                case "${TYPE}" in
                        aac) :;;
                        flac) case "${TAGNAME}" in
                                time) SAMPLES="`metaflac --show-total-samples "${INPUT}" 2>/dev/null`"
                                      RATE="`metaflac --show-sample-rate "${INPUT}" 2>/dev/null`"
                                      echo $(( ${SAMPLES} / ${RATE} )) 2>/dev/null;;
                                album | artist | title | track | name)
                                        metaflac --show-tag="${TAGNAME}" "${INPUT}" ;;
                                *) exit 1 ;;
                                esac ;;
                        mp2) :;;
                        mp3) case "${TAGNAME}" in
                                album) mp3info -p '%l' "${INPUT}" ;;
                                artist) mp3info -p '%a' "${INPUT}" ;;
                                title) mp3info -p '%t' "${INPUT}" ;;
                                track) mp3info -p '%n' "${INPUT}" ;;
                                name) :;;
                                time) mp3info -p '%S' "${INPUT}" ;;
                                *) exit 1 ;;
                             esac ;;
                        ogg) :;;
                        mp4) :;;
                        spx) :;;
                        wav) case "${TAGNAME}" in
                                time) sfinfo "${4}" | awk '/^Duration / {print $2}' ;;
                                *) exit 1 ;;
                             esac ;;
                        wv) :;;
                        *) echo "Unknown source file format: ${TYPE}" >&2
                           exit 1;;
                esac ;;

        play)
                :;;

        *)
                echo "$0 encode <inputfile.wav> <outputfile>" >&2
                echo "$0 decode <inputfile> <outputfile.wav>" >&2
                echo "$0 filerawdecode <filetype> <inputfile>" >&2
                echo "$0 streamrawdecode <file_or_mime_type>" >&2
                echo "$0 gettag <tagname> <filetype> <inputfile>" >&2
                exit 1 ;;
esac
Advertisement | Your ad here

Around Wikia's network

Random Wiki