Commit f679b945 authored by Alexey Rusakov's avatar Alexey Rusakov

Merge branch 'upstream' into 'alt-git'

parents 8ec10e2b 8758e977
......@@ -8,6 +8,7 @@
*.lo
*.o
.deps
.dirstamp
Makefile
Makefile.in
aclocal.m4
......@@ -37,4 +38,15 @@ tags
.stgit*
doc/protocol.html
doc/protocol
doc/user
doc/developer
doc/sticker
doc/api
test/software_volume
test/run_decoder
test/read_tags
test/run_encoder
test/run_output
test/read_conf
test/run_input
test/read_mixer
......@@ -5,31 +5,44 @@ Avuton Olrich <avuton@gmail.com>
release manager
Max Kellermann <max@duempel.org>
general
José Anarch <anarchsss@gmail.com>
JACK plugin
Patrik Weiskircher <pat@icore.at>
Stored playlist commands
lead developer
Laszlo Ashin <kodest@gmail.com>
WavPack support
Viliam Mateicka <viliam.mateicka@gmail.com>
FFmpeg support
FFmpeg support, mixer and archive API
Eric Wollesen <encoded@xmtp.net>
encoder API, shout output
Thomas Jansen <mithi@mithi.net>
multithreading tweaks, miscellaneous
Rasmus Steinke <rasi1979@googlemail.com>
documentation
Romain Bignon <romain@peerfuse.org>
playlist manipulation
David Guibert <david.guibert@gmail.com>
PulseAudio mixer
Jochen Keil <jochen.keil@gmail.com>
CUE sheet support
Jeffrey Middleton <jefromi@gmail.com>
playlist manipulation
Sean McNamara <smcnam@gmail.com>
WIN32 compatibility
Former Developers
-----------------
Warren Dukes <warren.dukes@gmail.com>
general
former lead developer and project founder
Niklas Hofer
'next' and 'previous' patch
......@@ -42,5 +55,16 @@ Guus Sliepen <guus@sliepen.eu.org>
J. Alexander Treuman <jat@spatialrift.net>
general, MP3, ID3, PulseAudio, format conversion, stored playlists
AudioCompress, much much more...
Eric Wong
former lead developer
José Anarch <anarchsss@gmail.com>
JACK plugin
Patrik Weiskircher <pat@icore.at>
Stored playlist commands
Nick Welch <mack@incise.org>
Sighandlers
......@@ -99,7 +99,7 @@ libsidplay2 - http://sidplay2.sourceforge.net/
For C64 SID support.
libfluidsynth - http://fluidsynth.resonance.org/
For MIDI support.
For MIDI support (DO NOT USE - use libwildmidi instead)
libwildmidi - http://wildmidi.sourceforge.net/
For MIDI support.
......@@ -120,6 +120,12 @@ For playing HTTP streams.
libmms - https://launchpad.net/libmms
For playing MMS streams.
SQLite - http://www.sqlite.org/
For the sticker database.
libcue - http://libcue.sourceforge.net/
For CUE sheet support.
pkg-config
----------
......
ver 0.15 - (200?/??/??)
ver 0.15 (2009/06/23)
* input:
- parse Icy-Metadata
- added support for the MMS protocol
- hide HTTP password in playlist
- lastfm: new input plugin for last.fm radio (experimental and incomplete!)
- curl: moved proxy settings to "input" block
* tags:
- support the "album artist" tag
- support MusicBrainz tags
- parse RVA2 tags in mp3 files
- parse ID3 tags in AIFF/RIFF/WAV files
- ffmpeg: support new metadata API
- ffmpeg: added support for the tags comment, genre, year
* decoders:
- audiofile: streaming support added
- audiofile: added 24 bit support
- modplug: another MOD plugin, based on libmodplug
- mikmod disabled by default, due to severe security issues in libmikmod
- sidplay: new decoder plugin for C64 SID (using libsidplay2)
- fluidsynth: new decoder plugin for MIDI files (using libfluidsynth)
- fluidsynth: new decoder plugin for MIDI files (using libfluidsynth,
experimental due to shortcomings in libfluidsynth)
- wildmidi: another decoder plugin for MIDI files (using libwildmidi)
- flac: parse stream tags
- mpcdec: support the new libmpcdec SV8 API
- added configuration option to disable decoder plugins
- flac: support embedded cuesheets
- ffmpeg: updated list of supported formats
* audio outputs:
- added option to disable audio outputs by default
- wait 10 seconds before reopening after play failure
- shout: enlarged buffer size to 32 kB
- null: allow disabling synchronization
- mvp: fall back to stereo
- mvp: fall back to 16 bit audio samples
- mvp: check for reopen errors
- mvp: fixed default device detection
- pipe: new audio output plugin which runs a command
- alsa: better period_time default value for high sample rates
- solaris: new audio output plugin for Solaris /dev/audio
- httpd: new audio output plugin for web based streaming, similar to icecast
but built in.
* commands:
- "playlistinfo" supports a range now
- "playlistinfo" and "move" supports a range now
- added "sticker database", command "sticker", which allows clients
to implement features like "song rating"
* Rewritten mixer code to support multiple mixers
to implement features like "song rating"
- added "consume" command which removes a song after play
- added "single" command, if activated, stops playback after current song or
repeats the song if "repeat" is active.
* mixers:
- rewritten mixer code to support multiple mixers
- new pulseaudio mixer
- alsa: new mixer_index option supports choosing between multiple
identically-named controls on a device.
* Add audio archive extraction support:
- bzip2
- iso9660
- zip
* the option "error_file" was removed, all messages are logged into
"log_file"
"log_file"
* support logging to syslog
* fall back to XDG music directory if no music_directory is configured
* failure to read the state file is non-fatal
......@@ -34,6 +65,17 @@ ver 0.15 - (200?/??/??)
* playlist_directory and music_directory are optional
* playlist: recalculate the queued song after random is toggled
* playlist: don't unpause on delete
* pause when all audio outputs fail to play
* daemon: ignore "user" setting if already running as that user
* listen: fix broken client IP addresses in log
* listen: bind failure on secondary address is non-fatal
* 24/32 bit audio support
* print available protocols in --version
* fill buffer after seeking
* choose the fallback resampler at runtime
* steps taken towards win32 compatibility
* require glib 2.6 or greater
* built-in documentation using doxygen and docbook
ver 0.14.2 (2009/02/13)
......
0.14
----
*) data structures
*) remove changes made to linked list for TagTracker
*) input plugins
*) add support for playing aac streams
*) Add support for 24-bit audio
*) cleanup linked list code!
*) add error codes for status->error
*) Cleanup Config File Code
*) audio output
*) allowing "pausing" of audio output devices
*) while pausing, play silence for the devices that don't support
"pausing"
*) more accurate time reporting by determining how much of audio_device
buffer has been played
*) state
*) abstract out state code from playlist.c
*) put MPD Version in statefile
*) add playlistreplace command (replace current playlist with saved playlist
and keep playing)
0.15.0
------
*) support for dynamically loading plugins
*) cleanup input plugins "API"
*) cleanup output plugins "API"
*) implement listener socket protocol as documented here:
http://mpd.wikia.com/wiki/MusicPlayerDaemonListenerProtocol
???
---
*) mixer
*) add sun support
*) add OS X support
*) audio output
*) write a nas native audioOutput
*) write a sun native audioOutput
1.0
---
*) bug fixes
post-1.0
--------
*) rewrite audio pipe
*) use pthreads/clone
*) try to constrain the use of pthread mutex's and condition's
to specific output plugins
*) use pull model for audio_output
*) threads
0) managing thread
*) receives commands
*) manages state
*) handles time/metadata sending
1) decoding thread
2) effects thread
*) crossfading
*) *command* resampling/conversions
3) audio_output thread
*) thread for each audio_output device
*) dynamic metadata
*) implement by recording the ftell positions of entries
*) buffer changes and flush them once every 60 seconds
*) buffer changes while doing an update
*) be sure to check that the metadata "header" is what we expect
before writing at the position
*) add support for:
*) last time played
*) times played
*) times skipped
*) ranking
DOCBOOK_FILES = protocol.xml
DOCBOOK_HTML = $(patsubst %.xml,%/index.html,$(DOCBOOK_FILES))
man_MANS = mpd.1 mpd.conf.5
doc_DATA = mpdconf.example
EXTRA_DIST = $(man_MANS) $(DOCBOOK_FILES) mpdconf.example
if ENABLE_DOCUMENTATION
protocoldir = $(docdir)/protocol
protocol_DATA = $(wildcard protocol/*.html)
$(DOCBOOK_HTML): %/index.html: %.xml
$(XMLTO) -o protocol --stringparam chunker.output.encoding=utf-8 html $<
api/html/index.html: doxygen.conf
$(DOXYGEN) $<
all-local: $(DOCBOOK_HTML) api/html/index.html
clean-local:
rm -rf $(patsubst %.xml,%,$(DOCBOOK_FILES))
rm -rf api
install-data-local: api/html/index.html
$(mkinstalldirs) $(DESTDIR)$(docdir)/api/html
$(INSTALL_DATA) -c -m 644 api/html/*.html api/html/*.css api/html/*.png api/html/*.gif $(DESTDIR)$(docdir)/api/html
endif
<?xml version='1.0' encoding="utf-8"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"docbook/dtd/xml/4.2/docbookx.dtd">
<book>
<title>The Music Player Daemon - Developer's Manual</title>
<chapter>
<title>Introduction</title>
<para>
This is a guide for those who wish to hack on the MPD source
code. MPD is an open project, and we are always happy about
contributions. So far, more than 50 people have contributed
patches.
</para>
<para>
This document is work in progress. Most of it may be incomplete
yet. Please help!
</para>
</chapter>
<chapter>
<title>Code Style</title>
<itemizedlist>
<listitem>
<para>
indent with tabs (width 8)
</para>
</listitem>
<listitem>
<para>
don't write CPP when you can write C: use inline functions
and enums instead of macros
</para>
</listitem>
<listitem>
<para>
the code should be C99 compliant, and must compile with
<application>GCC</application>;
<application>clang</application> support is highly desirable
</para>
</listitem>
<listitem>
<para>
C++ is ok (for integrating C++ only libraries), but it
should be avoided
</para>
</listitem>
<listitem>
<para>
Some example code:
</para>
<programlisting lang="C">static inline bool
foo(const char *abc, int xyz)
{
if (abc == NULL) {
g_warning("Foo happened!\n");
return -1;
}
return xyz;
}
</programlisting>
</listitem>
</itemizedlist>
</chapter>
<chapter>
<title>Hacking The Source</title>
<para>
Always write your code against the latest git:
</para>
<programlisting>git clone git://git.musicpd.org/master/mpd.git</programlisting>
<para>
Configure with the options <option>--enable-debug
--enable-werror</option>. Enable as many plugins as possible,
to be sure that you don't break any disabled code.
</para>
<para>
Don't mix several changes in one single patch. Create a
separate patch for every change. Tools like
<application>stgit</application> help you with that.
</para>
</chapter>
<chapter>
<title>Submitting Patches</title>
<para>
Send your patches to the mailing list:
musicpd-dev-team@lists.sourceforge.net
</para>
</chapter>
</book>
......@@ -38,7 +38,7 @@ PROJECT_NUMBER =
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
OUTPUT_DIRECTORY = api
OUTPUT_DIRECTORY = doc/api
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
......@@ -534,7 +534,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = ../src
INPUT = src
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
......
......@@ -158,28 +158,34 @@ distortions.
Linear Interpolator (4)
Linear interpolator, very fast, poor quality.
.TP
internal
Poor quality, no floating point operations. This is the default (and
only choice) if MPD was compiled without libsamplerate.
.RE
.IP
For an up-to-date list of available converters, please see the libsamplerate
documentation (available online at <\fBhttp://www.mega-nerd.com/SRC/\fP>).
.TP
.B mixer_type <alsa, oss, software or hardware>
.B mixer_type <alsa, oss, software, hardware or disabled>
This specifies which mixer to use. The default is hardware and depends on
what audio output support mpd was built with. Options alsa and oss are
legacy and should not be used in new configs, but when set mixer_device
and mixer_control will apply.
.TP
.B mixer_device <mixer dev>
This specifies which mixer to use. The default for oss is "/dev/mixer"; the
default for alsa is "default". This option is deprecated and should not be
used. Look at the mixer_device option of corresponding output device instead.
This specifies which mixer to use. The default for oss is
"/dev/mixer"; the default for alsa is "default". This global option is
deprecated and should not be used. Look at the mixer_device option of
corresponding output device instead.
.TP
.B mixer_control <mixer ctrl>
This specifies which mixer control to use (sometimes referred to as the
"device"). Examples of mixer controls are PCM, Line1, Master, etc. An example
for OSS is "Pcm", and an example for alsa is "PCM". This option is deprecated
and should not be used. Look at the mixer_control option of corresponding
output device instead.
This specifies which mixer control to use (sometimes referred to as
the "device"). Examples of mixer controls are PCM, Line1, Master,
etc. An example for OSS is "Pcm", and an example for alsa is
"PCM". This global option is deprecated and should not be used. Look
at the mixer_control option of corresponding output device instead.
.TP
.B replaygain <album or track>
If specified, mpd will adjust the volume of songs played using ReplayGain tags
......@@ -205,16 +211,8 @@ The default is 10%, a little over 1 second of CD-quality audio with the default
buffer size.
.TP
.B http_proxy_host <hostname>
Use to specify the proxy host used for HTTP connections.
.TP
.B http_proxy_port <port>
The port that the HTTP proxy host uses.
.TP
.B http_proxy_user <username>
If the HTTP proxy server requires authentication, this specifies the username.
.TP
.B http_proxy_password <password>
If the HTTP proxy server requires authentication, this specifies the password.
This setting is deprecated. Use the "proxy" setting in the "curl"
input block. See MPD user manual for details.
.TP
.B connection_timeout <seconds>
If a client does not send any new data in this time period, the connection is
......@@ -288,13 +286,19 @@ whatever audio format is passed to the audio output.
This specifies the device to use for audio output. The default is "default".
.TP
.B mixer_device <mixer dev>
This specifies which mixer to use. The default for oss is "/dev/mixer"; the
default for alsa is "default".
This specifies which mixer to use. The default is "default". To use
the second sound card in a system, use "hw:1".
.TP
.B mixer_control <mixer ctrl>
This specifies which mixer control to use (sometimes referred to as the
"device"). Examples of mixer controls are PCM, Line1, Master, etc. An example
for OSS is "Pcm", and an example for alsa is "PCM".
This specifies which mixer control to use (sometimes referred to as
the "device"). The default is "PCM". Use "amixer scontrols" to see
the list of possible controls.
.TP
.B mixer_index <mixer index>
A number identifying the index of the named mixer control. This is
probably only useful if your alsa device has more than one
identically\-named mixer control. The default is "0". Use "amixer
scontrols" to see the list of controls with their indexes.
.TP
.B use_mmap <yes or no>
Setting this allows you to use memory-mapped I/O. Certain hardware setups may
......@@ -330,6 +334,13 @@ or 5804 microseconds for CD-quality audio.
.TP
.B device <dev>
This specifies the device to use for audio output. The default is "/dev/dsp".
.TP
.B mixer_device <mixer dev>
This specifies which mixer to use. The default is "/dev/mixer".
.TP
.B mixer_control <mixer ctrl>
This specifies which mixer control to use (sometimes referred to as the
"device"). The default is to use the main PCM mixer. An example is "Pcm".
.SH OPTIONAL PULSE OUTPUT PARAMETERS
.TP
.B server <server list>
......
......@@ -50,7 +50,7 @@
<para>
To facilitate faster adding of files etc. you can pass a list
of commands all at once using a command list. The command
list beings with <command>command_list_begin</command> or
list begins with <command>command_list_begin</command> or
<command>command_list_ok_begin</command> and ends with
<command>command_list_end</command>.
</para>
......@@ -62,7 +62,7 @@
<returnvalue>OK</returnvalue> is returned. If a command
fails, no more commands are executed and the appropriate
<returnvalue>ACK</returnvalue> error is returned. If
<command>command_list_begin</command> is used,
<command>command_list_ok_begin</command> is used,
<returnvalue>list_OK</returnvalue> is returned for each
successful command executed in the command list.
</para>
......@@ -123,6 +123,7 @@
</term>
<listitem>
<para>
<footnote id="since_0_14"><simpara>Since MPD 0.14</simpara></footnote>
Waits until there is a noteworthy change in one or more
of MPD's subsystems. As soon as there is one, it lists
all changed systems in a line in the format
......@@ -190,6 +191,9 @@
MPD will only send notifications when something changed in
one of the specified subsytems.
</para>
<simpara>
Since <application>MPD</application> 0.14
</simpara>
</listitem>
</varlistentry>
<varlistentry id="command_status">
......@@ -217,6 +221,20 @@
</para>
</listitem>
<listitem>
<para>
<varname>single</varname>:
<returnvalue>0 or 1</returnvalue>
<footnote id="since_0_15"><simpara>Since MPD 0.15</simpara></footnote>
</para>
</listitem>
<listitem>
<para>
<varname>consume</varname>:
<returnvalue>0 or 1</returnvalue>
<footnoteref linkend="since_0_15"/>
</para>
</listitem>
<listitem>
<para>
<varname>playlist</varname>:
<returnvalue>31-bit unsigned integer, the playlist
......@@ -347,6 +365,22 @@
<title>Playback options</title>
<variablelist>
<varlistentry id="command_consume">
<term>
<cmdsynopsis>
<command>consume</command>
<arg choice="req"><replaceable>STATE</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
<footnoteref linkend="since_0_15"/>
Sets consume state to <varname>STATE</varname>,
<varname>STATE</varname> should be 0 or 1.
When consume is activated, each song played is removed from playlist.
</para>
</listitem>
</varlistentry>
<varlistentry id="command_crossfade">
<term>
<cmdsynopsis>
......@@ -402,6 +436,23 @@
</para>
</listitem>
</varlistentry>
<varlistentry id="command_single">
<term>
<cmdsynopsis>
<command>single</command>
<arg choice="req"><replaceable>STATE</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
<footnoteref linkend="since_0_15"/>
Sets single state to <varname>STATE</varname>,
<varname>STATE</varname> should be 0 or 1.
When single is activated, playback is stopped after current song, or
song is repeated if the 'repeat' mode is enabled.
</para>
</listitem>
</varlistentry>
<varlistentry id="command_volume">
<term>
<cmdsynopsis>
......@@ -634,14 +685,21 @@ OK
<term>
<cmdsynopsis>
<command>move</command>
<arg choice="req"><replaceable>FROM</replaceable></arg>
<group>
<arg choice="req"><replaceable>FROM</replaceable></arg>
<arg choice="req"><replaceable>START:END</replaceable></arg>
</group>
<arg choice="req"><replaceable>TO</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Moves the song at <varname>FROM</varname> to
<varname>TO</varname> in the playlist.
Moves the song at <varname>FROM</varname> or range of songs
at <varname>START:END</varname> to <varname>TO</varname>
in the playlist.
<footnote id="range_since_0_15">
<simpara>Ranges are supported since MPD 0.15</simpara>
</footnote>
</para>
</listitem>
</varlistentry>
......@@ -655,8 +713,8 @@ OK
</term>
<listitem>
<para>
Moves the song with <varname>FROM</varname> to
<varname>TO</varname> (both song ids) in the
Moves the song with <varname>FROM</varname> (songid) to
<varname>TO</varname> (playlist index) in the
playlist. If <varname>TO</varname> is negative, it
is relative to the current song in the playlist (if
there is one).
......@@ -714,14 +772,19 @@ OK
<term>
<cmdsynopsis>
<command>playlistinfo</command>
<arg><replaceable>SONGPOS</replaceable></arg>
<group>
<arg><replaceable>SONGPOS</replaceable></arg>
<arg><replaceable>START:END</replaceable></arg>
</group>
</cmdsynopsis>
</term>
<listitem>
<para>
Displays a list of songs in the playlist.
<varname>SONGPOS</varname> is optional and specifies
a single song to display info for.
Displays a list of all songs in the playlist, or if the optional
argument is given, displays information only for the song
<varname>SONGPOS</varname> or the range of songs
<varname>START:END</varname>
<footnoteref linkend="range_since_0_15"/>
</para>
</listitem>
</varlistentry>
......@@ -782,13 +845,13 @@ OK
<term>
<cmdsynopsis>
<command>shuffle</command>
<arg><replaceable>SONGRANGE</replaceable></arg>
<arg><replaceable>START:END</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Shuffles the current playlist.
<varname>SONGRANGE</varname> is optional and specifies
<varname>START:END</varname> is optional and specifies
a range of songs.
</para>
</listitem>
......@@ -1162,10 +1225,11 @@ OK
<title>Stickers</title>
<para>
"Stickers" are pieces of information attached to existing MPD
objects (e.g. song files, directories, albums). Clients can
create arbitrary name/value pairs. MPD itself does not assume
any special meaning in them.
"Stickers"<footnoteref linkend="since_0_15"/> are pieces of
information attached to existing MPD objects (e.g. song files,
directories, albums). Clients can create arbitrary name/value
pairs. MPD itself does not assume any special meaning in
them.
</para>
<para>
......@@ -1222,6 +1286,58 @@ OK
</para>
</listitem>
</varlistentry>
<varlistentry id="command_sticker_delete">
<term>
<cmdsynopsis>
<command>sticker</command>
<arg choice="plain">delete</arg>
<arg choice="req"><replaceable>TYPE</replaceable></arg>
<arg choice="req"><replaceable>URI</replaceable></arg>
<arg choice="opt"><replaceable>NAME</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Deletes a sticker value from the specified object. If
you do not specify a sticker name, all sticker values
are deleted.
</para>
</listitem>
</varlistentry>
<varlistentry id="command_sticker_list">
<term>
<cmdsynopsis>
<command>sticker</command>
<arg choice="plain">list</arg>
<arg choice="req"><replaceable>TYPE</replaceable></arg>
<arg choice="req"><replaceable>URI</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Lists the stickers for the specified object.
</para>
</listitem>
</varlistentry>
<varlistentry id="command_sticker_find">
<term>
<cmdsynopsis>
<command>sticker</command>
<arg choice="plain">find</arg>
<arg choice="req"><replaceable>TYPE</replaceable></arg>
<arg choice="req"><replaceable>URI</replaceable></arg>
<arg choice="req"><replaceable>NAME</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Searches the sticker database for stickers with the
specified name, below the specified directory (URI).
For each matching song, it prints the URI and that one
sticker's value.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
......
......@@ -28,51 +28,64 @@
its easy to change this on the fly, if needed.
</para>
<tag>
<name>rating</name>
<value>1-5</value>
<para>
Will store a rating value from 1 (worst) to 5 (best) for a given song.
</para>
</tag>
<variablelist>
<varlistentry>
<term><varname>rating</varname></term>
<listitem>
<para>
Will store a rating value from 1 (worst) to 5 (best) for a
given song.
</para>
</listitem>
</varlistentry>
<tag>
<name>album_rating</name>
<value>1-5</value>
<para>
Will store a rating value from 1 (worst) to 5 (best) for a given album.
</para>
</tag>
<varlistentry>
<term><varname>album_rating</varname></term>
<listitem>
<para>
Will store a rating value from 1 (worst) to 5 (best) for a
given album.
</para>
</listitem>
</varlistentry>
<tag>
<name>style</name>
<value>Keyword</value>
<para>
This tag is used to keep the Genre tag clean, by now having 1000's of genres.
Instead you define a Main Genre for each file and can make a more specific
description. This should be one Keyword like "Post Punk" or "Progressive Death Metal"
An Alternative name for this tag is "Subgenre", time will tell which one gets
more support.
</para>
</tag>
<varlistentry>
<term><varname>style</varname></term>
<listitem>
<para>
This tag is used to keep the Genre tag clean, by now
having 1000's of genres. Instead you define a Main Genre
for each file and can make a more specific
description. This should be one Keyword like "Post Punk"
or "Progressive Death Metal" An Alternative name for this
tag is "Subgenre", time will tell which one gets more
support.
</para>
</listitem>
</varlistentry>
<tag>
<name>lyrics</name>
<value>The lyrics of the song, including header with Artist - Title</value>
<para>
This one is self explaining. This gives the option to store lyrics of
a song where they belong to: mapped to the song
</para>
</tag>
<varlistentry>
<term><varname>lyrics</varname></term>
<listitem>
<para>
This one is self explaining. This gives the option to
store lyrics of a song where they belong to: mapped to the
song
</para>
</listitem>
</varlistentry>
<tag>
<name>similar_artists</name>
<value>Comma seperated list of artists</value>
<para>
This tag enables a last.fm alike aproach which will still work when being offline
Keep in mind, that this tag is absolutely non-standard! I am not aware of any
other player that uses a comparable tag.
</para>
</tag>
<varlistentry>
<term><varname>similar_artists</varname> (Comma seperated list of artists)</term>
<listitem>
<para>
This tag enables a last.fm alike aproach which will still
work when being offline Keep in mind, that this tag is
absolutely non-standard! I am not aware of any other
player that uses a comparable tag.
</para>
</listitem>
</varlistentry>
</variablelist>
</chapter>
</book>
This diff is collapsed. Click to expand it.
AC_DEFUN([AM_PATH_FAAD],
[dnl ##
dnl faad
dnl ##
AC_ARG_ENABLE(aac,
AS_HELP_STRING([--disable-aac],
[disable AAC support (default: enable)]),,
enable_aac=yes)
AC_ARG_WITH(faad,
AS_HELP_STRING([--with-faad=PFX],
[prefix where faad2 is installed (optional)]),,
faad_prefix="")
AC_ARG_WITH(faad-libraries,
AS_HELP_STRING([--with-faad-libraries=DIR],
[directory where faad2 library is installed (optional)]),,
faad_libraries="")
AC_ARG_WITH(faad-includes,
AS_HELP_STRING([--with-faad-includes=DIR],
[directory where faad2 header files are installed (optional)]),,
faad_includes="")
if test x$enable_aac = xyes; then
if test "x$faad_libraries" != "x" ; then
FAAD_LIBS="-L$faad_libraries"
elif test "x$faad_prefix" != "x" ; then
FAAD_LIBS="-L$faad_prefix/lib"
fi
FAAD_LIBS="$FAAD_LIBS -lfaad"
if test "x$faad_includes" != "x" ; then
FAAD_CFLAGS="-I$faad_includes"
elif test "x$faad_prefix" != "x" ; then
FAAD_CFLAGS="-I$faad_prefix/include"
fi
oldcflags=$CFLAGS
oldlibs=$LIBS
oldcppflags=$CPPFLAGS
CFLAGS="$CFLAGS $MPD_CFLAGS $FAAD_CFLAGS -I."
LIBS="$LIBS $MPD_LIBS $FAAD_LIBS"
CPPFLAGS=$CFLAGS
AC_CHECK_HEADER(faad.h,,enable_aac=no)
if test x$enable_aac = xyes; then
AC_CHECK_DECL(FAAD2_VERSION,,enable_aac=no,[#include <faad.h>])
fi
if test x$enable_aac = xyes; then
AC_CHECK_DECL(faacDecInit2,,enable_aac=no,[#include <faad.h>])
fi
if test x$enable_aac = xyes; then
AC_CHECK_LIB(faad,faacDecInit2,[MPD_LIBS="$MPD_LIBS $FAAD_LIBS";MPD_CFLAGS="$MPD_CFLAGS $FAAD_CFLAGS"],enable_aac=no)
if test x$enable_aac = xno; then
enable_aac=yes
AC_CHECK_LIB(faad,NeAACDecInit2,[MPD_LIBS="$MPD_LIBS $FAAD_LIBS";MPD_CFLAGS="$MPD_CFLAGS $FAAD_CFLAGS"],enable_aac=no)
fi
fi
if test x$enable_aac = xyes; then
AC_MSG_CHECKING(that FAAD2 uses buffer and bufferlen)
AC_COMPILE_IFELSE([
#include <faad.h>
int main() {
char buffer;
long bufferlen = 0;
faacDecHandle decoder;
faacDecFrameInfo frameInfo;
faacDecConfigurationPtr config;
unsigned char channels;
long sampleRate;
mp4AudioSpecificConfig mp4ASC;
decoder = faacDecOpen();
config = faacDecGetCurrentConfiguration(decoder);
config->outputFormat = FAAD_FMT_16BIT;
faacDecSetConfiguration(decoder,config);
AudioSpecificConfig(&buffer, bufferlen, &mp4ASC);
faacDecInit(decoder,&buffer,bufferlen,&sampleRate,&channels);
faacDecInit2(decoder,&buffer,bufferlen,&sampleRate,&channels);
faacDecDecode(decoder,&frameInfo,&buffer,bufferlen);
return 0;
}
],[AC_MSG_RESULT(yes);AC_DEFINE(HAVE_FAAD_BUFLEN_FUNCS,1,[Define if FAAD2 uses buflen in function calls])],[AC_MSG_RESULT(no);
AC_MSG_CHECKING(that FAAD2 can even be used)
AC_COMPILE_IFELSE([
#include <faad.h>
int main() {
char buffer;
faacDecHandle decoder;
faacDecFrameInfo frameInfo;
faacDecConfigurationPtr config;
unsigned char channels;
long sampleRate;
long bufferlen = 0;
unsigned long dummy1_32;
unsigned char dummy2_8, dummy3_8, dummy4_8, dummy5_8, dummy6_8,
dummy7_8, dummy8_8;
decoder = faacDecOpen();
config = faacDecGetCurrentConfiguration(decoder);
config->outputFormat = FAAD_FMT_16BIT;
faacDecSetConfiguration(decoder,config);
AudioSpecificConfig(&buffer,&dummy1_32,&dummy2_8,
&dummy3_8,&dummy4_8,&dummy5_8,
&dummy6_8,&dummy7_8,&dummy8_8);
faacDecInit(decoder,&buffer,&sampleRate,&channels);
faacDecInit2(decoder,&buffer,bufferlen,&sampleRate,&channels);
faacDecDecode(decoder,&frameInfo,&buffer);
faacDecClose(decoder);
return 0;
}
],AC_MSG_RESULT(yes),[AC_MSG_RESULT(no);enable_aac=no])
])
fi
if test x$enable_aac = xyes; then
AC_CHECK_MEMBERS([faacDecConfiguration.downMatrix,faacDecConfiguration.dontUpSampleImplicitSBR,faacDecFrameInfo.samplerate],,,[#include <faad.h>])
AC_DEFINE(HAVE_FAAD,1,[Define to use FAAD2 for AAC decoding])
else
AC_MSG_WARN([faad2 lib needed for MP4/AAC support -- disabling MP4/AAC support])
fi
CFLAGS=$oldcflags
LIBS=$oldlibs
CPPFLAGS=$oldcppflags
fi
if test x$enable_aac = xyes; then
oldcflags=$CFLAGS
oldlibs=$LIBS
oldcppflags=$CPPFLAGS
CFLAGS="$CFLAGS $MPD_CFLAGS $FAAD_CFLAGS -Werror"
LIBS="$LIBS $MPD_LIBS $FAAD_LIBS"
CPPFLAGS=$CFLAGS
AC_MSG_CHECKING(for broken libfaad headers)
AC_COMPILE_IFELSE([
#include <faad.h>
#include <stddef.h>
#include <stdint.h>
int main() {
unsigned char channels;
uint32_t sample_rate;
faacDecInit2(NULL, NULL, 0, &sample_rate, &channels);
return 0;
}
],
[AC_MSG_RESULT(correct)],
[AC_MSG_RESULT(broken);
AC_DEFINE(HAVE_FAAD_LONG, 1, [Define if faad.h uses the broken "unsigned long" pointers])])
CFLAGS=$oldcflags
LIBS=$oldlibs
CPPFLAGS=$oldcppflags
fi
if test x$enable_aac = xyes; then
enable_mp4=yes
MP4FF_LIBS="-lmp4ff"
oldcflags=$CFLAGS
oldlibs=$LIBS
oldcppflags=$CPPFLAGS
CFLAGS="$CFLAGS $FAAD_CFLAGS"
LIBS="$LIBS $FAAD_LIBS $MP4FF_LIBS"
CPPFLAGS=$CFLAGS
AC_CHECK_HEADER(mp4ff.h,,enable_mp4=no)
if test x$enable_mp4 = xyes; then
AC_CHECK_LIB(mp4ff,mp4ff_open_read,,enable_mp4=no)
fi
if test x$enable_mp4 = xyes; then
AC_SUBST(MP4FF_LIBS)
AC_DEFINE(HAVE_MP4, 1, [Define to use FAAD2+mp4ff for MP4 decoding])
else
AC_MSG_WARN([libmp4ff needed for MP4 support -- disabling MP4 support])
unset MP4FF_LIBS
fi
CFLAGS=$oldcflags
LIBS=$oldlibs
CPPFLAGS=$oldcppflags
else
enable_mp4=no
fi
])
......@@ -6,10 +6,18 @@ AC_DEFUN([AM_PATH_LAME],
[dnl
dnl Get the cflags and libraries
dnl
AC_ARG_WITH(lame,[ --with-lame=PFX Prefix where liblame is installed (optional)], lame_prefix="$withval", lame_prefix="")
AC_ARG_WITH(lame-libraries,[ --with-lame-libraries=DIR Directory where liblame library is installed (optional)], lame_libraries="$withval", lame_libraries="")
AC_ARG_WITH(lame-includes,[ --with-lame-includes=DIR Directory where liblame header files are installed (optional)], lame_includes="$withval", lame_includes="")
AC_ARG_ENABLE(lametest, [ --disable-lametest Do not try to compile and run a test liblame program],, enable_lametest=yes)
AC_ARG_WITH(lame,
AS_HELP_STRING([--with-lame=PFX],
[prefix where liblame is installed (optional)]),,
lame_prefix="")
AC_ARG_WITH(lame-libraries,
AS_HELP_STRING([--with-lame-libraries=DIR],
[directory where liblame library is installed (optional)]),,
lame_libraries="")
AC_ARG_WITH(lame-includes,
AS_HELP_STRING([--with-lame-includes=DIR],
[directory where liblame header files are installed (optional)]),,
lame_includes="")
if test "x$lame_prefix" != "xno" ; then
......@@ -35,7 +43,6 @@ if test "x$lame_prefix" != "xno" ; then
no_lame=""
if test "x$enable_lametest" = "xyes" ; then
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $LAME_CFLAGS"
......@@ -97,10 +104,6 @@ int main ()
fi
AC_DEFINE(HAVE_LAME, 1, [Define if you have liblame.])
use_lame="1"
else
LAME_CFLAGS=""
LAME_LIBS=""
fi
AC_SUBST(LAME_CFLAGS)
AC_SUBST(LAME_LIBS)
rm -f conf.lametest
......
......@@ -8,10 +8,22 @@ AC_DEFUN([AM_PATH_LIBOGGFLAC],
[dnl
dnl Get the cflags and libraries
dnl
AC_ARG_WITH(libOggFLAC,[ --with-libOggFLAC=PFX Prefix where libOggFLAC is installed (optional)], libOggFLAC_prefix="$withval", libOggFLAC_prefix="")
AC_ARG_WITH(libOggFLAC-libraries,[ --with-libOggFLAC-libraries=DIR Directory where libOggFLAC library is installed (optional)], libOggFLAC_libraries="$withval", libOggFLAC_libraries="")
AC_ARG_WITH(libOggFLAC-includes,[ --with-libOggFLAC-includes=DIR Directory where libOggFLAC header files are installed (optional)], libOggFLAC_includes="$withval", libOggFLAC_includes="")
AC_ARG_ENABLE(libOggFLACtest, [ --disable-libOggFLACtest Do not try to compile and run a test libOggFLAC program],, enable_libOggFLACtest=yes)
AC_ARG_WITH(libOggFLAC,
AS_HELP_STRING([--with-libOggFLAC=PFX],
[prefix where libOggFLAC is installed (optional)]),,
libOggFLAC_prefix="")
AC_ARG_WITH(libOggFLAC-libraries,
AS_HELP_STRING([--with-libOggFLAC-libraries=DIR],
[directory where libOggFLAC library is installed (optional)]),,
libOggFLAC_libraries="")
AC_ARG_WITH(libOggFLAC-includes,
AS_HELP_STRING([--with-libOggFLAC-includes=DIR],
[directory where libOggFLAC header files are installed (optional)]),,
libOggFLAC_includes="")
AC_ARG_ENABLE(libOggFLACtest,
AS_HELP_STRING([--disable-libOggFLACtest],
[do not try to compile and run a test libOggFLAC program]),,
enable_libOggFLACtest=yes)
if test "x$libOggFLAC_libraries" != "x" ; then
LIBOGGFLAC_LIBS="-L$libOggFLAC_libraries"
......
AC_DEFUN([MPD_AUTO_ENABLED], [
var="enable_$1"
feature="$2"
if eval "test x`echo '$'$var` = xauto"; then
AC_MSG_NOTICE([auto-detected $feature])
eval "$var=yes"
fi
])
AC_DEFUN([MPD_AUTO_DISABLED], [
var="enable_$1"
feature="$2"
msg="$3"
if eval "test x`echo '$'$var` = xauto"; then
AC_MSG_WARN([$msg -- disabling $feature])
eval "$var=no"
elif eval "test x`echo '$'$var` = xyes"; then
AC_MSG_ERROR([$feature: $msg])
fi
])
dnl Check whether a prerequisite for a feature was found. This is
dnl very similar to MPD_AUTO_RESULT, but does not finalize the
dnl detection; it assumes that more checks will follow.
AC_DEFUN([MPD_AUTO_PRE], [
name="$1"
var="enable_$1"
found="found_$name"
feature="$2"
msg="$3"
if eval "test x`echo '$'$var` != xno" && eval "test x`echo '$'$found` = xno"; then
MPD_AUTO_DISABLED([$name], [$feature], [$msg])
fi
])
AC_DEFUN([MPD_AUTO_RESULT], [
name="$1"
var="enable_$1"
found="found_$name"
feature="$2"
msg="$3"
if eval "test x`echo '$'$var` = xno"; then
eval "$found=no"
fi
if eval "test x`echo '$'$found` = xyes"; then
MPD_AUTO_ENABLED([$name], [$feature])
else
MPD_AUTO_DISABLED([$name], [$feature], [$msg])
fi
])
AC_DEFUN([MPD_AUTO_PKG], [
if eval "test x`echo '$'enable_$1` != xno"; then
PKG_CHECK_MODULES([$2], [$3],
[eval "found_$1=yes"],
[eval "found_$1=no"])
fi
MPD_AUTO_RESULT([$1], [$4], [$5])
])
......@@ -12,7 +12,7 @@ AC_DEFUN([MPD_CHECK_FLAG],[
])
if eval "test x`echo '$mpd_check_cflag_'$var` = xyes"
then
MPD_CFLAGS="$MPD_CFLAGS $1"
AM_CFLAGS="$AM_CFLAGS $1"
fi
])
])
#!/bin/bash
PWD=`pwd`
## If we're not in the scripts directory
## assume the base directory.
if test "`basename $PWD`" != "scripts"; then
MYOLDPWD=`pwd`
cd `dirname $0`
fi
./makedist.sh
rpmbuild -bb mpd.spec
if test $? -eq 0; then
echo 'Your RPM should be ready now'
else
echo 'Something went wrong when building your RPM'
fi
if test -f ../mpd-?.??.?.tar.gz;
then
rm ../mpd-?.??.?.tar.gz
fi
if test "`basename $PWD`" != "scripts"; then
cd $MYOLDPWD
fi
# the Music Player Daemon (MPD)
# Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
# This project's homepage is: http://www.musicpd.org
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# please send bugfixes or comments to avuton@gmail.com
%define _prefix /usr
%define _share %_prefix/share
%define _bindir %_prefix/bin
%define _docdir %_share/doc
%define _mandir %_share/man
Summary: Music Player Daemon (MPD)
Name: mpd
Version: 0.14.0
Release: 0
License: GPL
Group: Productivity/Multimedia/Sound/Players
Source: ../%name-%version.tar.gz
#Patch:
BuildRoot: %{_tmppath}/%{name}-build
%description
Music Player Daemon is simply a daemon for playing music
which can be easily controlled over TCP by different
clients. It has very low CPU usage and can be controlled
from different machines at the same time.
%prep
%setup -q
#%patch -q1 -b .buildroot
%build
CFLAGS="%{optflags}" \
CXXFLAGS="%{optflags}" \
LDFLAGS="%{optflags}" \
./configure --prefix=%{_prefix}
make
%install
make DESTDIR=$RPM_BUILD_ROOT install
%clean
[ ${RPM_BUILD_ROOT} != "/" ] && rm -rf ${RPM_BUILD_ROOT}
%files
%defattr(-,root,root)
%{_bindir}/%{name}
%doc %{_docdir}
%doc %attr(0444,root,root) %{_mandir}
%changelog
* Fri Jul 21 2006 Avuton Olrich <avuton@gmail.com>
- Initial revision
......@@ -8,6 +8,8 @@
PREFIX=/tmp/mpd
rm -rf $PREFIX
test "x$MAKE" != x || MAKE=make
export CFLAGS="-Os"
test -x configure || NOCONFIGURE=1 ./autogen.sh
......@@ -16,17 +18,17 @@ test -x configure || NOCONFIGURE=1 ./autogen.sh
./configure --prefix=$PREFIX/full \
--disable-dependency-tracking --enable-debug --enable-werror \
--enable-un \
--enable-ao --enable-mod --enable-mvp
make -j2 install
make distclean
--enable-ao --enable-mikmod --enable-mvp
$MAKE install
$MAKE distclean
# no UN, no oggvorbis, no flac, enable oggflac
./configure --prefix=$PREFIX/small \
--disable-dependency-tracking --enable-debug --enable-werror \
--disable-un \
--disable-flac --disable-oggvorbis --enable-oggflac
make -j2 install
make distclean
--disable-flac --disable-vorbis --enable-oggflac
$MAKE install
$MAKE distclean
# strip down (disable TCP, disable nearly all plugins)
CFLAGS="$CFLAGS -DNDEBUG" \
......@@ -36,12 +38,13 @@ CFLAGS="$CFLAGS -DNDEBUG" \
--disable-curl \
--disable-id3 --disable-lsr \
--disable-ao --disable-alsa --disable-jack --disable-pulse --disable-fifo \
--disable-shout-ogg --disable-shout-mp3 --disable-lame \
--disable-shout-ogg --disable-shout-mp3 --disable-lame-encoder \
--disable-ffmpeg --disable-wavpack --disable-mpc --disable-aac \
--disable-flac --disable-oggvorbis --disable-oggflac --disable-audiofile \
--disable-flac --disable-vorbis --disable-oggflac --disable-audiofile \
--disable-cue \
--with-zeroconf=no
make -j2 install
make distclean
$MAKE install
$MAKE distclean
# shout: ogg without mp3
./configure --prefix=$PREFIX/shout_ogg \
......@@ -50,12 +53,12 @@ make distclean
--disable-curl \
--disable-id3 --disable-lsr \
--disable-ao --disable-alsa --disable-jack --disable-pulse --disable-fifo \
--enable-shout-ogg --disable-shout-mp3 --disable-lame \
--enable-shout-ogg --disable-shout-mp3 --disable-lame-encoder \
--disable-ffmpeg --disable-wavpack --disable-mpc --disable-aac \
--disable-flac --enable-oggvorbis --disable-oggflac --disable-audiofile \
--disable-flac --enable-vorbis --disable-oggflac --disable-audiofile \
--with-zeroconf=no
make -j2 install
make distclean
$MAKE install
$MAKE distclean
# shout: mp3 without ogg
./configure --prefix=$PREFIX/shout_mp3 \
......@@ -64,12 +67,12 @@ make distclean
--disable-curl \
--disable-id3 --disable-lsr \
--disable-ao --disable-alsa --disable-jack --disable-pulse --disable-fifo \
--disable-shout-ogg --enable-shout-mp3 --enable-lame \
--disable-shout-ogg --enable-shout-mp3 --enable-lame-encoder \
--disable-ffmpeg --disable-wavpack --disable-mpc --disable-aac \
--disable-flac --disable-oggvorbis --disable-oggflac --disable-audiofile \
--disable-flac --disable-vorbis --disable-oggflac --disable-audiofile \
--with-zeroconf=no
make -j2 install
make distclean
$MAKE install
$MAKE distclean
# oggvorbis + oggflac
./configure --prefix=$PREFIX/oggvorbisflac \
......@@ -79,9 +82,9 @@ make distclean
--disable-id3 --disable-lsr \
--disable-mp3 \
--disable-ao --disable-alsa --disable-jack --disable-pulse --disable-fifo \
--disable-shout-ogg --disable-shout-mp3 --disable-lame \
--disable-shout-ogg --disable-shout-mp3 --disable-lame-encoder \
--disable-ffmpeg --disable-wavpack --disable-mpc --disable-aac \
--disable-flac --enable-oggvorbis --enable-oggflac --disable-audiofile \
--disable-flac --enable-vorbis --enable-oggflac --disable-audiofile \
--with-zeroconf=no
make -j2 install
make distclean
$MAKE install
$MAKE distclean
bin_PROGRAMS = mpd
mpd_CFLAGS = $(MPD_CFLAGS)
mpd_CPPFLAGS = \
$(SQLITE_CFLAGS) \
$(CURL_CFLAGS) \
$(MMS_CFLAGS) \
$(AO_CFLAGS) $(ALSA_CFLAGS) \
$(SHOUT_CFLAGS) \
$(OGGVORBIS_CFLAGS) $(VORBISENC_CFLAGS) \
$(patsubst -I%/FLAC,-I%,$(FLAC_CFLAGS)) \
$(AUDIOFILE_CFLAGS) $(LIBMIKMOD_CFLAGS) \
$(MODPLUG_CFLAGS) \
$(SIDPLAY_CFLAGS) \
$(FLUIDSYNTH_CFLAGS) \
$(WILDMIDI_CFLAGS) \
$(ID3TAG_CFLAGS) \
$(MAD_CFLAGS) \
$(FFMPEG_CFLAGS) \
$(GLIB_CFLAGS)
mpd_LDADD = $(MPD_LIBS) \
$(SQLITE_LIBS) \
$(CURL_LIBS) \
$(MMS_LIBS) \
$(AO_LIBS) $(ALSA_LIBS) \
$(SHOUT_LIBS) \
$(OGGVORBIS_LIBS) $(VORBISENC_LIBS) $(FLAC_LIBS) \
$(AUDIOFILE_LIBS) $(LIBMIKMOD_LIBS) \
$(MODPLUG_LIBS) \
$(SIDPLAY_LIBS) \
$(FLUIDSYNTH_LIBS) \
$(WILDMIDI_LIBS) \
$(ID3TAG_LIBS) \
$(MAD_LIBS) \
$(MP4FF_LIBS) \
$(FFMPEG_LIBS) \
$(GLIB_LIBS)
mpd_headers = \
notify.h \
ack.h \
audio.h \
audio_format.h \
audio_parser.h \
audioOutput.h \
output_internal.h \
output_api.h \
output_list.h \
output_all.h \
output_thread.h \
output_control.h \
output_state.h \
output_print.h \
output_command.h \
output/shout_plugin.h \
buffer2array.h \
command.h \
idle.h \
cmdline.h \
conf.h \
crossfade.h \
dbUtils.h \
decoder_thread.h \
decoder_control.h \
decoder_api.h \
decoder_internal.h \
directory.h \
directory_save.h \
directory_print.h \
database.h \
update.h \
dirvec.h \
gcc.h \
decoder_list.h \
decoder/_flac_common.h \
decoder/_ogg_common.h \
input_stream.h \
input_file.h \
input_curl.h \
input_mms.h \
icy_metadata.h \
client.h \
listen.h \
log.h \
ls.h \
main.h \
mixer_api.h \
event_pipe.h \
daemon.h \
normalize.h \
compress.h \
pipe.h \
path.h \
mapper.h \
pcm_utils.h \
pcm_convert.h \
pcm_volume.h \
pcm_mix.h \
pcm_channels.h \
pcm_format.h \
pcm_resample.h \
pcm_dither.h \
pcm_prng.h \
permission.h \
player_thread.h \
player_control.h \
playlist.h \
playlist_internal.h \
playlist_print.h \
playlist_save.h \
playlist_state.h \
queue.h \
queue_print.h \
queue_save.h \
replay_gain.h \
sig_handlers.h \
song.h \
song_print.h \
song_save.h \
song_sticker.h \
songvec.h \
state_file.h \
stats.h \
sticker.h \
tag.h \
tag_internal.h \
tag_pool.h \
tag_id3.h \
tag_print.h \
tag_save.h \
strset.h \
utils.h \
volume.h \
zeroconf.h zeroconf-internal.h \
locate.h \
stored_playlist.h \
timer.h \
archive_api.h \
archive_list.h \
input_archive.h
mpd_SOURCES = \
$(mpd_headers) \
notify.c \
audio.c \
audio_parser.c \
audioOutput.c \
output_api.c \
output_list.c \
output_all.c \
output_thread.c \
output_control.c \
output_state.c \
output_print.c \
output_command.c \
output_init.c \
output/null_plugin.c \
buffer2array.c \
command.c \
idle.c \
cmdline.c \
conf.c \
crossfade.c \
dbUtils.c \
decoder_thread.c \
decoder_control.c \
decoder_api.c \
directory.c \
directory_save.c \
directory_print.c \
database.c \
dirvec.c \
update.c \
decoder_list.c \
input_stream.c \
input_file.c \
client.c \
listen.c \
log.c \
ls.c \
main.c \
event_pipe.c \
daemon.c \
mixer_api.c \
normalize.c \
compress.c \
pipe.c \
path.c \
mapper.c \
pcm_convert.c \
pcm_volume.c \
pcm_mix.c \
pcm_channels.c \
pcm_format.c \
pcm_resample.c \
pcm_dither.c \
permission.c \
player_thread.c \
player_control.c \
playlist.c \
playlist_global.c \
playlist_control.c \
playlist_edit.c \
playlist_print.c \
playlist_save.c \
playlist_state.c \
queue.c \
queue_print.c \
queue_save.c \
replay_gain.c \
sig_handlers.c \
song.c \
song_print.c \
song_save.c \
songvec.c \
state_file.c \
stats.c \
tag.c \
tag_pool.c \
tag_print.c \
tag_save.c \
strset.c \
utils.c \
volume.c \
locate.c \
stored_playlist.c \
timer.c
if ENABLE_SQLITE
mpd_SOURCES += sticker.c song_sticker.c
endif
if HAVE_LIBSAMPLERATE
mpd_SOURCES += pcm_resample_libsamplerate.c
else
mpd_SOURCES += pcm_resample_fallback.c
endif
if HAVE_ID3TAG
mpd_SOURCES += tag_id3.c
endif
# archive plugins
if HAVE_BZ2
mpd_SOURCES += archive/bz2_plugin.c
endif
if HAVE_ZIP
mpd_SOURCES += archive/zip_plugin.c
endif
if HAVE_ISO
mpd_SOURCES += archive/iso_plugin.c
endif
if ENABLE_ARCHIVE
mpd_SOURCES += \
archive_api.c \
archive_list.c \
input_archive.c
endif
# decoder plugins
if HAVE_MAD
mpd_SOURCES += decoder/mp3_plugin.c
endif
if HAVE_MPCDEC
mpd_SOURCES += decoder/mpc_plugin.c
endif
if HAVE_WAVPACK
mpd_SOURCES += decoder/wavpack_plugin.c
endif
if HAVE_FAAD
mpd_SOURCES += decoder/aac_plugin.c
endif
if HAVE_MP4
mpd_SOURCES += decoder/mp4_plugin.c
endif
if HAVE_OGG_COMMON
mpd_SOURCES += decoder/_ogg_common.c
endif
if HAVE_FLAC_COMMON
mpd_SOURCES += decoder/_flac_common.c
endif
if HAVE_OGGVORBIS
mpd_SOURCES += decoder/oggvorbis_plugin.c
endif
if HAVE_FLAC
mpd_SOURCES += decoder/flac_plugin.c
endif
if HAVE_OGGFLAC
mpd_SOURCES += decoder/oggflac_plugin.c
endif
if HAVE_AUDIOFILE
mpd_SOURCES += decoder/audiofile_plugin.c
endif
if HAVE_MIKMOD
mpd_SOURCES += decoder/mikmod_plugin.c
endif
if HAVE_MODPLUG
mpd_SOURCES += decoder/modplug_plugin.c
endif
if ENABLE_SIDPLAY
mpd_SOURCES += decoder/sidplay_plugin.cxx
endif
if ENABLE_FLUIDSYNTH
mpd_SOURCES += decoder/fluidsynth_plugin.c
endif
if ENABLE_WILDMIDI
mpd_SOURCES += decoder/wildmidi_plugin.c
endif
if HAVE_FFMPEG
mpd_SOURCES += decoder/ffmpeg_plugin.c
endif
if HAVE_ZEROCONF
mpd_SOURCES += zeroconf.c
if HAVE_AVAHI
mpd_SOURCES += zeroconf-avahi.c
endif
if HAVE_BONJOUR
mpd_SOURCES += zeroconf-bonjour.c
endif
endif
if HAVE_CURL
mpd_SOURCES += input_curl.c icy_metadata.c
endif
if ENABLE_MMS
mpd_SOURCES += input_mms.c
endif
if HAVE_ALSA
mpd_SOURCES += output/alsa_plugin.c
mpd_SOURCES += mixer/alsa_mixer.c
endif
if HAVE_AO
mpd_SOURCES += output/ao_plugin.c
endif
if HAVE_FIFO
mpd_SOURCES += output/fifo_plugin.c
endif
if HAVE_JACK
mpd_SOURCES += output/jack_plugin.c
endif
if HAVE_MVP
mpd_SOURCES += output/mvp_plugin.c
endif
if HAVE_OSS
mpd_SOURCES += output/oss_plugin.c
mpd_SOURCES += mixer/oss_mixer.c
endif
if HAVE_OSX
mpd_SOURCES += output/osx_plugin.c
endif
if HAVE_PULSE
mpd_SOURCES += output/pulse_plugin.c
endif
if HAVE_SHOUT
mpd_SOURCES += output/shout_plugin.c
endif
if HAVE_SHOUT_MP3
mpd_SOURCES += output/shout_mp3.c
endif
if HAVE_SHOUT_OGG
mpd_SOURCES += output/shout_ogg.c
endif
# sparse is a semantic parser
# URL: git://www.kernel.org/pub/scm/devel/sparse/sparse.git
SPARSE = sparse
SPARSE_FLAGS =
SPARSE_CPPFLAGS = $(DEFAULT_INCLUDES) \
-I$(shell $(CC) -print-file-name=include) \
-I$(shell $(CC) -print-file-name=include-fixed)
sparse-check:
for i in $(mpd_SOURCES); \
do \
$(SPARSE) -I. $(mpd_CFLAGS) $(mpd_CPPFLAGS) $(SPARSE_FLAGS) $(SPARSE_CPPFLAGS) $(srcdir)/$$i || exit; \
done
TEST_CFLAGS = -DUNIT_TEST
TEST_FILES := $(shell grep UNIT_TEST \
$(addprefix $(srcdir)/, $(mpd_SOURCES)) | \
awk -F: '{print $$1}' | uniq)
test: $(addprefix test-, $(subst .c,,$(TEST_FILES)))
test-%: %.c
$(CC) $(CFLAGS) $(TEST_CFLAGS) -o $@ $<
@./$@
@echo $@: OK
.PHONY: sparse-check test
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_ACK_H
......
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "aiff.h"
#include <glib.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "aiff"
struct aiff_header {
char id[4];
uint32_t size;
char format[4];
};
struct aiff_chunk_header {
char id[4];
uint32_t size;
};
size_t
aiff_seek_id3(FILE *file)
{
int ret;
struct stat st;
struct aiff_header header;
struct aiff_chunk_header chunk;
size_t size;
/* determine the file size */
ret = fstat(fileno(file), &st);
if (ret < 0) {
g_warning("Failed to stat file descriptor: %s",
strerror(errno));
return 0;
}
/* seek to the beginning and read the AIFF header */
ret = fseek(file, 0, SEEK_SET);
if (ret != 0) {
g_warning("Failed to seek: %s", g_strerror(errno));
return 0;
}
size = fread(&header, sizeof(header), 1, file);
if (size != 1 ||
memcmp(header.id, "FORM", 4) != 0 ||
GUINT32_FROM_BE(header.size) > (uint32_t)st.st_size ||
memcmp(header.format, "AIFF", 4) != 0)
/* not a AIFF file */
return 0;
while (true) {
/* read the chunk header */
size = fread(&chunk, sizeof(chunk), 1, file);
if (size != 1)
return 0;
size = GUINT32_FROM_BE(chunk.size);
if (size % 2 != 0)
/* pad byte */
++size;
if (memcmp(chunk.id, "ID3 ", 4) == 0)
/* found it! */
return size;
if ((off_t)size < 0)
/* integer underflow after cast to signed
type */
return 0;
ret = fseek(file, size, SEEK_CUR);
if (ret != 0)
return 0;
}
}
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/** \file
*
* A parser for the AIFF file format.
*/
#ifndef MPD_AIFF_H
#define MPD_AIFF_H
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
/**
* Seeks the AIFF file to the ID3 chunk.
*
* @return the size of the ID3 chunk on success, or 0 if this is not a
* AIFF file or no ID3 chunk was found
*/
size_t
aiff_seek_id3(FILE *file);
#endif
/* the Music Player Daemon (MPD)
* Copyright (C) 2008 Viliam Mateicka <viliam.mateicka@gmail.com>
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
......@@ -21,7 +22,7 @@
*/
#include "archive_api.h"
#include "input_stream.h"
#include "input_plugin.h"
#include "config.h"
#include <stdint.h>
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2008 Viliam Mateicka <viliam.mateicka@gmail.com>
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
......@@ -21,7 +22,7 @@
*/
#include "archive_api.h"
#include "input_stream.h"
#include "input_plugin.h"
#include <cdio/cdio.h>
#include <cdio/iso9660.h>
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2008 Viliam Mateicka <viliam.mateicka@gmail.com>
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
......@@ -22,7 +23,7 @@
#include "archive_api.h"
#include "archive_api.h"
#include "input_stream.h"
#include "input_plugin.h"
#include <zzip/zzip.h>
#include <glib.h>
......@@ -48,7 +49,7 @@ zip_open(char * pathname)
// open archive
context->list = NULL;
context->dir = zzip_dir_open(pathname, 0);
context->dir = zzip_dir_open(pathname, NULL);
if (context->dir == NULL) {
g_warning("zipfile %s open failed\n", pathname);
return NULL;
......@@ -56,7 +57,7 @@ zip_open(char * pathname)
while (zzip_dir_read(context->dir, &dirent)) {
//add only files
if (dirent.st_size > 0) {
if (dirent.st_size > 0) {
context->list = g_slist_prepend(context->list,
g_strdup(dirent.d_name));
}
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2008 Viliam Mateicka <viliam.mateicka@gmail.com>
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,12 +11,12 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <string.h>
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2008 Viliam Mateicka <viliam.mateicka@gmail.com>
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_ARCHIVE_API_H
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2008 Viliam Mateicka <viliam.mateicka@gmail.com>
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_ARCHIVE_INTERNAL_H
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2008 Viliam Mateicka <viliam.mateicka@gmail.com>
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "archive_list.h"
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2008 Viliam Mateicka <viliam.mateicka@gmail.com>
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_ARCHIVE_LIST_H
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,17 +11,19 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "audio.h"
#include "audio_format.h"
#include "audio_parser.h"
#include "output_internal.h"
#include "output_plugin.h"
#include "output_all.h"
#include "mixer_api.h"
#include "conf.h"
#include <glib.h>
......@@ -58,43 +60,3 @@ void finishAudioConfig(void)
{
audio_format_clear(&configured_audio_format);
}
bool mixer_control_setvol(unsigned int device, int volume, int rel)
{
struct audio_output *output;
if (device >= audio_output_count())
return false;
output = audio_output_get(device);
if (output->plugin && output->plugin->control) {
if (rel) {
int cur_volume;
if (!output->plugin->control(output->data, AC_MIXER_GETVOL, &cur_volume)) {
return false;
}
volume = volume + cur_volume;
}
if (volume > 100)
volume = 100;
else if (volume < 0)
volume = 0;
return output->plugin->control(output->data, AC_MIXER_SETVOL, &volume);
}
return false;
}
bool mixer_control_getvol(unsigned int device, int *volume)
{
struct audio_output *output;
if (device >= audio_output_count())
return false;
output = audio_output_get(device);
if (output->plugin && output->plugin->control) {
return output->plugin->control(output->data, AC_MIXER_GETVOL, volume);
}
return false;
}
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_AUDIO_H
......@@ -31,7 +32,4 @@ void initAudioConfig(void);
void finishAudioConfig(void);
bool mixer_control_setvol(unsigned int device, int volume, int rel);
bool mixer_control_getvol(unsigned int device, int *volume);
#endif
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "audioOutput.h"
#include "output_api.h"
#include "output_list.h"
void printAllOutputPluginTypes(FILE * fp)
{
unsigned i;
const struct audio_output_plugin *plugin;
audio_output_plugins_for_each(plugin, i)
fprintf(fp, "%s ", plugin->name);
fprintf(fp, "\n");
fflush(fp);
}
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_AUDIO_FORMAT_H
......@@ -59,7 +60,7 @@ audio_valid_sample_rate(unsigned sample_rate)
static inline bool
audio_valid_sample_format(unsigned bits)
{
return bits == 16 || bits == 24 || bits == 8;
return bits == 16 || bits == 24 || bits == 32 || bits == 8;
}
/**
......@@ -68,7 +69,7 @@ audio_valid_sample_format(unsigned bits)
static inline bool
audio_valid_channel_count(unsigned channels)
{
return channels == 1 || channels == 2;
return channels >= 1 && channels <= 8;
}
/**
......
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
......
......@@ -11,14 +11,15 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Parser functions for audio related objects.
/** \file
*
* Parser functions for audio related objects.
*/
#ifndef AUDIO_PARSER_H
......@@ -30,6 +31,16 @@
struct audio_format;
/**
* Parses a string in the form "SAMPLE_RATE:BITS:CHANNELS" into an
* #audio_format.
*
* @param dest the destination #audio_format struct
* @param src the input string
* @param error location to store the error occuring, or NULL to
* ignore errors
* @return true on success
*/
bool
audio_format_parse(struct audio_format *dest, const char *src, GError **error);
......
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "buffer.h"
#include "chunk.h"
#include "poison.h"
#include <glib.h>
#include <assert.h>
struct music_buffer {
struct music_chunk *chunks;
unsigned num_chunks;
struct music_chunk *available;
/** a mutex which protects #available */
GMutex *mutex;
#ifndef NDEBUG
unsigned num_allocated;
#endif
};
struct music_buffer *
music_buffer_new(unsigned num_chunks)
{
struct music_buffer *buffer;
struct music_chunk *chunk;
assert(num_chunks > 0);
buffer = g_new(struct music_buffer, 1);
buffer->chunks = g_new(struct music_chunk, num_chunks);
buffer->num_chunks = num_chunks;
chunk = buffer->available = buffer->chunks;
poison_undefined(chunk, sizeof(*chunk));
for (unsigned i = 1; i < num_chunks; ++i) {
chunk->next = &buffer->chunks[i];
chunk = chunk->next;
poison_undefined(chunk, sizeof(*chunk));
}
chunk->next = NULL;
buffer->mutex = g_mutex_new();
#ifndef NDEBUG
buffer->num_allocated = 0;
#endif
return buffer;
}
void
music_buffer_free(struct music_buffer *buffer)
{
assert(buffer->chunks != NULL);
assert(buffer->num_chunks > 0);
assert(buffer->num_allocated == 0);
g_mutex_free(buffer->mutex);
g_free(buffer->chunks);
g_free(buffer);
}
unsigned
music_buffer_size(const struct music_buffer *buffer)
{
return buffer->num_chunks;
}
struct music_chunk *
music_buffer_allocate(struct music_buffer *buffer)
{
struct music_chunk *chunk;
g_mutex_lock(buffer->mutex);
chunk = buffer->available;
if (chunk != NULL) {
buffer->available = chunk->next;
music_chunk_init(chunk);
#ifndef NDEBUG
++buffer->num_allocated;
#endif
}
g_mutex_unlock(buffer->mutex);
return chunk;
}
void
music_buffer_return(struct music_buffer *buffer, struct music_chunk *chunk)
{
assert(buffer != NULL);
assert(chunk != NULL);
g_mutex_lock(buffer->mutex);
music_chunk_free(chunk);
poison_undefined(chunk, sizeof(*chunk));
chunk->next = buffer->available;
buffer->available = chunk;
#ifndef NDEBUG
--buffer->num_allocated;
#endif
g_mutex_unlock(buffer->mutex);
}
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_MUSIC_BUFFER_H
#define MPD_MUSIC_BUFFER_H
/**
* An allocator for #music_chunk objects.
*/
struct music_buffer;
/**
* Creates a new #music_buffer object.
*
* @param num_chunks the number of #music_chunk reserved in this
* buffer
*/
struct music_buffer *
music_buffer_new(unsigned num_chunks);
/**
* Frees the #music_buffer object
*/
void
music_buffer_free(struct music_buffer *buffer);
/**
* Returns the total number of reserved chunks in this buffer. This
* is the same value which was passed to the constructor
* music_buffer_new().
*/
unsigned
music_buffer_size(const struct music_buffer *buffer);
/**
* Allocates a chunk from the buffer. When it is not used anymore,
* call music_buffer_return().
*
* @return an empty chunk or NULL if there are no chunks available
*/
struct music_chunk *
music_buffer_allocate(struct music_buffer *buffer);
/**
* Returns a chunk to the buffer. It can be reused by
* music_buffer_allocate() then.
*/
void
music_buffer_return(struct music_buffer *buffer, struct music_chunk *chunk);
#endif
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "buffer2array.h"
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_BUFFER_2_ARRAY_H
......
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "chunk.h"
#include "audio_format.h"
#include "tag.h"
#include <assert.h>
void
music_chunk_init(struct music_chunk *chunk)
{
chunk->length = 0;
chunk->tag = NULL;
}
void
music_chunk_free(struct music_chunk *chunk)
{
if (chunk->tag != NULL)
tag_free(chunk->tag);
}
#ifndef NDEBUG
bool
music_chunk_check_format(const struct music_chunk *chunk,
const struct audio_format *audio_format)
{
assert(chunk != NULL);
assert(audio_format != NULL);
assert(audio_format_valid(audio_format));
return chunk->length == 0 ||
audio_format_equals(&chunk->audio_format, audio_format);
}
#endif
void *
music_chunk_write(struct music_chunk *chunk,
const struct audio_format *audio_format,
float data_time, uint16_t bit_rate,
size_t *max_length_r)
{
const size_t frame_size = audio_format_frame_size(audio_format);
size_t num_frames;
assert(music_chunk_check_format(chunk, audio_format));
assert(chunk->length == 0 || audio_format_valid(&chunk->audio_format));
if (chunk->length == 0) {
/* if the chunk is empty, nobody has set bitRate and
times yet */
chunk->bit_rate = bit_rate;
chunk->times = data_time;
}
num_frames = (sizeof(chunk->data) - chunk->length) / frame_size;
if (num_frames == 0)
return NULL;
#ifndef NDEBUG
chunk->audio_format = *audio_format;
#endif
*max_length_r = num_frames * frame_size;
return chunk->data + chunk->length;
}
bool
music_chunk_expand(struct music_chunk *chunk,
const struct audio_format *audio_format, size_t length)
{
const size_t frame_size = audio_format_frame_size(audio_format);
assert(chunk != NULL);
assert(chunk->length + length <= sizeof(chunk->data));
assert(audio_format_equals(&chunk->audio_format, audio_format));
chunk->length += length;
return chunk->length + frame_size > sizeof(chunk->data);
}
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_CHUNK_H
#define MPD_CHUNK_H
#ifndef NDEBUG
#include "audio_format.h"
#endif
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
enum {
CHUNK_SIZE = 4096,
};
struct audio_format;
/**
* A chunk of music data. Its format is defined by the
* music_pipe_append() caller.
*/
struct music_chunk {
/** the next chunk in a linked list */
struct music_chunk *next;
/** number of bytes stored in this chunk */
uint16_t length;
/** current bit rate of the source file */
uint16_t bit_rate;
/** the time stamp within the song */
float times;
/**
* An optional tag associated with this chunk (and the
* following chunks); appears at song boundaries. The tag
* object is owned by this chunk, and must be freed when this
* chunk is deinitialized in music_chunk_free()
*/
struct tag *tag;
/** the data (probably PCM) */
char data[CHUNK_SIZE];
#ifndef NDEBUG
struct audio_format audio_format;
#endif
};
void
music_chunk_init(struct music_chunk *chunk);
void
music_chunk_free(struct music_chunk *chunk);
static inline bool
music_chunk_is_empty(const struct music_chunk *chunk)
{
return chunk->length == 0 && chunk->tag == NULL;
}
#ifndef NDEBUG
/**
* Checks if the audio format if the chunk is equal to the specified
* audio_format.
*/
bool
music_chunk_check_format(const struct music_chunk *chunk,
const struct audio_format *audio_format);
#endif
/**
* Prepares appending to the music chunk. Returns a buffer where you
* may write into. After you are finished, call music_chunk_expand().
*
* @param chunk the music_chunk object
* @param audio_format the audio format for the appended data; must
* stay the same for the life cycle of this chunk
* @param data_time the time within the song
* @param bit_rate the current bit rate of the source file
* @param max_length_r the maximum write length is returned here
* @return a writable buffer, or NULL if the chunk is full
*/
void *
music_chunk_write(struct music_chunk *chunk,
const struct audio_format *audio_format,
float data_time, uint16_t bit_rate,
size_t *max_length_r);
/**
* Increases the length of the chunk after the caller has written to
* the buffer returned by music_chunk_write().
*
* @param chunk the music_chunk object
* @param audio_format the audio format for the appended data; must
* stay the same for the life cycle of this chunk
* @param length the number of bytes which were appended
* @return true if the chunk is full
*/
bool
music_chunk_expand(struct music_chunk *chunk,
const struct audio_format *audio_format, size_t length);
#endif
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_CLIENT_H
......@@ -30,7 +31,7 @@ struct sockaddr;
void client_manager_init(void);
void client_manager_deinit(void);
void client_new(int fd, const struct sockaddr *addr, int uid);
void client_new(int fd, const struct sockaddr *sa, size_t sa_length, int uid);
bool client_is_expired(const struct client *client);
......@@ -45,11 +46,6 @@ unsigned client_get_permission(const struct client *client);
void client_set_permission(struct client *client, unsigned permission);
/**
* Write a block of data to the client.
*/
void client_write(struct client *client, const char *data, size_t length);
/**
* Write a C string to the client.
*/
void client_puts(struct client *client, const char *s);
......
/*
* Copyright (C) 2003-2008 The Music Player Daemon Project
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -11,17 +11,20 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "cmdline.h"
#include "path.h"
#include "log.h"
#include "conf.h"
#include "decoder_list.h"
#include "config.h"
#include "audioOutput.h"
#include "output_list.h"
#include "ls.h"
#ifdef ENABLE_ARCHIVE
#include "archive_list.h"
......@@ -46,18 +49,14 @@ static void version(void)
"This is free software; see the source for copying conditions. There is NO\n"
"warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
"\n"
"Supported formats:\n");
"Supported decoders:\n");
decoder_plugin_init_all();
decoder_plugin_print_all_suffixes(stdout);
puts("\n"
"Supported decoders:\n");
decoder_plugin_print_all_decoders(stdout);
puts("\n"
"Supported outputs:\n");
printAllOutputPluginTypes(stdout);
audio_output_plugin_print_all_types(stdout);
#ifdef ENABLE_ARCHIVE
puts("\n"
......@@ -66,10 +65,14 @@ static void version(void)
archive_plugin_print_all_suffixes(stdout);
#endif
puts("\n"
"Supported protocols:\n");
print_supported_uri_schemes_to_fp(stdout);
exit(EXIT_SUCCESS);
}
#if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 12)
#if GLIB_CHECK_VERSION(2,12,0)
static const char *summary =
"Music Player Daemon - a daemon for playing music.";
#endif
......@@ -80,14 +83,15 @@ void parseOptions(int argc, char **argv, Options *options)
GOptionContext *context;
bool ret;
static gboolean option_version,
option_create_db, option_no_create_db, option_no_daemon;
option_create_db, option_no_create_db, option_no_daemon,
option_no_config;
const GOptionEntry entries[] = {
{ "version", 'V', 0, G_OPTION_ARG_NONE, &option_version,
"print version number", NULL },
{ "kill", 0, 0, G_OPTION_ARG_NONE, &options->kill,
"kill the currently running mpd session", NULL },
{ "create-db", 0, 0, G_OPTION_ARG_NONE, &option_create_db,
"force (re)creation of database", NULL },
{ "kill", 0, 0, G_OPTION_ARG_NONE, &options->kill,
"kill the currently running mpd session", NULL },
{ "no-config", 0, 0, G_OPTION_ARG_NONE, &option_no_config,
"don't read from config", NULL },
{ "no-create-db", 0, 0, G_OPTION_ARG_NONE, &option_no_create_db,
"don't create database, even if it doesn't exist", NULL },
{ "no-daemon", 0, 0, G_OPTION_ARG_NONE, &option_no_daemon,
......@@ -96,6 +100,8 @@ void parseOptions(int argc, char **argv, Options *options)
"print messages to stderr", NULL },
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &options->verbose,
"verbose logging", NULL },
{ "version", 'V', 0, G_OPTION_ARG_NONE, &option_version,
"print version number", NULL },
{ .long_name = NULL }
};
......@@ -108,7 +114,7 @@ void parseOptions(int argc, char **argv, Options *options)
context = g_option_context_new("[path/to/mpd.conf]");
g_option_context_add_main_entries(context, entries, NULL);
#if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 12)
#if GLIB_CHECK_VERSION(2,12,0)
g_option_context_set_summary(context, summary);
#endif
......@@ -123,6 +129,10 @@ void parseOptions(int argc, char **argv, Options *options)
if (option_version)
version();
/* initialize the logging library, so the configuration file
parser can use it already */
log_early_init(options->verbose);
if (option_create_db && option_no_create_db)
g_error("Cannot use both --create-db and --no-create-db\n");
......@@ -133,7 +143,9 @@ void parseOptions(int argc, char **argv, Options *options)
options->daemon = !option_no_daemon;
if (argc <= 1) {
if (option_no_config) {
g_debug("Ignoring config, using daemon defaults\n");
} else if (argc <= 1) {
/* default configuration file path */
char *path1;
char *path2;
......
/*
* Copyright (C) 2003-2008 The Music Player Daemon Project
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef CMDLINE_H
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_COMMAND_H
......@@ -46,7 +47,4 @@ command_process(struct client *client, char *commandString);
void command_success(struct client *client);
G_GNUC_PRINTF(3, 4) void command_error(struct client *client, enum ack error,
const char *fmt, ...);
#endif
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
*
* Compressor logic by
* (c)2003-6 fluffy@beesbuzz.biz
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -14,10 +11,14 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Imported from AudioCompress by J. Shagam <fluffy@beesbuzz.biz>
*/
#include "compress.h"
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
*
* interface to audio compression
* (c)2003-6 fluffy@beesbuzz.biz
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -14,10 +11,14 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Imported from AudioCompress by J. Shagam <fluffy@beesbuzz.biz>
*/
#ifndef MPD_COMPRESS_H
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "conf.h"
......@@ -29,6 +30,9 @@
#include <stdlib.h>
#include <errno.h>
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "config"
#define MAX_STRING_SIZE MPD_PATH_MAX+80
#define CONF_COMMENT '#'
......@@ -55,18 +59,18 @@ static int get_bool(const char *value)
static const char *f[] = { "no", "false", "0", NULL };
for (x = t; *x; x++) {
if (!strcasecmp(*x, value))
if (!g_ascii_strcasecmp(*x, value))
return 1;
}
for (x = f; *x; x++) {
if (!strcasecmp(*x, value))
if (!g_ascii_strcasecmp(*x, value))
return 0;
}
return CONF_BOOL_INVALID;
}
struct config_param *
newConfigParam(const char *value, int line)
config_new_param(const char *value, int line)
{
struct config_param *ret = g_new(struct config_param, 1);
......@@ -83,15 +87,14 @@ newConfigParam(const char *value, int line)
return ret;
}
void
static void
config_param_free(gpointer data, G_GNUC_UNUSED gpointer user_data)
{
struct config_param *param = data;
int i;
g_free(param->value);
for (i = 0; i < param->num_block_params; i++) {
for (unsigned i = 0; i < param->num_block_params; i++) {
g_free(param->block_params[i].name);
g_free(param->block_params[i].value);
}
......@@ -210,12 +213,14 @@ void config_global_init(void)
registerConfigParam(CONF_ID3V1_ENCODING, 0, 0);
registerConfigParam(CONF_METADATA_TO_USE, 0, 0);
registerConfigParam(CONF_SAVE_ABSOLUTE_PATHS, 0, 0);
registerConfigParam(CONF_DECODER, true, true);
registerConfigParam(CONF_INPUT, true, true);
registerConfigParam(CONF_GAPLESS_MP3_PLAYBACK, 0, 0);
}
void
addBlockParam(struct config_param * param, const char *name, const char *value,
int line)
config_add_block_param(struct config_param * param, const char *name,
const char *value, int line)
{
struct block_param *bp;
......@@ -233,9 +238,9 @@ addBlockParam(struct config_param * param, const char *name, const char *value,
}
static struct config_param *
config_read_fileigBlock(FILE * fp, int *count, char *string)
config_read_block(FILE *fp, int *count, char *string)
{
struct config_param *ret = newConfigParam(NULL, *count);
struct config_param *ret = config_new_param(NULL, *count);
int i;
int numberOfArgs;
......@@ -278,7 +283,7 @@ config_read_fileigBlock(FILE * fp, int *count, char *string)
*count, string, ret->line);
}
addBlockParam(ret, array[0], array[1], *count);
config_add_block_param(ret, array[0], array[1], *count);
}
return ret;
......@@ -295,6 +300,8 @@ void config_read_file(const char *file)
struct config_entry *entry;
struct config_param *param;
g_debug("loading file %s", file);
if (!(fp = fopen(file, "r"))) {
g_error("problems opening file %s for reading: %s\n",
file, strerror(errno));
......@@ -341,9 +348,9 @@ void config_read_file(const char *file)
g_error("improperly formatted config file at "
"line %i: %s\n", count, string);
}
param = config_read_fileigBlock(fp, &count, string);
param = config_read_block(fp, &count, string);
} else
param = newConfigParam(array[1], count);
param = config_new_param(array[1], count);
entry->params = g_slist_append(entry->params, param);
}
......@@ -438,15 +445,14 @@ config_get_positive(const char *name, unsigned default_value)
}
struct block_param *
getBlockParam(const struct config_param * param, const char *name)
config_get_block_param(const struct config_param * param, const char *name)
{
struct block_param *ret = NULL;
int i;
if (param == NULL)
return NULL;
for (i = 0; i < param->num_block_params; i++) {
for (unsigned i = 0; i < param->num_block_params; i++) {
if (0 == strcmp(name, param->block_params[i].name)) {
if (ret) {
g_warning("\"%s\" first defined on line %i, and "
......@@ -484,7 +490,7 @@ const char *
config_get_block_string(const struct config_param *param, const char *name,
const char *default_value)
{
struct block_param *bp = getBlockParam(param, name);
struct block_param *bp = config_get_block_param(param, name);
if (bp == NULL)
return default_value;
......@@ -496,7 +502,7 @@ unsigned
config_get_block_unsigned(const struct config_param *param, const char *name,
unsigned default_value)
{
struct block_param *bp = getBlockParam(param, name);
struct block_param *bp = config_get_block_param(param, name);
long value;
char *endptr;
......@@ -517,7 +523,7 @@ bool
config_get_block_bool(const struct config_param *param, const char *name,
bool default_value)
{
struct block_param *bp = getBlockParam(param, name);
struct block_param *bp = config_get_block_param(param, name);
int value;
if (bp == NULL)
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_CONF_H
......@@ -64,6 +65,8 @@
#define CONF_ID3V1_ENCODING "id3v1_encoding"
#define CONF_METADATA_TO_USE "metadata_to_use"
#define CONF_SAVE_ABSOLUTE_PATHS "save_absolute_paths_in_playlists"
#define CONF_DECODER "decoder"
#define CONF_INPUT "input"
#define CONF_GAPLESS_MP3_PLAYBACK "gapless_mp3_playback"
#define CONF_BOOL_UNSET -1
......@@ -83,7 +86,7 @@ struct config_param {
unsigned int line;
struct block_param *block_params;
int num_block_params;
unsigned num_block_params;
};
void config_global_init(void);
......@@ -124,7 +127,7 @@ unsigned
config_get_positive(const char *name, unsigned default_value);
struct block_param *
getBlockParam(const struct config_param *param, const char *name);
config_get_block_param(const struct config_param *param, const char *name);
bool config_get_bool(const char *name, bool default_value);
......@@ -148,11 +151,10 @@ config_get_block_bool(const struct config_param *param, const char *name,
bool default_value);
struct config_param *
newConfigParam(const char *value, int line);
void config_param_free(gpointer data, gpointer user_data);
config_new_param(const char *value, int line);
void
addBlockParam(struct config_param *param, const char *name, const char *value, int line);
config_add_block_param(struct config_param *param, const char *name,
const char *value, int line);
#endif
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* Copyright (C) 2008 Max Kellermann <max@duempel.org>
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -12,14 +11,15 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "crossfade.h"
#include "pcm_mix.h"
#include "pipe.h"
#include "chunk.h"
#include "audio_format.h"
#include "tag.h"
......@@ -58,6 +58,10 @@ void cross_fade_apply(struct music_chunk *a, const struct music_chunk *b,
{
size_t size;
assert(a != NULL);
assert(b != NULL);
assert(a->length == 0 || b->length == 0 ||
audio_format_equals(&a->audio_format, &b->audio_format));
assert(current_chunk <= num_chunks);
if (a->tag == NULL && b->tag != NULL)
......@@ -79,6 +83,12 @@ void cross_fade_apply(struct music_chunk *a, const struct music_chunk *b,
there is unmixed rest at the end. Copy it over.
The output buffer API guarantees that there is
enough room in a->data. */
#ifndef NDEBUG
if (a->length == 0)
a->audio_format = b->audio_format;
#endif
memcpy(a->data + a->length,
b->data + a->length,
b->length - a->length);
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* Copyright (C) 2008 Max Kellermann <max@duempel.org>
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -12,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_CROSSFADE_H
......@@ -23,11 +23,32 @@
struct audio_format;
struct music_chunk;
/**
* Calculate how many music pipe chunks should be used for crossfading.
*
* @param duration the requested crossfade duration
* @param total_time total_time the duration of the new song
* @param af the audio format of the new song
* @param old_format the audio format of the current song
* @param max_chunks the maximum number of chunks
* @return the number of chunks for crossfading, or 0 if cross fading
* should be disabled for this song change
*/
unsigned cross_fade_calc(float duration, float total_time,
const struct audio_format *af,
const struct audio_format *old_format,
unsigned max_chunks);
/**
* Applies cross fading to two chunks, i.e. mixes these chunks.
* Internally, this calls pcm_mix().
*
* @param a the chunk in the current song (and the destination chunk)
* @param b the according chunk in the new song
* @param format the audio format of both chunks (must be the same)
* @param current_chunk the relative index of the current chunk
* @param num_chunks the number of chunks used for cross fading
*/
void cross_fade_apply(struct music_chunk *a, const struct music_chunk *b,
const struct audio_format *format,
unsigned int current_chunk, unsigned int num_chunks);
......
#include "cue_tag.h"
static struct tag*
cue_tag_cd(struct Cdtext* cdtext, struct Rem* rem)
{
char* tmp = NULL;
struct tag* tag = NULL;
//if (cdtext == NULL)
//return NULL;
tag = tag_new();
tag_begin_add(tag);
{ /* TAG_ITEM_ALBUM_ARTIST */
if ((tmp = cdtext_get(PTI_PERFORMER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_ALBUM_ARTIST, tmp);
else if ((tmp = cdtext_get(PTI_SONGWRITER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_ALBUM_ARTIST, tmp);
else if ((tmp = cdtext_get(PTI_COMPOSER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_ALBUM_ARTIST, tmp);
else if ((tmp = cdtext_get(PTI_ARRANGER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_ALBUM_ARTIST, tmp);
/* TAG_ITEM_ALBUM_ARTIST */ }
{ /* TAG_ITEM_ARTIST */
if ((tmp = cdtext_get(PTI_PERFORMER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_ARTIST, tmp);
else if ((tmp = cdtext_get(PTI_SONGWRITER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_ARTIST, tmp);
else if ((tmp = cdtext_get(PTI_COMPOSER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_ARTIST, tmp);
else if ((tmp = cdtext_get(PTI_ARRANGER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_ARTIST, tmp);
/* TAG_ITEM_ARTIST */ }
/* TAG_ITEM_PERFORMER */
if ((tmp = cdtext_get(PTI_PERFORMER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_PERFORMER, tmp);
/* TAG_ITEM_COMPOSER */
if ((tmp = cdtext_get(PTI_COMPOSER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_COMPOSER, tmp);
/* TAG_ITEM_ALBUM */
if ((tmp = cdtext_get(PTI_TITLE, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_ALBUM, tmp);
/* TAG_ITEM_GENRE */
if ((tmp = cdtext_get(PTI_GENRE, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_GENRE, tmp);
/* TAG_ITEM_DATE */
if ((tmp = rem_get(REM_DATE, rem)) != NULL)
tag_add_item(tag, TAG_ITEM_DATE, tmp);
/* TAG_ITEM_COMMENT */
if ((tmp = cdtext_get(PTI_MESSAGE, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_COMMENT, tmp);
/* TAG_ITEM_DISC */
if ((tmp = cdtext_get(PTI_DISC_ID, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_DISC, tmp);
/* stream name, usually empty
* tag_add_item(tag, TAG_ITEM_NAME,);
*/
/* REM MUSICBRAINZ entry?
tag_add_item(tag, TAG_MUSICBRAINZ_ARTISTID,);
tag_add_item(tag, TAG_MUSICBRAINZ_ALBUMID,);
tag_add_item(tag, TAG_MUSICBRAINZ_ALBUMARTISTID,);
tag_add_item(tag, TAG_MUSICBRAINZ_TRACKID,);
*/
tag_end_add(tag);
if (tag != NULL)
{
if (tag_is_empty(tag))
{
tag_free(tag);
return NULL;
}
else
return tag;
}
else
return NULL;
}
static struct tag*
cue_tag_track(struct Cdtext* cdtext, struct Rem* rem)
{
char* tmp = NULL;
struct tag* tag = NULL;
//if (cdtext == NULL)
//return NULL;
tag = tag_new();
tag_begin_add(tag);
{ /* TAG_ITEM_ARTIST */
if ((tmp = cdtext_get(PTI_PERFORMER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_ARTIST, tmp);
else if ((tmp = cdtext_get(PTI_SONGWRITER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_ARTIST, tmp);
else if ((tmp = cdtext_get(PTI_COMPOSER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_ARTIST, tmp);
else if ((tmp = cdtext_get(PTI_ARRANGER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_ARTIST, tmp);
/* TAG_ITEM_ARTIST */ }
/* TAG_ITEM_TITLE */
if ((tmp = cdtext_get(PTI_TITLE, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_TITLE, tmp);
/* TAG_ITEM_GENRE */
if ((tmp = cdtext_get(PTI_GENRE, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_GENRE, tmp);
/* TAG_ITEM_DATE */
if ((tmp = rem_get(REM_DATE, rem)) != NULL)
tag_add_item(tag, TAG_ITEM_DATE, tmp);
/* TAG_ITEM_COMPOSER */
if ((tmp = cdtext_get(PTI_COMPOSER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_COMPOSER, tmp);
/* TAG_ITEM_PERFORMER */
if ((tmp = cdtext_get(PTI_PERFORMER, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_PERFORMER, tmp);
/* TAG_ITEM_COMMENT */
if ((tmp = cdtext_get(PTI_MESSAGE, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_COMMENT, tmp);
/* TAG_ITEM_DISC */
if ((tmp = cdtext_get(PTI_DISC_ID, cdtext)) != NULL)
tag_add_item(tag, TAG_ITEM_DISC, tmp);
tag_end_add(tag);
if (tag != NULL)
{
if (tag_is_empty(tag))
{
tag_free(tag);
return NULL;
}
else
return tag;
}
else
return NULL;
}
struct tag*
cue_tag_file( FILE* fp,
const unsigned int tnum)
{
struct tag* cd_tag = NULL;
struct tag* track_tag = NULL;
struct tag* merge_tag = NULL;
struct Cd* cd = NULL;
if (tnum > 256)
return NULL;
if (fp == NULL)
return NULL;
else
cd = cue_parse_file(fp);
if (cd == NULL)
return NULL;
else
{
/* tag from CDtext info */
cd_tag = cue_tag_cd( cd_get_cdtext(cd),
cd_get_rem(cd));
/* tag from TRACKtext info */
track_tag = cue_tag_track( track_get_cdtext( cd_get_track(cd, tnum)),
track_get_rem( cd_get_track(cd, tnum)));
cd_delete(cd);
}
if ((cd_tag != NULL) && (track_tag != NULL))
{
merge_tag = tag_merge(cd_tag, track_tag);
tag_free(cd_tag);
tag_free(track_tag);
return merge_tag;
}
else if (cd_tag != NULL)
{
return cd_tag;
}
else if (track_tag != NULL)
{
return track_tag;
}
else
return NULL;
}
struct tag*
cue_tag_string( char* str,
const unsigned int tnum)
{
struct tag* cd_tag = NULL;
struct tag* track_tag = NULL;
struct tag* merge_tag = NULL;
struct Cd* cd = NULL;
if (tnum > 256)
return NULL;
if (str == NULL)
return NULL;
else
cd = cue_parse_string(str);
if (cd == NULL)
return NULL;
else
{
/* tag from CDtext info */
cd_tag = cue_tag_cd( cd_get_cdtext(cd),
cd_get_rem(cd));
/* tag from TRACKtext info */
track_tag = cue_tag_track( track_get_cdtext( cd_get_track(cd, tnum)),
track_get_rem( cd_get_track(cd, tnum)));
cd_delete(cd);
}
if ((cd_tag != NULL) && (track_tag != NULL))
{
merge_tag = tag_merge(cd_tag, track_tag);
tag_free(cd_tag);
tag_free(track_tag);
return merge_tag;
}
else if (cd_tag != NULL)
{
return cd_tag;
}
else if (track_tag != NULL)
{
return track_tag;
}
else
return NULL;
}
#ifndef MPD_CUE_TAG_H
#define MPD_CUE_TAG_H
#include "config.h"
#ifdef HAVE_CUE /* libcue */
#include <libcue/libcue.h>
#include "../tag.h"
struct tag*
cue_tag_file( FILE*,
const unsigned int);
struct tag*
cue_tag_string( char*,
const unsigned int);
#endif /* libcue */
#endif
/*
* Copyright (C) 2003-2008 The Music Player Daemon Project
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "daemon.h"
......@@ -35,6 +36,9 @@
#include <grp.h>
#endif
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "daemon"
#ifndef WIN32
/** the Unix user name which MPD runs as */
......@@ -100,32 +104,66 @@ void
daemonize_set_user(void)
{
#ifndef WIN32
if (user_name != NULL) {
/* get uid */
if (setgid(user_gid) == -1) {
g_error("cannot setgid for user \"%s\": %s",
user_name, g_strerror(errno));
}
if (user_name == NULL)
return;
/* get uid */
if (setgid(user_gid) == -1) {
g_error("cannot setgid for user \"%s\": %s",
user_name, g_strerror(errno));
}
#ifdef _BSD_SOURCE
/* init suplementary groups
* (must be done before we change our uid)
*/
if (initgroups(user_name, user_gid) == -1) {
g_warning("cannot init supplementary groups "
"of user \"%s\": %s",
user_name, g_strerror(errno));
}
/* init suplementary groups
* (must be done before we change our uid)
*/
if (initgroups(user_name, user_gid) == -1) {
g_warning("cannot init supplementary groups "
"of user \"%s\": %s",
user_name, g_strerror(errno));
}
#endif
/* set uid */
if (setuid(user_uid) == -1) {
g_error("cannot change to uid of user \"%s\": %s",
user_name, g_strerror(errno));
}
/* set uid */
if (setuid(user_uid) == -1) {
g_error("cannot change to uid of user \"%s\": %s",
user_name, g_strerror(errno));
}
#endif
}
#ifndef G_OS_WIN32
static void
daemonize_detach(void)
{
pid_t pid;
/* flush all file handles before duplicating the buffers */
fflush(NULL);
/* detach from parent process */
pid = fork();
if (pid < 0)
g_error("fork() failed: %s", g_strerror(errno));
if (pid > 0)
/* exit the parent process */
_exit(EXIT_SUCCESS);
/* release the current working directory */
if (chdir("/") < 0)
g_error("problems changing to root directory");
/* detach from the current session */
setsid();
g_debug("daemonized!");
}
#endif
void
daemonize(bool detach)
{
......@@ -143,25 +181,8 @@ daemonize(bool detach)
}
}
if (detach) {
int pid;
fflush(NULL);
pid = fork();
if (pid > 0)
_exit(EXIT_SUCCESS);
else if (pid < 0) {
g_error("problems fork'ing for daemon!");
}
if (chdir("/") < 0) {
g_error("problems changing to root directory");
}
setsid();
g_debug("daemonized!");
}
if (detach)
daemonize_detach();
if (pidfile != NULL) {
g_debug("writing pid file");
......@@ -170,7 +191,7 @@ daemonize(bool detach)
}
#else
/* no daemonization on WIN32 */
(void)options;
(void)detach;
#endif
}
......@@ -178,9 +199,12 @@ void
daemonize_init(const char *user, const char *_pidfile)
{
#ifndef WIN32
user_name = g_strdup(user);
if (user_name != NULL) {
struct passwd *pwd = getpwnam(user_name);
if (user != NULL && strcmp(user, g_get_user_name()) != 0) {
struct passwd *pwd;
user_name = g_strdup(user);
pwd = getpwnam(user_name);
if (pwd == NULL)
g_error("no such user \"%s\"", user_name);
......
/*
* Copyright (C) 2003-2008 The Music Player Daemon Project
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DAEMON_H
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* Copyright (C) 2008 Max Kellermann <max@duempel.org>
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -12,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "database.h"
......@@ -38,11 +38,25 @@
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "database"
#define DIRECTORY_INFO_BEGIN "info_begin"
#define DIRECTORY_INFO_END "info_end"
#define DIRECTORY_MPD_VERSION "mpd_version: "
#define DIRECTORY_FS_CHARSET "fs_charset: "
static char *database_path;
static struct directory *music_root;
static time_t directory_dbModTime;
static time_t database_mtime;
/**
* The quark used for GError.domain.
*/
static inline GQuark
db_quark(void)
{
return g_quark_from_static_string("database");
}
void
db_init(const char *path)
......@@ -90,16 +104,12 @@ db_get_directory(const char *name)
if (name == NULL)
return music_root;
return directory_get_directory(music_root, name);
return directory_lookup_directory(music_root, name);
}
struct song *
db_get_song(const char *file)
{
struct song *song;
struct directory *directory;
char *duplicated, *shortname, *dir;
assert(file != NULL);
g_debug("get song: %s", file);
......@@ -107,27 +117,7 @@ db_get_song(const char *file)
if (music_root == NULL)
return NULL;
duplicated = g_strdup(file);
shortname = strrchr(duplicated, '/');
if (!shortname) {
shortname = duplicated;
dir = NULL;
} else {
*shortname = '\0';
++shortname;
dir = duplicated;
}
directory = db_get_directory(dir);
if (directory != NULL)
song = songvec_find(&directory->songs, shortname);
else
song = NULL;
assert(song == NULL || song->parent == directory);
g_free(duplicated);
return song;
return directory_lookup_song(music_root, file);
}
int
......@@ -256,18 +246,19 @@ db_save(void)
while (fclose(fp) && errno == EINTR);
if (stat(database_path, &st) == 0)
directory_dbModTime = st.st_mtime;
database_mtime = st.st_mtime;
return true;
}
bool
db_load(void)
db_load(GError **error)
{
FILE *fp = NULL;
struct stat st;
char buffer[100];
bool foundFsCharset = false, foundVersion = false;
bool found_charset = false, found_version = false;
bool success;
assert(database_path != NULL);
assert(music_root != NULL);
......@@ -276,21 +267,24 @@ db_load(void)
music_root = directory_new("", NULL);
while (!(fp = fopen(database_path, "r")) && errno == EINTR) ;
if (fp == NULL) {
g_warning("unable to open db file \"%s\": %s",
database_path, strerror(errno));
g_set_error(error, db_quark(), errno,
"Failed to open database file \"%s\": %s",
database_path, strerror(errno));
return false;
}
/* get initial info */
if (!fgets(buffer, sizeof(buffer), fp))
g_error("Error reading db, fgets");
if (!fgets(buffer, sizeof(buffer), fp)) {
fclose(fp);
g_set_error(error, db_quark(), 0, "Unexpected end of file");
return false;
}
g_strchomp(buffer);
if (0 != strcmp(DIRECTORY_INFO_BEGIN, buffer)) {
g_warning("db info not found in db file; "
"you should recreate the db using --create-db");
while (fclose(fp) && errno == EINTR) ;
fclose(fp);
g_set_error(error, db_quark(), 0, "Database corrupted");
return false;
}
......@@ -299,42 +293,57 @@ db_load(void)
g_strchomp(buffer);
if (g_str_has_prefix(buffer, DIRECTORY_MPD_VERSION)) {
if (foundVersion)
g_error("already found version in db");
foundVersion = true;
if (found_version) {
fclose(fp);
g_set_error(error, db_quark(), 0,
"Duplicate version line");
return false;
}
found_version = true;
} else if (g_str_has_prefix(buffer, DIRECTORY_FS_CHARSET)) {
char *fsCharset;
const char *tempCharset;
const char *new_charset, *old_charset;
if (foundFsCharset)
g_error("already found fs charset in db");
if (found_charset) {
fclose(fp);
g_set_error(error, db_quark(), 0,
"Duplicate charset line");
return false;
}
foundFsCharset = true;
found_charset = true;
fsCharset = &(buffer[strlen(DIRECTORY_FS_CHARSET)]);
tempCharset = path_get_fs_charset();
if (tempCharset != NULL
&& strcmp(fsCharset, tempCharset)) {
new_charset = &(buffer[strlen(DIRECTORY_FS_CHARSET)]);
old_charset = path_get_fs_charset();
if (old_charset != NULL
&& strcmp(new_charset, old_charset)) {
fclose(fp);
g_message("Existing database has charset \"%s\" "
"instead of \"%s\"; "
"discarding database file",
fsCharset, tempCharset);
new_charset, old_charset);
return false;
}
} else
g_error("unknown line in db info: %s",
buffer);
} else {
fclose(fp);
g_set_error(error, db_quark(), 0,
"Malformed line: %s", buffer);
return false;
}
}
g_debug("reading DB");
directory_load(fp, music_root);
success = directory_load(fp, music_root, error);
while (fclose(fp) && errno == EINTR) ;
if (!success)
return false;
stats_update();
if (stat(database_path, &st) == 0)
directory_dbModTime = st.st_mtime;
database_mtime = st.st_mtime;
return true;
}
......@@ -342,5 +351,5 @@ db_load(void)
time_t
db_get_mtime(void)
{
return directory_dbModTime;
return database_mtime;
}
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* Copyright (C) 2008 Max Kellermann <max@duempel.org>
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -12,14 +11,17 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_DATABASE_H
#define MPD_DATABASE_H
#include <glib.h>
#include <sys/time.h>
#include <stdbool.h>
......@@ -66,7 +68,7 @@ bool
db_save(void);
bool
db_load(void);
db_load(GError **error);
time_t
db_get_mtime(void);
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "dbUtils.h"
......@@ -26,7 +27,6 @@
#include "song_print.h"
#include "tag.h"
#include "strset.h"
#include "log.h"
#include "stored_playlist.h"
#include <glib.h>
......@@ -233,7 +233,6 @@ static void
visitTag(struct client *client, struct strset *set,
struct song *song, enum tag_type tagType)
{
int i;
struct tag *tag = song->tag;
if (tagType == LOCATE_TAG_FILE_TYPE) {
......@@ -244,12 +243,13 @@ visitTag(struct client *client, struct strset *set,
if (!tag)
return;
for (i = 0; i < tag->numOfItems; i++) {
for (unsigned i = 0; i < tag->num_items; i++) {
if (tag->items[i]->type == tagType) {
strset_add(set, tag->items[i]->value);
return;
}
}
strset_add(set, "");
}
......@@ -294,7 +294,7 @@ int listAllUniqueTags(struct client *client, int type,
while ((value = strset_next(data.set)) != NULL)
client_printf(client, "%s: %s\n",
mpdTagItemKeys[type],
tag_item_names[type],
value);
strset_free(data.set);
......@@ -304,37 +304,3 @@ int listAllUniqueTags(struct client *client, int type,
return ret;
}
static int
sumSavedFilenameMemoryInDirectory(struct directory *dir, void *data)
{
int *sum = data;
if (directory_is_root(dir))
return 0;
*sum += (strlen(directory_get_path(dir)) + 1
- sizeof(struct directory *)) * dir->songs.nr;
return 0;
}
static int
sumSavedFilenameMemoryInSong(struct song *song, void *data)
{
int *sum = data;
*sum += strlen(song->url) + 1;
return 0;
}
void printSavedMemoryFromFilenames(void)
{
int sum = 0;
db_walk(NULL, sumSavedFilenameMemoryInSong,
sumSavedFilenameMemoryInDirectory, (void *)&sum);
DEBUG("saved memory from filenames: %i\n", sum);
}
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_DB_UTILS_H
......@@ -48,6 +49,4 @@ int
listAllUniqueTags(struct client *client, int type,
const struct locate_item_list *criteria);
void printSavedMemoryFromFilenames(void);
#endif
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
*
* Common data structures and functions used by FLAC and OggFLAC
* (c) 2005 by Eric Wong <normalperson@yhbt.net>
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -14,18 +11,20 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Common data structures and functions used by FLAC and OggFLAC
*/
#include "_flac_common.h"
#include <glib.h>
#include <FLAC/format.h>
#include <FLAC/metadata.h>
#include <assert.h>
void
......@@ -101,16 +100,31 @@ flac_parse_replay_gain(const FLAC__StreamMetadata *block,
*/
static const char *
flac_comment_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry,
const char *name, size_t *length_r)
const char *name, const char *char_tnum, size_t *length_r)
{
size_t name_length = strlen(name);
size_t char_tnum_length = 0;
const char *comment = (const char*)entry->entry;
if (entry->length > name_length &&
g_ascii_strncasecmp(comment, name, name_length) == 0 &&
comment[name_length] == '=') {
*length_r = entry->length - name_length - 1;
return comment + name_length + 1;
g_ascii_strncasecmp(comment, name, name_length) == 0) {
if (char_tnum != NULL) {
char_tnum_length = strlen(char_tnum);
if (entry->length > name_length + char_tnum_length + 2 &&
comment[name_length] == '[' &&
g_ascii_strncasecmp(comment + name_length + 1,
char_tnum, char_tnum_length) == 0 &&
comment[name_length + char_tnum_length + 1] == ']')
name_length = name_length + char_tnum_length + 2;
else if (entry->length > name_length + char_tnum_length &&
g_ascii_strncasecmp(comment + name_length,
char_tnum, char_tnum_length) == 0)
name_length = name_length + char_tnum_length;
}
if (comment[name_length] == '=') {
*length_r = entry->length - name_length - 1;
return comment + name_length + 1;
}
}
return NULL;
......@@ -123,12 +137,13 @@ flac_comment_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry,
static bool
flac_copy_comment(struct tag *tag,
const FLAC__StreamMetadata_VorbisComment_Entry *entry,
const char *name, enum tag_type tag_type)
const char *name, enum tag_type tag_type,
const char *char_tnum)
{
const char *value;
size_t value_length;
value = flac_comment_value(entry, name, &value_length);
value = flac_comment_value(entry, name, char_tnum, &value_length);
if (value != NULL) {
tag_add_item_n(tag, tag_type, value, value_length);
return true;
......@@ -143,34 +158,34 @@ static const char *VORBIS_COMMENT_TRACK_KEY = "tracknumber";
static const char *VORBIS_COMMENT_DISC_KEY = "discnumber";
static void
flac_parse_comment(struct tag *tag,
flac_parse_comment(struct tag *tag, const char *char_tnum,
const FLAC__StreamMetadata_VorbisComment_Entry *entry)
{
assert(tag != NULL);
if (flac_copy_comment(tag, entry, VORBIS_COMMENT_TRACK_KEY,
TAG_ITEM_TRACK) ||
TAG_ITEM_TRACK, char_tnum) ||
flac_copy_comment(tag, entry, VORBIS_COMMENT_DISC_KEY,
TAG_ITEM_DISC) ||
TAG_ITEM_DISC, char_tnum) ||
flac_copy_comment(tag, entry, "album artist",
TAG_ITEM_ALBUM_ARTIST))
TAG_ITEM_ALBUM_ARTIST, char_tnum))
return;
for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i)
if (flac_copy_comment(tag, entry,
mpdTagItemKeys[i], i))
tag_item_names[i], i, char_tnum))
return;
}
void
flac_vorbis_comments_to_tag(struct tag *tag,
flac_vorbis_comments_to_tag(struct tag *tag, const char *char_tnum,
const FLAC__StreamMetadata *block)
{
FLAC__StreamMetadata_VorbisComment_Entry *comments =
block->data.vorbis_comment.comments;
for (unsigned i = block->data.vorbis_comment.num_comments; i > 0; --i)
flac_parse_comment(tag, comments++);
flac_parse_comment(tag, char_tnum, comments++);
}
void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
......@@ -187,6 +202,10 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT:
flac_parse_replay_gain(block, data);
if (data->tag != NULL)
flac_vorbis_comments_to_tag(data->tag, NULL, block);
default:
break;
}
......@@ -345,3 +364,54 @@ flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
#if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7
char*
flac_cue_track( const char* pathname,
const unsigned int tnum)
{
FLAC__StreamMetadata* cs = FLAC__metadata_object_new(FLAC__METADATA_TYPE_CUESHEET);
FLAC__metadata_get_cuesheet(pathname, &cs);
if (cs == NULL)
return NULL;
if (cs->data.cue_sheet.num_tracks <= 1)
{
FLAC__metadata_object_delete(cs);
return NULL;
}
if (tnum > 0 && tnum < cs->data.cue_sheet.num_tracks)
{
char* track = g_strdup_printf("track_%03u.flac", tnum);
FLAC__metadata_object_delete(cs);
return track;
}
else
{
FLAC__metadata_object_delete(cs);
return NULL;
}
}
unsigned int
flac_vtrack_tnum(const char* fname)
{
/* find last occurrence of '_' in fname
* which is hopefully something like track_xxx.flac
* another/better way would be to use tag struct
*/
char* ptr = strrchr(fname, '_');
// copy ascii tracknumber to int
char vtrack[4];
g_strlcpy(vtrack, ++ptr, 4);
return (unsigned int)strtol(vtrack, NULL, 10);
}
#endif /* FLAC_API_VERSION_CURRENT >= 7 */
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
*
* Common data structures and functions used by FLAC and OggFLAC
* (c) 2005 by Eric Wong <normalperson@yhbt.net>
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -14,9 +11,14 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Common data structures and functions used by FLAC and OggFLAC
*/
#ifndef MPD_FLAC_COMMON_H
......@@ -168,11 +170,22 @@ void flac_error_common_cb(const char *plugin,
struct flac_data *data);
void
flac_vorbis_comments_to_tag(struct tag *tag,
flac_vorbis_comments_to_tag(struct tag *tag, const char *char_tnum,
const FLAC__StreamMetadata *block);
FLAC__StreamDecoderWriteStatus
flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
const FLAC__int32 *const buf[]);
#if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7
char*
flac_cue_track( const char* pathname,
const unsigned int tnum);
unsigned int
flac_vtrack_tnum( const char*);
#endif /* FLAC_API_VERSION_CURRENT >= 7 */
#endif /* _FLAC_COMMON_H */
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
*
* Common functions used for Ogg data streams (Ogg-Vorbis and OggFLAC)
* (c) 2005 by Eric Wong <normalperson@yhbt.net>
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -14,9 +11,14 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Common functions used for Ogg data streams (Ogg-Vorbis and OggFLAC)
*/
#include "_ogg_common.h"
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
*
* Common functions used for Ogg data streams (Ogg-Vorbis and OggFLAC)
* (c) 2005 by Eric Wong <normalperson@yhbt.net>
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -14,9 +11,14 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Common functions used for Ogg data streams (Ogg-Vorbis and OggFLAC)
*/
#ifndef MPD_OGG_COMMON_H
......
/* the Music Player Daemon (MPD)
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
* This project's homepage is: http://www.musicpd.org
*
* libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net>
*
/*
* Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
......@@ -13,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "../decoder_api.h"
......@@ -31,7 +30,7 @@
/* pick 1020 since its devisible for 8,16,24, and 32-bit audio */
#define CHUNK_SIZE 1020
static int getAudiofileTotalTime(const char *file)
static int audiofile_get_duration(const char *file)
{
int total_time;
AFfilehandle af_fp = afOpenFile(file, "r", NULL);
......@@ -79,7 +78,7 @@ audiofile_file_seek(AFvirtualfile *vfile, long offset, int is_relative)
{
struct input_stream *is = (struct input_stream *) vfile->closure;
int whence = (is_relative ? SEEK_CUR : SEEK_SET);
if (input_stream_seek(is, offset, whence)) {
if (input_stream_seek(is, offset, whence)) {
return is->offset;
} else {
return -1;
......@@ -101,7 +100,7 @@ setup_virtual_fops(struct input_stream *stream)
}
static void
audiofile_streamdecode(struct decoder * decoder, struct input_stream *inStream)
audiofile_stream_decode(struct decoder *decoder, struct input_stream *is)
{
AFvirtualfile *vf;
int fs, frame_count;
......@@ -109,11 +108,17 @@ audiofile_streamdecode(struct decoder * decoder, struct input_stream *inStream)
int bits;
struct audio_format audio_format;
float total_time;
uint16_t bitRate;
uint16_t bit_rate;
int ret, current = 0;
char chunk[CHUNK_SIZE];
enum decoder_command cmd;
if (!is->seekable) {
g_warning("not seekable");
return;
}
vf = setup_virtual_fops(inStream);
vf = setup_virtual_fops(is);
af_fp = afOpenVirtualFile(vf, "r", NULL);
if (af_fp == AF_NULL_FILEHANDLE) {
......@@ -121,8 +126,15 @@ audiofile_streamdecode(struct decoder * decoder, struct input_stream *inStream)
return;
}
afGetSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits);
if (!audio_valid_sample_format(bits)) {
g_debug("input file has %d bit samples, converting to 16",
bits);
bits = 16;
}
afSetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK,
AF_SAMPFMT_TWOSCOMP, 16);
AF_SAMPFMT_TWOSCOMP, bits);
afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits);
audio_format.bits = (uint8_t)bits;
audio_format.sample_rate =
......@@ -142,31 +154,34 @@ audiofile_streamdecode(struct decoder * decoder, struct input_stream *inStream)
total_time = ((float)frame_count / (float)audio_format.sample_rate);
bitRate = (uint16_t)(inStream->size * 8.0 / total_time / 1000.0 + 0.5);
bit_rate = (uint16_t)(is->size * 8.0 / total_time / 1000.0 + 0.5);
fs = (int)afGetVirtualFrameSize(af_fp, AF_DEFAULT_TRACK, 1);
decoder_initialized(decoder, &audio_format, true, total_time);
do {
if (decoder_get_command(decoder) == DECODE_COMMAND_SEEK) {
current = decoder_seek_where(decoder) *
audio_format.sample_rate;
afSeekFrame(af_fp, AF_DEFAULT_TRACK, current);
decoder_command_finished(decoder);
}
ret = afReadFrames(af_fp, AF_DEFAULT_TRACK, chunk,
CHUNK_SIZE / fs);
if (ret <= 0)
break;
current += ret;
decoder_data(decoder, NULL,
chunk, ret * fs,
(float)current / (float)audio_format.sample_rate,
bitRate, NULL);
} while (decoder_get_command(decoder) != DECODE_COMMAND_STOP);
cmd = decoder_data(decoder, NULL,
chunk, ret * fs,
(float)current /
(float)audio_format.sample_rate,
bit_rate, NULL);
if (cmd == DECODE_COMMAND_SEEK) {
current = decoder_seek_where(decoder) *
audio_format.sample_rate;
afSeekFrame(af_fp, AF_DEFAULT_TRACK, current);
decoder_command_finished(decoder);
cmd = DECODE_COMMAND_NONE;
}
} while (cmd == DECODE_COMMAND_NONE);
afCloseFile(af_fp);
}
......@@ -174,7 +189,7 @@ audiofile_streamdecode(struct decoder * decoder, struct input_stream *inStream)
static struct tag *audiofile_tag_dup(const char *file)
{
struct tag *ret = NULL;
int total_time = getAudiofileTotalTime(file);
int total_time = audiofile_get_duration(file);
if (total_time >= 0) {
ret = tag_new();
......@@ -197,9 +212,9 @@ static const char *const audiofile_mime_types[] = {
NULL
};
const struct decoder_plugin audiofilePlugin = {
const struct decoder_plugin audiofile_decoder_plugin = {
.name = "audiofile",
.stream_decode = audiofile_streamdecode,
.stream_decode = audiofile_stream_decode,
.tag_dup = audiofile_tag_dup,
.suffixes = audiofile_suffixes,
.mime_types = audiofile_mime_types,
......
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment