Commit f679b945 authored by Alexey Rusakov's avatar Alexey Rusakov

Merge branch 'upstream' into 'alt-git'

parents 8ec10e2b 8758e977
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
*.lo *.lo
*.o *.o
.deps .deps
.dirstamp
Makefile Makefile
Makefile.in Makefile.in
aclocal.m4 aclocal.m4
...@@ -37,4 +38,15 @@ tags ...@@ -37,4 +38,15 @@ tags
.stgit* .stgit*
doc/protocol.html doc/protocol.html
doc/protocol doc/protocol
doc/user
doc/developer
doc/sticker
doc/api 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> ...@@ -5,31 +5,44 @@ Avuton Olrich <avuton@gmail.com>
release manager release manager
Max Kellermann <max@duempel.org> Max Kellermann <max@duempel.org>
general lead developer
José Anarch <anarchsss@gmail.com>
JACK plugin
Patrik Weiskircher <pat@icore.at>
Stored playlist commands
Laszlo Ashin <kodest@gmail.com> Laszlo Ashin <kodest@gmail.com>
WavPack support WavPack support
Viliam Mateicka <viliam.mateicka@gmail.com> Viliam Mateicka <viliam.mateicka@gmail.com>
FFmpeg support FFmpeg support, mixer and archive API
Eric Wollesen <encoded@xmtp.net> Eric Wollesen <encoded@xmtp.net>
encoder API, shout output encoder API, shout output
Thomas Jansen <mithi@mithi.net> 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 Former Developers
----------------- -----------------
Warren Dukes <warren.dukes@gmail.com> Warren Dukes <warren.dukes@gmail.com>
general former lead developer and project founder
Niklas Hofer Niklas Hofer
'next' and 'previous' patch 'next' and 'previous' patch
...@@ -42,5 +55,16 @@ Guus Sliepen <guus@sliepen.eu.org> ...@@ -42,5 +55,16 @@ Guus Sliepen <guus@sliepen.eu.org>
J. Alexander Treuman <jat@spatialrift.net> J. Alexander Treuman <jat@spatialrift.net>
general, MP3, ID3, PulseAudio, format conversion, stored playlists general, MP3, ID3, PulseAudio, format conversion, stored playlists
AudioCompress, much much more...
Eric Wong 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/ ...@@ -99,7 +99,7 @@ libsidplay2 - http://sidplay2.sourceforge.net/
For C64 SID support. For C64 SID support.
libfluidsynth - http://fluidsynth.resonance.org/ libfluidsynth - http://fluidsynth.resonance.org/
For MIDI support. For MIDI support (DO NOT USE - use libwildmidi instead)
libwildmidi - http://wildmidi.sourceforge.net/ libwildmidi - http://wildmidi.sourceforge.net/
For MIDI support. For MIDI support.
...@@ -120,6 +120,12 @@ For playing HTTP streams. ...@@ -120,6 +120,12 @@ For playing HTTP streams.
libmms - https://launchpad.net/libmms libmms - https://launchpad.net/libmms
For playing MMS streams. For playing MMS streams.
SQLite - http://www.sqlite.org/
For the sticker database.
libcue - http://libcue.sourceforge.net/
For CUE sheet support.
pkg-config pkg-config
---------- ----------
......
ver 0.15 - (200?/??/??) ver 0.15 (2009/06/23)
* input: * input:
- parse Icy-Metadata - parse Icy-Metadata
- added support for the MMS protocol - 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: * tags:
- support the "album artist" tag - support the "album artist" tag
- support MusicBrainz tags - support MusicBrainz tags
- parse RVA2 tags in mp3 files - 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: * decoders:
- audiofile: streaming support added - audiofile: streaming support added
- audiofile: added 24 bit support
- modplug: another MOD plugin, based on libmodplug - modplug: another MOD plugin, based on libmodplug
- mikmod disabled by default, due to severe security issues in libmikmod - mikmod disabled by default, due to severe security issues in libmikmod
- sidplay: new decoder plugin for C64 SID (using libsidplay2) - 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) - 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: * 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 - shout: enlarged buffer size to 32 kB
- null: allow disabling synchronization - 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: * commands:
- "playlistinfo" supports a range now - "playlistinfo" and "move" supports a range now
- added "sticker database", command "sticker", which allows clients - added "sticker database", command "sticker", which allows clients
to implement features like "song rating" to implement features like "song rating"
* Rewritten mixer code to support multiple mixers - 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: * Add audio archive extraction support:
- bzip2 - bzip2
- iso9660 - iso9660
- zip - zip
* the option "error_file" was removed, all messages are logged into * the option "error_file" was removed, all messages are logged into
"log_file" "log_file"
* support logging to syslog * support logging to syslog
* fall back to XDG music directory if no music_directory is configured * fall back to XDG music directory if no music_directory is configured
* failure to read the state file is non-fatal * failure to read the state file is non-fatal
...@@ -34,6 +65,17 @@ ver 0.15 - (200?/??/??) ...@@ -34,6 +65,17 @@ ver 0.15 - (200?/??/??)
* playlist_directory and music_directory are optional * playlist_directory and music_directory are optional
* playlist: recalculate the queued song after random is toggled * playlist: recalculate the queued song after random is toggled
* playlist: don't unpause on delete * 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) 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 = ...@@ -38,7 +38,7 @@ PROJECT_NUMBER =
# If a relative path is entered, it will be relative to the location # 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. # 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 # 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 # 4096 sub-directories (in 2 levels) under the output directory of each output
...@@ -534,7 +534,7 @@ WARN_LOGFILE = ...@@ -534,7 +534,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories # directories like "/usr/src/myproject". Separate the files or directories
# with spaces. # with spaces.
INPUT = ../src INPUT = src
# This tag can be used to specify the character encoding of the source files # 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 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
......
...@@ -158,28 +158,34 @@ distortions. ...@@ -158,28 +158,34 @@ distortions.
Linear Interpolator (4) Linear Interpolator (4)
Linear interpolator, very fast, poor quality. 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 .RE
.IP .IP
For an up-to-date list of available converters, please see the libsamplerate For an up-to-date list of available converters, please see the libsamplerate
documentation (available online at <\fBhttp://www.mega-nerd.com/SRC/\fP>). documentation (available online at <\fBhttp://www.mega-nerd.com/SRC/\fP>).
.TP .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 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 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 legacy and should not be used in new configs, but when set mixer_device
and mixer_control will apply. and mixer_control will apply.
.TP .TP
.B mixer_device <mixer dev> .B mixer_device <mixer dev>
This specifies which mixer to use. The default for oss is "/dev/mixer"; the This specifies which mixer to use. The default for oss is
default for alsa is "default". This option is deprecated and should not be "/dev/mixer"; the default for alsa is "default". This global option is
used. Look at the mixer_device option of corresponding output device instead. deprecated and should not be used. Look at the mixer_device option of
corresponding output device instead.
.TP .TP
.B mixer_control <mixer ctrl> .B mixer_control <mixer ctrl>
This specifies which mixer control to use (sometimes referred to as the This specifies which mixer control to use (sometimes referred to as
"device"). Examples of mixer controls are PCM, Line1, Master, etc. An example the "device"). Examples of mixer controls are PCM, Line1, Master,
for OSS is "Pcm", and an example for alsa is "PCM". This option is deprecated etc. An example for OSS is "Pcm", and an example for alsa is
and should not be used. Look at the mixer_control option of corresponding "PCM". This global option is deprecated and should not be used. Look
output device instead. at the mixer_control option of corresponding output device instead.
.TP .TP
.B replaygain <album or track> .B replaygain <album or track>
If specified, mpd will adjust the volume of songs played using ReplayGain tags 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 ...@@ -205,16 +211,8 @@ The default is 10%, a little over 1 second of CD-quality audio with the default
buffer size. buffer size.
.TP .TP
.B http_proxy_host <hostname> .B http_proxy_host <hostname>
Use to specify the proxy host used for HTTP connections. This setting is deprecated. Use the "proxy" setting in the "curl"
.TP input block. See MPD user manual for details.
.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.
.TP .TP
.B connection_timeout <seconds> .B connection_timeout <seconds>
If a client does not send any new data in this time period, the connection is 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. ...@@ -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". This specifies the device to use for audio output. The default is "default".
.TP .TP
.B mixer_device <mixer dev> .B mixer_device <mixer dev>
This specifies which mixer to use. The default for oss is "/dev/mixer"; the This specifies which mixer to use. The default is "default". To use
default for alsa is "default". the second sound card in a system, use "hw:1".
.TP .TP
.B mixer_control <mixer ctrl> .B mixer_control <mixer ctrl>
This specifies which mixer control to use (sometimes referred to as the This specifies which mixer control to use (sometimes referred to as
"device"). Examples of mixer controls are PCM, Line1, Master, etc. An example the "device"). The default is "PCM". Use "amixer scontrols" to see
for OSS is "Pcm", and an example for alsa is "PCM". 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 .TP
.B use_mmap <yes or no> .B use_mmap <yes or no>
Setting this allows you to use memory-mapped I/O. Certain hardware setups may 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. ...@@ -330,6 +334,13 @@ or 5804 microseconds for CD-quality audio.
.TP .TP
.B device <dev> .B device <dev>
This specifies the device to use for audio output. The default is "/dev/dsp". 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 .SH OPTIONAL PULSE OUTPUT PARAMETERS
.TP .TP
.B server <server list> .B server <server list>
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
<para> <para>
To facilitate faster adding of files etc. you can pass a list To facilitate faster adding of files etc. you can pass a list
of commands all at once using a command list. The command 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_ok_begin</command> and ends with
<command>command_list_end</command>. <command>command_list_end</command>.
</para> </para>
...@@ -62,7 +62,7 @@ ...@@ -62,7 +62,7 @@
<returnvalue>OK</returnvalue> is returned. If a command <returnvalue>OK</returnvalue> is returned. If a command
fails, no more commands are executed and the appropriate fails, no more commands are executed and the appropriate
<returnvalue>ACK</returnvalue> error is returned. If <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 <returnvalue>list_OK</returnvalue> is returned for each
successful command executed in the command list. successful command executed in the command list.
</para> </para>
...@@ -123,6 +123,7 @@ ...@@ -123,6 +123,7 @@
</term> </term>
<listitem> <listitem>
<para> <para>
<footnote id="since_0_14"><simpara>Since MPD 0.14</simpara></footnote>
Waits until there is a noteworthy change in one or more Waits until there is a noteworthy change in one or more
of MPD's subsystems. As soon as there is one, it lists of MPD's subsystems. As soon as there is one, it lists
all changed systems in a line in the format all changed systems in a line in the format
...@@ -190,6 +191,9 @@ ...@@ -190,6 +191,9 @@
MPD will only send notifications when something changed in MPD will only send notifications when something changed in
one of the specified subsytems. one of the specified subsytems.
</para> </para>
<simpara>
Since <application>MPD</application> 0.14
</simpara>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="command_status"> <varlistentry id="command_status">
...@@ -217,6 +221,20 @@ ...@@ -217,6 +221,20 @@
</para> </para>
</listitem> </listitem>
<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> <para>
<varname>playlist</varname>: <varname>playlist</varname>:
<returnvalue>31-bit unsigned integer, the playlist <returnvalue>31-bit unsigned integer, the playlist
...@@ -347,6 +365,22 @@ ...@@ -347,6 +365,22 @@
<title>Playback options</title> <title>Playback options</title>
<variablelist> <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"> <varlistentry id="command_crossfade">
<term> <term>
<cmdsynopsis> <cmdsynopsis>
...@@ -402,6 +436,23 @@ ...@@ -402,6 +436,23 @@
</para> </para>
</listitem> </listitem>
</varlistentry> </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"> <varlistentry id="command_volume">
<term> <term>
<cmdsynopsis> <cmdsynopsis>
...@@ -634,14 +685,21 @@ OK ...@@ -634,14 +685,21 @@ OK
<term> <term>
<cmdsynopsis> <cmdsynopsis>
<command>move</command> <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> <arg choice="req"><replaceable>TO</replaceable></arg>
</cmdsynopsis> </cmdsynopsis>
</term> </term>
<listitem> <listitem>
<para> <para>
Moves the song at <varname>FROM</varname> to Moves the song at <varname>FROM</varname> or range of songs
<varname>TO</varname> in the playlist. 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> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -655,8 +713,8 @@ OK ...@@ -655,8 +713,8 @@ OK
</term> </term>
<listitem> <listitem>
<para> <para>
Moves the song with <varname>FROM</varname> to Moves the song with <varname>FROM</varname> (songid) to
<varname>TO</varname> (both song ids) in the <varname>TO</varname> (playlist index) in the
playlist. If <varname>TO</varname> is negative, it playlist. If <varname>TO</varname> is negative, it
is relative to the current song in the playlist (if is relative to the current song in the playlist (if
there is one). there is one).
...@@ -714,14 +772,19 @@ OK ...@@ -714,14 +772,19 @@ OK
<term> <term>
<cmdsynopsis> <cmdsynopsis>
<command>playlistinfo</command> <command>playlistinfo</command>
<arg><replaceable>SONGPOS</replaceable></arg> <group>
<arg><replaceable>SONGPOS</replaceable></arg>
<arg><replaceable>START:END</replaceable></arg>
</group>
</cmdsynopsis> </cmdsynopsis>
</term> </term>
<listitem> <listitem>
<para> <para>
Displays a list of songs in the playlist. Displays a list of all songs in the playlist, or if the optional
<varname>SONGPOS</varname> is optional and specifies argument is given, displays information only for the song
a single song to display info for. <varname>SONGPOS</varname> or the range of songs
<varname>START:END</varname>
<footnoteref linkend="range_since_0_15"/>
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -782,13 +845,13 @@ OK ...@@ -782,13 +845,13 @@ OK
<term> <term>
<cmdsynopsis> <cmdsynopsis>
<command>shuffle</command> <command>shuffle</command>
<arg><replaceable>SONGRANGE</replaceable></arg> <arg><replaceable>START:END</replaceable></arg>
</cmdsynopsis> </cmdsynopsis>
</term> </term>
<listitem> <listitem>
<para> <para>
Shuffles the current playlist. Shuffles the current playlist.
<varname>SONGRANGE</varname> is optional and specifies <varname>START:END</varname> is optional and specifies
a range of songs. a range of songs.
</para> </para>
</listitem> </listitem>
...@@ -1162,10 +1225,11 @@ OK ...@@ -1162,10 +1225,11 @@ OK
<title>Stickers</title> <title>Stickers</title>
<para> <para>
"Stickers" are pieces of information attached to existing MPD "Stickers"<footnoteref linkend="since_0_15"/> are pieces of
objects (e.g. song files, directories, albums). Clients can information attached to existing MPD objects (e.g. song files,
create arbitrary name/value pairs. MPD itself does not assume directories, albums). Clients can create arbitrary name/value
any special meaning in them. pairs. MPD itself does not assume any special meaning in
them.
</para> </para>
<para> <para>
...@@ -1222,6 +1286,58 @@ OK ...@@ -1222,6 +1286,58 @@ OK
</para> </para>
</listitem> </listitem>
</varlistentry> </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> </variablelist>
</section> </section>
......
...@@ -28,51 +28,64 @@ ...@@ -28,51 +28,64 @@
its easy to change this on the fly, if needed. its easy to change this on the fly, if needed.
</para> </para>
<tag> <variablelist>
<name>rating</name> <varlistentry>
<value>1-5</value> <term><varname>rating</varname></term>
<para> <listitem>
Will store a rating value from 1 (worst) to 5 (best) for a given song. <para>
</para> Will store a rating value from 1 (worst) to 5 (best) for a
</tag> given song.
</para>
</listitem>
</varlistentry>
<tag> <varlistentry>
<name>album_rating</name> <term><varname>album_rating</varname></term>
<value>1-5</value> <listitem>
<para> <para>
Will store a rating value from 1 (worst) to 5 (best) for a given album. Will store a rating value from 1 (worst) to 5 (best) for a
</para> given album.
</tag> </para>
</listitem>
</varlistentry>
<tag> <varlistentry>
<name>style</name> <term><varname>style</varname></term>
<value>Keyword</value> <listitem>
<para> <para>
This tag is used to keep the Genre tag clean, by now having 1000's of genres. This tag is used to keep the Genre tag clean, by now
Instead you define a Main Genre for each file and can make a more specific having 1000's of genres. Instead you define a Main Genre
description. This should be one Keyword like "Post Punk" or "Progressive Death Metal" for each file and can make a more specific
An Alternative name for this tag is "Subgenre", time will tell which one gets description. This should be one Keyword like "Post Punk"
more support. or "Progressive Death Metal" An Alternative name for this
</para> tag is "Subgenre", time will tell which one gets more
</tag> support.
</para>
</listitem>
</varlistentry>
<tag> <varlistentry>
<name>lyrics</name> <term><varname>lyrics</varname></term>
<value>The lyrics of the song, including header with Artist - Title</value> <listitem>
<para> <para>
This one is self explaining. This gives the option to store lyrics of This one is self explaining. This gives the option to
a song where they belong to: mapped to the song store lyrics of a song where they belong to: mapped to the
</para> song
</tag> </para>
</listitem>
</varlistentry>
<tag> <varlistentry>
<name>similar_artists</name> <term><varname>similar_artists</varname> (Comma seperated list of artists)</term>
<value>Comma seperated list of artists</value> <listitem>
<para> <para>
This tag enables a last.fm alike aproach which will still work when being offline This tag enables a last.fm alike aproach which will still
Keep in mind, that this tag is absolutely non-standard! I am not aware of any work when being offline Keep in mind, that this tag is
other player that uses a comparable tag. absolutely non-standard! I am not aware of any other
</para> player that uses a comparable tag.
</tag> </para>
</listitem>
</varlistentry>
</variablelist>
</chapter> </chapter>
</book> </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], ...@@ -6,10 +6,18 @@ AC_DEFUN([AM_PATH_LAME],
[dnl [dnl
dnl Get the cflags and libraries dnl Get the cflags and libraries
dnl dnl
AC_ARG_WITH(lame,[ --with-lame=PFX Prefix where liblame is installed (optional)], lame_prefix="$withval", lame_prefix="") AC_ARG_WITH(lame,
AC_ARG_WITH(lame-libraries,[ --with-lame-libraries=DIR Directory where liblame library is installed (optional)], lame_libraries="$withval", lame_libraries="") AS_HELP_STRING([--with-lame=PFX],
AC_ARG_WITH(lame-includes,[ --with-lame-includes=DIR Directory where liblame header files are installed (optional)], lame_includes="$withval", lame_includes="") [prefix where liblame is installed (optional)]),,
AC_ARG_ENABLE(lametest, [ --disable-lametest Do not try to compile and run a test liblame program],, enable_lametest=yes) 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 if test "x$lame_prefix" != "xno" ; then
...@@ -35,7 +43,6 @@ if test "x$lame_prefix" != "xno" ; then ...@@ -35,7 +43,6 @@ if test "x$lame_prefix" != "xno" ; then
no_lame="" no_lame=""
if test "x$enable_lametest" = "xyes" ; then
ac_save_CFLAGS="$CFLAGS" ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS" ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $LAME_CFLAGS" CFLAGS="$CFLAGS $LAME_CFLAGS"
...@@ -97,10 +104,6 @@ int main () ...@@ -97,10 +104,6 @@ int main ()
fi fi
AC_DEFINE(HAVE_LAME, 1, [Define if you have liblame.]) AC_DEFINE(HAVE_LAME, 1, [Define if you have liblame.])
use_lame="1" use_lame="1"
else
LAME_CFLAGS=""
LAME_LIBS=""
fi
AC_SUBST(LAME_CFLAGS) AC_SUBST(LAME_CFLAGS)
AC_SUBST(LAME_LIBS) AC_SUBST(LAME_LIBS)
rm -f conf.lametest rm -f conf.lametest
......
...@@ -8,10 +8,22 @@ AC_DEFUN([AM_PATH_LIBOGGFLAC], ...@@ -8,10 +8,22 @@ AC_DEFUN([AM_PATH_LIBOGGFLAC],
[dnl [dnl
dnl Get the cflags and libraries dnl Get the cflags and libraries
dnl dnl
AC_ARG_WITH(libOggFLAC,[ --with-libOggFLAC=PFX Prefix where libOggFLAC is installed (optional)], libOggFLAC_prefix="$withval", libOggFLAC_prefix="") AC_ARG_WITH(libOggFLAC,
AC_ARG_WITH(libOggFLAC-libraries,[ --with-libOggFLAC-libraries=DIR Directory where libOggFLAC library is installed (optional)], libOggFLAC_libraries="$withval", libOggFLAC_libraries="") AS_HELP_STRING([--with-libOggFLAC=PFX],
AC_ARG_WITH(libOggFLAC-includes,[ --with-libOggFLAC-includes=DIR Directory where libOggFLAC header files are installed (optional)], libOggFLAC_includes="$withval", libOggFLAC_includes="") [prefix where libOggFLAC is installed (optional)]),,
AC_ARG_ENABLE(libOggFLACtest, [ --disable-libOggFLACtest Do not try to compile and run a test libOggFLAC program],, enable_libOggFLACtest=yes) 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 if test "x$libOggFLAC_libraries" != "x" ; then
LIBOGGFLAC_LIBS="-L$libOggFLAC_libraries" 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],[ ...@@ -12,7 +12,7 @@ AC_DEFUN([MPD_CHECK_FLAG],[
]) ])
if eval "test x`echo '$mpd_check_cflag_'$var` = xyes" if eval "test x`echo '$mpd_check_cflag_'$var` = xyes"
then then
MPD_CFLAGS="$MPD_CFLAGS $1" AM_CFLAGS="$AM_CFLAGS $1"
fi 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 @@ ...@@ -8,6 +8,8 @@
PREFIX=/tmp/mpd PREFIX=/tmp/mpd
rm -rf $PREFIX rm -rf $PREFIX
test "x$MAKE" != x || MAKE=make
export CFLAGS="-Os" export CFLAGS="-Os"
test -x configure || NOCONFIGURE=1 ./autogen.sh test -x configure || NOCONFIGURE=1 ./autogen.sh
...@@ -16,17 +18,17 @@ test -x configure || NOCONFIGURE=1 ./autogen.sh ...@@ -16,17 +18,17 @@ test -x configure || NOCONFIGURE=1 ./autogen.sh
./configure --prefix=$PREFIX/full \ ./configure --prefix=$PREFIX/full \
--disable-dependency-tracking --enable-debug --enable-werror \ --disable-dependency-tracking --enable-debug --enable-werror \
--enable-un \ --enable-un \
--enable-ao --enable-mod --enable-mvp --enable-ao --enable-mikmod --enable-mvp
make -j2 install $MAKE install
make distclean $MAKE distclean
# no UN, no oggvorbis, no flac, enable oggflac # no UN, no oggvorbis, no flac, enable oggflac
./configure --prefix=$PREFIX/small \ ./configure --prefix=$PREFIX/small \
--disable-dependency-tracking --enable-debug --enable-werror \ --disable-dependency-tracking --enable-debug --enable-werror \
--disable-un \ --disable-un \
--disable-flac --disable-oggvorbis --enable-oggflac --disable-flac --disable-vorbis --enable-oggflac
make -j2 install $MAKE install
make distclean $MAKE distclean
# strip down (disable TCP, disable nearly all plugins) # strip down (disable TCP, disable nearly all plugins)
CFLAGS="$CFLAGS -DNDEBUG" \ CFLAGS="$CFLAGS -DNDEBUG" \
...@@ -36,12 +38,13 @@ CFLAGS="$CFLAGS -DNDEBUG" \ ...@@ -36,12 +38,13 @@ CFLAGS="$CFLAGS -DNDEBUG" \
--disable-curl \ --disable-curl \
--disable-id3 --disable-lsr \ --disable-id3 --disable-lsr \
--disable-ao --disable-alsa --disable-jack --disable-pulse --disable-fifo \ --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-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 --with-zeroconf=no
make -j2 install $MAKE install
make distclean $MAKE distclean
# shout: ogg without mp3 # shout: ogg without mp3
./configure --prefix=$PREFIX/shout_ogg \ ./configure --prefix=$PREFIX/shout_ogg \
...@@ -50,12 +53,12 @@ make distclean ...@@ -50,12 +53,12 @@ make distclean
--disable-curl \ --disable-curl \
--disable-id3 --disable-lsr \ --disable-id3 --disable-lsr \
--disable-ao --disable-alsa --disable-jack --disable-pulse --disable-fifo \ --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-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 --with-zeroconf=no
make -j2 install $MAKE install
make distclean $MAKE distclean
# shout: mp3 without ogg # shout: mp3 without ogg
./configure --prefix=$PREFIX/shout_mp3 \ ./configure --prefix=$PREFIX/shout_mp3 \
...@@ -64,12 +67,12 @@ make distclean ...@@ -64,12 +67,12 @@ make distclean
--disable-curl \ --disable-curl \
--disable-id3 --disable-lsr \ --disable-id3 --disable-lsr \
--disable-ao --disable-alsa --disable-jack --disable-pulse --disable-fifo \ --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-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 --with-zeroconf=no
make -j2 install $MAKE install
make distclean $MAKE distclean
# oggvorbis + oggflac # oggvorbis + oggflac
./configure --prefix=$PREFIX/oggvorbisflac \ ./configure --prefix=$PREFIX/oggvorbisflac \
...@@ -79,9 +82,9 @@ make distclean ...@@ -79,9 +82,9 @@ make distclean
--disable-id3 --disable-lsr \ --disable-id3 --disable-lsr \
--disable-mp3 \ --disable-mp3 \
--disable-ao --disable-alsa --disable-jack --disable-pulse --disable-fifo \ --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-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 --with-zeroconf=no
make -j2 install $MAKE install
make distclean $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) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #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> * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 @@ ...@@ -21,7 +22,7 @@
*/ */
#include "archive_api.h" #include "archive_api.h"
#include "input_stream.h" #include "input_plugin.h"
#include "config.h" #include "config.h"
#include <stdint.h> #include <stdint.h>
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2008 Viliam Mateicka <viliam.mateicka@gmail.com> * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 @@ ...@@ -21,7 +22,7 @@
*/ */
#include "archive_api.h" #include "archive_api.h"
#include "input_stream.h" #include "input_plugin.h"
#include <cdio/cdio.h> #include <cdio/cdio.h>
#include <cdio/iso9660.h> #include <cdio/iso9660.h>
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2008 Viliam Mateicka <viliam.mateicka@gmail.com> * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 @@ ...@@ -22,7 +23,7 @@
#include "archive_api.h" #include "archive_api.h"
#include "archive_api.h" #include "archive_api.h"
#include "input_stream.h" #include "input_plugin.h"
#include <zzip/zzip.h> #include <zzip/zzip.h>
#include <glib.h> #include <glib.h>
...@@ -48,7 +49,7 @@ zip_open(char * pathname) ...@@ -48,7 +49,7 @@ zip_open(char * pathname)
// open archive // open archive
context->list = NULL; context->list = NULL;
context->dir = zzip_dir_open(pathname, 0); context->dir = zzip_dir_open(pathname, NULL);
if (context->dir == NULL) { if (context->dir == NULL) {
g_warning("zipfile %s open failed\n", pathname); g_warning("zipfile %s open failed\n", pathname);
return NULL; return NULL;
...@@ -56,7 +57,7 @@ zip_open(char * pathname) ...@@ -56,7 +57,7 @@ zip_open(char * pathname)
while (zzip_dir_read(context->dir, &dirent)) { while (zzip_dir_read(context->dir, &dirent)) {
//add only files //add only files
if (dirent.st_size > 0) { if (dirent.st_size > 0) {
context->list = g_slist_prepend(context->list, context->list = g_slist_prepend(context->list,
g_strdup(dirent.d_name)); g_strdup(dirent.d_name));
} }
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2008 Viliam Mateicka <viliam.mateicka@gmail.com> * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,12 +11,12 @@ ...@@ -11,12 +11,12 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 <stdio.h>
#include <string.h> #include <string.h>
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2008 Viliam Mateicka <viliam.mateicka@gmail.com> * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef MPD_ARCHIVE_API_H
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2008 Viliam Mateicka <viliam.mateicka@gmail.com> * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef MPD_ARCHIVE_INTERNAL_H
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2008 Viliam Mateicka <viliam.mateicka@gmail.com> * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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" #include "archive_list.h"
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2008 Viliam Mateicka <viliam.mateicka@gmail.com> * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef MPD_ARCHIVE_LIST_H
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,17 +11,19 @@ ...@@ -11,17 +11,19 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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.h"
#include "audio_format.h" #include "audio_format.h"
#include "audio_parser.h" #include "audio_parser.h"
#include "output_internal.h" #include "output_internal.h"
#include "output_plugin.h"
#include "output_all.h" #include "output_all.h"
#include "mixer_api.h" #include "conf.h"
#include <glib.h> #include <glib.h>
...@@ -58,43 +60,3 @@ void finishAudioConfig(void) ...@@ -58,43 +60,3 @@ void finishAudioConfig(void)
{ {
audio_format_clear(&configured_audio_format); 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) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef MPD_AUDIO_H
...@@ -31,7 +32,4 @@ void initAudioConfig(void); ...@@ -31,7 +32,4 @@ void initAudioConfig(void);
void finishAudioConfig(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 #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) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef MPD_AUDIO_FORMAT_H
...@@ -59,7 +60,7 @@ audio_valid_sample_rate(unsigned sample_rate) ...@@ -59,7 +60,7 @@ audio_valid_sample_rate(unsigned sample_rate)
static inline bool static inline bool
audio_valid_sample_format(unsigned bits) 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) ...@@ -68,7 +69,7 @@ audio_valid_sample_format(unsigned bits)
static inline bool static inline bool
audio_valid_channel_count(unsigned channels) audio_valid_channel_count(unsigned channels)
{ {
return channels == 1 || channels == 2; return channels >= 1 && channels <= 8;
} }
/** /**
......
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 @@ ...@@ -11,14 +11,15 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
/* /** \file
* Parser functions for audio related objects.
* *
* Parser functions for audio related objects.
*/ */
#ifndef AUDIO_PARSER_H #ifndef AUDIO_PARSER_H
...@@ -30,6 +31,16 @@ ...@@ -30,6 +31,16 @@
struct audio_format; 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 bool
audio_format_parse(struct audio_format *dest, const char *src, GError **error); 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) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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" #include "buffer2array.h"
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #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) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef MPD_CLIENT_H
...@@ -30,7 +31,7 @@ struct sockaddr; ...@@ -30,7 +31,7 @@ struct sockaddr;
void client_manager_init(void); void client_manager_init(void);
void client_manager_deinit(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); bool client_is_expired(const struct client *client);
...@@ -45,11 +46,6 @@ unsigned client_get_permission(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); 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. * Write a C string to the client.
*/ */
void client_puts(struct client *client, const char *s); 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -11,17 +11,20 @@ ...@@ -11,17 +11,20 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 "cmdline.h"
#include "path.h" #include "path.h"
#include "log.h"
#include "conf.h" #include "conf.h"
#include "decoder_list.h" #include "decoder_list.h"
#include "config.h" #include "config.h"
#include "audioOutput.h" #include "output_list.h"
#include "ls.h"
#ifdef ENABLE_ARCHIVE #ifdef ENABLE_ARCHIVE
#include "archive_list.h" #include "archive_list.h"
...@@ -46,18 +49,14 @@ static void version(void) ...@@ -46,18 +49,14 @@ static void version(void)
"This is free software; see the source for copying conditions. There is NO\n" "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" "warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
"\n" "\n"
"Supported formats:\n"); "Supported decoders:\n");
decoder_plugin_init_all(); decoder_plugin_init_all();
decoder_plugin_print_all_suffixes(stdout);
puts("\n"
"Supported decoders:\n");
decoder_plugin_print_all_decoders(stdout); decoder_plugin_print_all_decoders(stdout);
puts("\n" puts("\n"
"Supported outputs:\n"); "Supported outputs:\n");
printAllOutputPluginTypes(stdout); audio_output_plugin_print_all_types(stdout);
#ifdef ENABLE_ARCHIVE #ifdef ENABLE_ARCHIVE
puts("\n" puts("\n"
...@@ -66,10 +65,14 @@ static void version(void) ...@@ -66,10 +65,14 @@ static void version(void)
archive_plugin_print_all_suffixes(stdout); archive_plugin_print_all_suffixes(stdout);
#endif #endif
puts("\n"
"Supported protocols:\n");
print_supported_uri_schemes_to_fp(stdout);
exit(EXIT_SUCCESS); 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 = static const char *summary =
"Music Player Daemon - a daemon for playing music."; "Music Player Daemon - a daemon for playing music.";
#endif #endif
...@@ -80,14 +83,15 @@ void parseOptions(int argc, char **argv, Options *options) ...@@ -80,14 +83,15 @@ void parseOptions(int argc, char **argv, Options *options)
GOptionContext *context; GOptionContext *context;
bool ret; bool ret;
static gboolean option_version, 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[] = { 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, { "create-db", 0, 0, G_OPTION_ARG_NONE, &option_create_db,
"force (re)creation of database", NULL }, "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, { "no-create-db", 0, 0, G_OPTION_ARG_NONE, &option_no_create_db,
"don't create database, even if it doesn't exist", NULL }, "don't create database, even if it doesn't exist", NULL },
{ "no-daemon", 0, 0, G_OPTION_ARG_NONE, &option_no_daemon, { "no-daemon", 0, 0, G_OPTION_ARG_NONE, &option_no_daemon,
...@@ -96,6 +100,8 @@ void parseOptions(int argc, char **argv, Options *options) ...@@ -96,6 +100,8 @@ void parseOptions(int argc, char **argv, Options *options)
"print messages to stderr", NULL }, "print messages to stderr", NULL },
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &options->verbose, { "verbose", 'v', 0, G_OPTION_ARG_NONE, &options->verbose,
"verbose logging", NULL }, "verbose logging", NULL },
{ "version", 'V', 0, G_OPTION_ARG_NONE, &option_version,
"print version number", NULL },
{ .long_name = NULL } { .long_name = NULL }
}; };
...@@ -108,7 +114,7 @@ void parseOptions(int argc, char **argv, Options *options) ...@@ -108,7 +114,7 @@ void parseOptions(int argc, char **argv, Options *options)
context = g_option_context_new("[path/to/mpd.conf]"); context = g_option_context_new("[path/to/mpd.conf]");
g_option_context_add_main_entries(context, entries, NULL); 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); g_option_context_set_summary(context, summary);
#endif #endif
...@@ -123,6 +129,10 @@ void parseOptions(int argc, char **argv, Options *options) ...@@ -123,6 +129,10 @@ void parseOptions(int argc, char **argv, Options *options)
if (option_version) if (option_version)
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) if (option_create_db && option_no_create_db)
g_error("Cannot use both --create-db and --no-create-db\n"); g_error("Cannot use both --create-db and --no-create-db\n");
...@@ -133,7 +143,9 @@ void parseOptions(int argc, char **argv, Options *options) ...@@ -133,7 +143,9 @@ void parseOptions(int argc, char **argv, Options *options)
options->daemon = !option_no_daemon; 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 */ /* default configuration file path */
char *path1; char *path1;
char *path2; char *path2;
......
/* /*
* Copyright (C) 2003-2008 The Music Player Daemon Project * Copyright (C) 2003-2009 The Music Player Daemon Project
* http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef CMDLINE_H
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef MPD_COMMAND_H
...@@ -46,7 +47,4 @@ command_process(struct client *client, char *commandString); ...@@ -46,7 +47,4 @@ command_process(struct client *client, char *commandString);
void command_success(struct client *client); void command_success(struct client *client);
G_GNUC_PRINTF(3, 4) void command_error(struct client *client, enum ack error,
const char *fmt, ...);
#endif #endif
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
*
* Compressor logic by
* (c)2003-6 fluffy@beesbuzz.biz
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -14,10 +11,14 @@ ...@@ -14,10 +11,14 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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" #include "compress.h"
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
*
* interface to audio compression
* (c)2003-6 fluffy@beesbuzz.biz
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -14,10 +11,14 @@ ...@@ -14,10 +11,14 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 #ifndef MPD_COMPRESS_H
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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" #include "conf.h"
...@@ -29,6 +30,9 @@ ...@@ -29,6 +30,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "config"
#define MAX_STRING_SIZE MPD_PATH_MAX+80 #define MAX_STRING_SIZE MPD_PATH_MAX+80
#define CONF_COMMENT '#' #define CONF_COMMENT '#'
...@@ -55,18 +59,18 @@ static int get_bool(const char *value) ...@@ -55,18 +59,18 @@ static int get_bool(const char *value)
static const char *f[] = { "no", "false", "0", NULL }; static const char *f[] = { "no", "false", "0", NULL };
for (x = t; *x; x++) { for (x = t; *x; x++) {
if (!strcasecmp(*x, value)) if (!g_ascii_strcasecmp(*x, value))
return 1; return 1;
} }
for (x = f; *x; x++) { for (x = f; *x; x++) {
if (!strcasecmp(*x, value)) if (!g_ascii_strcasecmp(*x, value))
return 0; return 0;
} }
return CONF_BOOL_INVALID; return CONF_BOOL_INVALID;
} }
struct config_param * 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); struct config_param *ret = g_new(struct config_param, 1);
...@@ -83,15 +87,14 @@ newConfigParam(const char *value, int line) ...@@ -83,15 +87,14 @@ newConfigParam(const char *value, int line)
return ret; return ret;
} }
void static void
config_param_free(gpointer data, G_GNUC_UNUSED gpointer user_data) config_param_free(gpointer data, G_GNUC_UNUSED gpointer user_data)
{ {
struct config_param *param = data; struct config_param *param = data;
int i;
g_free(param->value); 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].name);
g_free(param->block_params[i].value); g_free(param->block_params[i].value);
} }
...@@ -210,12 +213,14 @@ void config_global_init(void) ...@@ -210,12 +213,14 @@ void config_global_init(void)
registerConfigParam(CONF_ID3V1_ENCODING, 0, 0); registerConfigParam(CONF_ID3V1_ENCODING, 0, 0);
registerConfigParam(CONF_METADATA_TO_USE, 0, 0); registerConfigParam(CONF_METADATA_TO_USE, 0, 0);
registerConfigParam(CONF_SAVE_ABSOLUTE_PATHS, 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); registerConfigParam(CONF_GAPLESS_MP3_PLAYBACK, 0, 0);
} }
void void
addBlockParam(struct config_param * param, const char *name, const char *value, config_add_block_param(struct config_param * param, const char *name,
int line) const char *value, int line)
{ {
struct block_param *bp; struct block_param *bp;
...@@ -233,9 +238,9 @@ addBlockParam(struct config_param * param, const char *name, const char *value, ...@@ -233,9 +238,9 @@ addBlockParam(struct config_param * param, const char *name, const char *value,
} }
static struct config_param * 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 i;
int numberOfArgs; int numberOfArgs;
...@@ -278,7 +283,7 @@ config_read_fileigBlock(FILE * fp, int *count, char *string) ...@@ -278,7 +283,7 @@ config_read_fileigBlock(FILE * fp, int *count, char *string)
*count, string, ret->line); *count, string, ret->line);
} }
addBlockParam(ret, array[0], array[1], *count); config_add_block_param(ret, array[0], array[1], *count);
} }
return ret; return ret;
...@@ -295,6 +300,8 @@ void config_read_file(const char *file) ...@@ -295,6 +300,8 @@ void config_read_file(const char *file)
struct config_entry *entry; struct config_entry *entry;
struct config_param *param; struct config_param *param;
g_debug("loading file %s", file);
if (!(fp = fopen(file, "r"))) { if (!(fp = fopen(file, "r"))) {
g_error("problems opening file %s for reading: %s\n", g_error("problems opening file %s for reading: %s\n",
file, strerror(errno)); file, strerror(errno));
...@@ -341,9 +348,9 @@ void config_read_file(const char *file) ...@@ -341,9 +348,9 @@ void config_read_file(const char *file)
g_error("improperly formatted config file at " g_error("improperly formatted config file at "
"line %i: %s\n", count, string); "line %i: %s\n", count, string);
} }
param = config_read_fileigBlock(fp, &count, string); param = config_read_block(fp, &count, string);
} else } else
param = newConfigParam(array[1], count); param = config_new_param(array[1], count);
entry->params = g_slist_append(entry->params, param); entry->params = g_slist_append(entry->params, param);
} }
...@@ -438,15 +445,14 @@ config_get_positive(const char *name, unsigned default_value) ...@@ -438,15 +445,14 @@ config_get_positive(const char *name, unsigned default_value)
} }
struct block_param * 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; struct block_param *ret = NULL;
int i;
if (param == NULL) if (param == NULL)
return 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 (0 == strcmp(name, param->block_params[i].name)) {
if (ret) { if (ret) {
g_warning("\"%s\" first defined on line %i, and " g_warning("\"%s\" first defined on line %i, and "
...@@ -484,7 +490,7 @@ const char * ...@@ -484,7 +490,7 @@ const char *
config_get_block_string(const struct config_param *param, const char *name, config_get_block_string(const struct config_param *param, const char *name,
const char *default_value) const char *default_value)
{ {
struct block_param *bp = getBlockParam(param, name); struct block_param *bp = config_get_block_param(param, name);
if (bp == NULL) if (bp == NULL)
return default_value; return default_value;
...@@ -496,7 +502,7 @@ unsigned ...@@ -496,7 +502,7 @@ unsigned
config_get_block_unsigned(const struct config_param *param, const char *name, config_get_block_unsigned(const struct config_param *param, const char *name,
unsigned default_value) unsigned default_value)
{ {
struct block_param *bp = getBlockParam(param, name); struct block_param *bp = config_get_block_param(param, name);
long value; long value;
char *endptr; char *endptr;
...@@ -517,7 +523,7 @@ bool ...@@ -517,7 +523,7 @@ bool
config_get_block_bool(const struct config_param *param, const char *name, config_get_block_bool(const struct config_param *param, const char *name,
bool default_value) bool default_value)
{ {
struct block_param *bp = getBlockParam(param, name); struct block_param *bp = config_get_block_param(param, name);
int value; int value;
if (bp == NULL) if (bp == NULL)
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef MPD_CONF_H
...@@ -64,6 +65,8 @@ ...@@ -64,6 +65,8 @@
#define CONF_ID3V1_ENCODING "id3v1_encoding" #define CONF_ID3V1_ENCODING "id3v1_encoding"
#define CONF_METADATA_TO_USE "metadata_to_use" #define CONF_METADATA_TO_USE "metadata_to_use"
#define CONF_SAVE_ABSOLUTE_PATHS "save_absolute_paths_in_playlists" #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_GAPLESS_MP3_PLAYBACK "gapless_mp3_playback"
#define CONF_BOOL_UNSET -1 #define CONF_BOOL_UNSET -1
...@@ -83,7 +86,7 @@ struct config_param { ...@@ -83,7 +86,7 @@ struct config_param {
unsigned int line; unsigned int line;
struct block_param *block_params; struct block_param *block_params;
int num_block_params; unsigned num_block_params;
}; };
void config_global_init(void); void config_global_init(void);
...@@ -124,7 +127,7 @@ unsigned ...@@ -124,7 +127,7 @@ unsigned
config_get_positive(const char *name, unsigned default_value); config_get_positive(const char *name, unsigned default_value);
struct block_param * 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); 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, ...@@ -148,11 +151,10 @@ config_get_block_bool(const struct config_param *param, const char *name,
bool default_value); bool default_value);
struct config_param * struct config_param *
newConfigParam(const char *value, int line); config_new_param(const char *value, int line);
void config_param_free(gpointer data, gpointer user_data);
void 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 #endif
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) * Copyright (C) 2003-2009 The Music Player Daemon Project
* Copyright (C) 2008 Max Kellermann <max@duempel.org> * http://www.musicpd.org
* This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -12,14 +11,15 @@ ...@@ -12,14 +11,15 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 "crossfade.h"
#include "pcm_mix.h" #include "pcm_mix.h"
#include "pipe.h" #include "chunk.h"
#include "audio_format.h" #include "audio_format.h"
#include "tag.h" #include "tag.h"
...@@ -58,6 +58,10 @@ void cross_fade_apply(struct music_chunk *a, const struct music_chunk *b, ...@@ -58,6 +58,10 @@ void cross_fade_apply(struct music_chunk *a, const struct music_chunk *b,
{ {
size_t size; 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); assert(current_chunk <= num_chunks);
if (a->tag == NULL && b->tag != NULL) if (a->tag == NULL && b->tag != NULL)
...@@ -79,6 +83,12 @@ void cross_fade_apply(struct music_chunk *a, const struct music_chunk *b, ...@@ -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. there is unmixed rest at the end. Copy it over.
The output buffer API guarantees that there is The output buffer API guarantees that there is
enough room in a->data. */ enough room in a->data. */
#ifndef NDEBUG
if (a->length == 0)
a->audio_format = b->audio_format;
#endif
memcpy(a->data + a->length, memcpy(a->data + a->length,
b->data + a->length, b->data + a->length,
b->length - a->length); b->length - a->length);
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) * Copyright (C) 2003-2009 The Music Player Daemon Project
* Copyright (C) 2008 Max Kellermann <max@duempel.org> * http://www.musicpd.org
* This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -12,9 +11,10 @@ ...@@ -12,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef MPD_CROSSFADE_H
...@@ -23,11 +23,32 @@ ...@@ -23,11 +23,32 @@
struct audio_format; struct audio_format;
struct music_chunk; 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, unsigned cross_fade_calc(float duration, float total_time,
const struct audio_format *af, const struct audio_format *af,
const struct audio_format *old_format, const struct audio_format *old_format,
unsigned max_chunks); 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, void cross_fade_apply(struct music_chunk *a, const struct music_chunk *b,
const struct audio_format *format, const struct audio_format *format,
unsigned int current_chunk, unsigned int num_chunks); 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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" #include "daemon.h"
...@@ -35,6 +36,9 @@ ...@@ -35,6 +36,9 @@
#include <grp.h> #include <grp.h>
#endif #endif
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "daemon"
#ifndef WIN32 #ifndef WIN32
/** the Unix user name which MPD runs as */ /** the Unix user name which MPD runs as */
...@@ -100,32 +104,66 @@ void ...@@ -100,32 +104,66 @@ void
daemonize_set_user(void) daemonize_set_user(void)
{ {
#ifndef WIN32 #ifndef WIN32
if (user_name != NULL) { if (user_name == NULL)
/* get uid */ return;
if (setgid(user_gid) == -1) {
g_error("cannot setgid for user \"%s\": %s", /* get uid */
user_name, g_strerror(errno)); if (setgid(user_gid) == -1) {
} g_error("cannot setgid for user \"%s\": %s",
user_name, g_strerror(errno));
}
#ifdef _BSD_SOURCE #ifdef _BSD_SOURCE
/* init suplementary groups /* init suplementary groups
* (must be done before we change our uid) * (must be done before we change our uid)
*/ */
if (initgroups(user_name, user_gid) == -1) { if (initgroups(user_name, user_gid) == -1) {
g_warning("cannot init supplementary groups " g_warning("cannot init supplementary groups "
"of user \"%s\": %s", "of user \"%s\": %s",
user_name, g_strerror(errno)); user_name, g_strerror(errno));
} }
#endif #endif
/* set uid */ /* set uid */
if (setuid(user_uid) == -1) { if (setuid(user_uid) == -1) {
g_error("cannot change to uid of user \"%s\": %s", g_error("cannot change to uid of user \"%s\": %s",
user_name, g_strerror(errno)); user_name, g_strerror(errno));
}
} }
#endif #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 void
daemonize(bool detach) daemonize(bool detach)
{ {
...@@ -143,25 +181,8 @@ daemonize(bool detach) ...@@ -143,25 +181,8 @@ daemonize(bool detach)
} }
} }
if (detach) { if (detach)
int pid; daemonize_detach();
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 (pidfile != NULL) { if (pidfile != NULL) {
g_debug("writing pid file"); g_debug("writing pid file");
...@@ -170,7 +191,7 @@ daemonize(bool detach) ...@@ -170,7 +191,7 @@ daemonize(bool detach)
} }
#else #else
/* no daemonization on WIN32 */ /* no daemonization on WIN32 */
(void)options; (void)detach;
#endif #endif
} }
...@@ -178,9 +199,12 @@ void ...@@ -178,9 +199,12 @@ void
daemonize_init(const char *user, const char *_pidfile) daemonize_init(const char *user, const char *_pidfile)
{ {
#ifndef WIN32 #ifndef WIN32
user_name = g_strdup(user); if (user != NULL && strcmp(user, g_get_user_name()) != 0) {
if (user_name != NULL) { struct passwd *pwd;
struct passwd *pwd = getpwnam(user_name);
user_name = g_strdup(user);
pwd = getpwnam(user_name);
if (pwd == NULL) if (pwd == NULL)
g_error("no such user \"%s\"", user_name); 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 * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef DAEMON_H
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) * Copyright (C) 2003-2009 The Music Player Daemon Project
* Copyright (C) 2008 Max Kellermann <max@duempel.org> * http://www.musicpd.org
* This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -12,9 +11,10 @@ ...@@ -12,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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" #include "database.h"
...@@ -38,11 +38,25 @@ ...@@ -38,11 +38,25 @@
#undef G_LOG_DOMAIN #undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "database" #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 char *database_path;
static struct directory *music_root; 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 void
db_init(const char *path) db_init(const char *path)
...@@ -90,16 +104,12 @@ db_get_directory(const char *name) ...@@ -90,16 +104,12 @@ db_get_directory(const char *name)
if (name == NULL) if (name == NULL)
return music_root; return music_root;
return directory_get_directory(music_root, name); return directory_lookup_directory(music_root, name);
} }
struct song * struct song *
db_get_song(const char *file) db_get_song(const char *file)
{ {
struct song *song;
struct directory *directory;
char *duplicated, *shortname, *dir;
assert(file != NULL); assert(file != NULL);
g_debug("get song: %s", file); g_debug("get song: %s", file);
...@@ -107,27 +117,7 @@ db_get_song(const char *file) ...@@ -107,27 +117,7 @@ db_get_song(const char *file)
if (music_root == NULL) if (music_root == NULL)
return NULL; return NULL;
duplicated = g_strdup(file); return directory_lookup_song(music_root, 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;
} }
int int
...@@ -256,18 +246,19 @@ db_save(void) ...@@ -256,18 +246,19 @@ db_save(void)
while (fclose(fp) && errno == EINTR); while (fclose(fp) && errno == EINTR);
if (stat(database_path, &st) == 0) if (stat(database_path, &st) == 0)
directory_dbModTime = st.st_mtime; database_mtime = st.st_mtime;
return true; return true;
} }
bool bool
db_load(void) db_load(GError **error)
{ {
FILE *fp = NULL; FILE *fp = NULL;
struct stat st; struct stat st;
char buffer[100]; char buffer[100];
bool foundFsCharset = false, foundVersion = false; bool found_charset = false, found_version = false;
bool success;
assert(database_path != NULL); assert(database_path != NULL);
assert(music_root != NULL); assert(music_root != NULL);
...@@ -276,21 +267,24 @@ db_load(void) ...@@ -276,21 +267,24 @@ db_load(void)
music_root = directory_new("", NULL); music_root = directory_new("", NULL);
while (!(fp = fopen(database_path, "r")) && errno == EINTR) ; while (!(fp = fopen(database_path, "r")) && errno == EINTR) ;
if (fp == NULL) { if (fp == NULL) {
g_warning("unable to open db file \"%s\": %s", g_set_error(error, db_quark(), errno,
database_path, strerror(errno)); "Failed to open database file \"%s\": %s",
database_path, strerror(errno));
return false; return false;
} }
/* get initial info */ /* get initial info */
if (!fgets(buffer, sizeof(buffer), fp)) if (!fgets(buffer, sizeof(buffer), fp)) {
g_error("Error reading db, fgets"); fclose(fp);
g_set_error(error, db_quark(), 0, "Unexpected end of file");
return false;
}
g_strchomp(buffer); g_strchomp(buffer);
if (0 != strcmp(DIRECTORY_INFO_BEGIN, buffer)) { if (0 != strcmp(DIRECTORY_INFO_BEGIN, buffer)) {
g_warning("db info not found in db file; " fclose(fp);
"you should recreate the db using --create-db"); g_set_error(error, db_quark(), 0, "Database corrupted");
while (fclose(fp) && errno == EINTR) ;
return false; return false;
} }
...@@ -299,42 +293,57 @@ db_load(void) ...@@ -299,42 +293,57 @@ db_load(void)
g_strchomp(buffer); g_strchomp(buffer);
if (g_str_has_prefix(buffer, DIRECTORY_MPD_VERSION)) { if (g_str_has_prefix(buffer, DIRECTORY_MPD_VERSION)) {
if (foundVersion) if (found_version) {
g_error("already found version in db"); fclose(fp);
foundVersion = true; 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)) { } else if (g_str_has_prefix(buffer, DIRECTORY_FS_CHARSET)) {
char *fsCharset; const char *new_charset, *old_charset;
const char *tempCharset;
if (foundFsCharset) if (found_charset) {
g_error("already found fs charset in db"); 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)]); new_charset = &(buffer[strlen(DIRECTORY_FS_CHARSET)]);
tempCharset = path_get_fs_charset(); old_charset = path_get_fs_charset();
if (tempCharset != NULL if (old_charset != NULL
&& strcmp(fsCharset, tempCharset)) { && strcmp(new_charset, old_charset)) {
fclose(fp);
g_message("Existing database has charset \"%s\" " g_message("Existing database has charset \"%s\" "
"instead of \"%s\"; " "instead of \"%s\"; "
"discarding database file", "discarding database file",
fsCharset, tempCharset); new_charset, old_charset);
return false; return false;
} }
} else } else {
g_error("unknown line in db info: %s", fclose(fp);
buffer); g_set_error(error, db_quark(), 0,
"Malformed line: %s", buffer);
return false;
}
} }
g_debug("reading DB"); g_debug("reading DB");
directory_load(fp, music_root); success = directory_load(fp, music_root, error);
while (fclose(fp) && errno == EINTR) ; while (fclose(fp) && errno == EINTR) ;
if (!success)
return false;
stats_update(); stats_update();
if (stat(database_path, &st) == 0) if (stat(database_path, &st) == 0)
directory_dbModTime = st.st_mtime; database_mtime = st.st_mtime;
return true; return true;
} }
...@@ -342,5 +351,5 @@ db_load(void) ...@@ -342,5 +351,5 @@ db_load(void)
time_t time_t
db_get_mtime(void) 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) 2003-2009 The Music Player Daemon Project
* Copyright (C) 2008 Max Kellermann <max@duempel.org> * http://www.musicpd.org
* This project's homepage is: http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -12,14 +11,17 @@ ...@@ -12,14 +11,17 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef MPD_DATABASE_H
#define MPD_DATABASE_H #define MPD_DATABASE_H
#include <glib.h>
#include <sys/time.h> #include <sys/time.h>
#include <stdbool.h> #include <stdbool.h>
...@@ -66,7 +68,7 @@ bool ...@@ -66,7 +68,7 @@ bool
db_save(void); db_save(void);
bool bool
db_load(void); db_load(GError **error);
time_t time_t
db_get_mtime(void); db_get_mtime(void);
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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" #include "dbUtils.h"
...@@ -26,7 +27,6 @@ ...@@ -26,7 +27,6 @@
#include "song_print.h" #include "song_print.h"
#include "tag.h" #include "tag.h"
#include "strset.h" #include "strset.h"
#include "log.h"
#include "stored_playlist.h" #include "stored_playlist.h"
#include <glib.h> #include <glib.h>
...@@ -233,7 +233,6 @@ static void ...@@ -233,7 +233,6 @@ static void
visitTag(struct client *client, struct strset *set, visitTag(struct client *client, struct strset *set,
struct song *song, enum tag_type tagType) struct song *song, enum tag_type tagType)
{ {
int i;
struct tag *tag = song->tag; struct tag *tag = song->tag;
if (tagType == LOCATE_TAG_FILE_TYPE) { if (tagType == LOCATE_TAG_FILE_TYPE) {
...@@ -244,12 +243,13 @@ visitTag(struct client *client, struct strset *set, ...@@ -244,12 +243,13 @@ visitTag(struct client *client, struct strset *set,
if (!tag) if (!tag)
return; return;
for (i = 0; i < tag->numOfItems; i++) { for (unsigned i = 0; i < tag->num_items; i++) {
if (tag->items[i]->type == tagType) { if (tag->items[i]->type == tagType) {
strset_add(set, tag->items[i]->value); strset_add(set, tag->items[i]->value);
return; return;
} }
} }
strset_add(set, ""); strset_add(set, "");
} }
...@@ -294,7 +294,7 @@ int listAllUniqueTags(struct client *client, int type, ...@@ -294,7 +294,7 @@ int listAllUniqueTags(struct client *client, int type,
while ((value = strset_next(data.set)) != NULL) while ((value = strset_next(data.set)) != NULL)
client_printf(client, "%s: %s\n", client_printf(client, "%s: %s\n",
mpdTagItemKeys[type], tag_item_names[type],
value); value);
strset_free(data.set); strset_free(data.set);
...@@ -304,37 +304,3 @@ int listAllUniqueTags(struct client *client, int type, ...@@ -304,37 +304,3 @@ int listAllUniqueTags(struct client *client, int type,
return ret; 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) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -11,9 +11,10 @@ ...@@ -11,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef MPD_DB_UTILS_H
...@@ -48,6 +49,4 @@ int ...@@ -48,6 +49,4 @@ int
listAllUniqueTags(struct client *client, int type, listAllUniqueTags(struct client *client, int type,
const struct locate_item_list *criteria); const struct locate_item_list *criteria);
void printSavedMemoryFromFilenames(void);
#endif #endif
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
*
* Common data structures and functions used by FLAC and OggFLAC
* (c) 2005 by Eric Wong <normalperson@yhbt.net>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -14,18 +11,20 @@ ...@@ -14,18 +11,20 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 "_flac_common.h"
#include <glib.h> #include <glib.h>
#include <FLAC/format.h>
#include <FLAC/metadata.h>
#include <assert.h> #include <assert.h>
void void
...@@ -101,16 +100,31 @@ flac_parse_replay_gain(const FLAC__StreamMetadata *block, ...@@ -101,16 +100,31 @@ flac_parse_replay_gain(const FLAC__StreamMetadata *block,
*/ */
static const char * static const char *
flac_comment_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry, 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 name_length = strlen(name);
size_t char_tnum_length = 0;
const char *comment = (const char*)entry->entry; const char *comment = (const char*)entry->entry;
if (entry->length > name_length && if (entry->length > name_length &&
g_ascii_strncasecmp(comment, name, name_length) == 0 && g_ascii_strncasecmp(comment, name, name_length) == 0) {
comment[name_length] == '=') { if (char_tnum != NULL) {
*length_r = entry->length - name_length - 1; char_tnum_length = strlen(char_tnum);
return comment + name_length + 1; 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; return NULL;
...@@ -123,12 +137,13 @@ flac_comment_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry, ...@@ -123,12 +137,13 @@ flac_comment_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry,
static bool static bool
flac_copy_comment(struct tag *tag, flac_copy_comment(struct tag *tag,
const FLAC__StreamMetadata_VorbisComment_Entry *entry, 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; const char *value;
size_t value_length; 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) { if (value != NULL) {
tag_add_item_n(tag, tag_type, value, value_length); tag_add_item_n(tag, tag_type, value, value_length);
return true; return true;
...@@ -143,34 +158,34 @@ static const char *VORBIS_COMMENT_TRACK_KEY = "tracknumber"; ...@@ -143,34 +158,34 @@ static const char *VORBIS_COMMENT_TRACK_KEY = "tracknumber";
static const char *VORBIS_COMMENT_DISC_KEY = "discnumber"; static const char *VORBIS_COMMENT_DISC_KEY = "discnumber";
static void static void
flac_parse_comment(struct tag *tag, flac_parse_comment(struct tag *tag, const char *char_tnum,
const FLAC__StreamMetadata_VorbisComment_Entry *entry) const FLAC__StreamMetadata_VorbisComment_Entry *entry)
{ {
assert(tag != NULL); assert(tag != NULL);
if (flac_copy_comment(tag, entry, VORBIS_COMMENT_TRACK_KEY, 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, flac_copy_comment(tag, entry, VORBIS_COMMENT_DISC_KEY,
TAG_ITEM_DISC) || TAG_ITEM_DISC, char_tnum) ||
flac_copy_comment(tag, entry, "album artist", flac_copy_comment(tag, entry, "album artist",
TAG_ITEM_ALBUM_ARTIST)) TAG_ITEM_ALBUM_ARTIST, char_tnum))
return; return;
for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i) for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i)
if (flac_copy_comment(tag, entry, if (flac_copy_comment(tag, entry,
mpdTagItemKeys[i], i)) tag_item_names[i], i, char_tnum))
return; return;
} }
void 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) const FLAC__StreamMetadata *block)
{ {
FLAC__StreamMetadata_VorbisComment_Entry *comments = FLAC__StreamMetadata_VorbisComment_Entry *comments =
block->data.vorbis_comment.comments; block->data.vorbis_comment.comments;
for (unsigned i = block->data.vorbis_comment.num_comments; i > 0; --i) 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, void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
...@@ -187,6 +202,10 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block, ...@@ -187,6 +202,10 @@ void flac_metadata_common_cb(const FLAC__StreamMetadata * block,
break; break;
case FLAC__METADATA_TYPE_VORBIS_COMMENT: case FLAC__METADATA_TYPE_VORBIS_COMMENT:
flac_parse_replay_gain(block, data); flac_parse_replay_gain(block, data);
if (data->tag != NULL)
flac_vorbis_comments_to_tag(data->tag, NULL, block);
default: default:
break; break;
} }
...@@ -345,3 +364,54 @@ flac_common_write(struct flac_data *data, const FLAC__Frame * frame, ...@@ -345,3 +364,54 @@ flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; 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) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
*
* Common data structures and functions used by FLAC and OggFLAC
* (c) 2005 by Eric Wong <normalperson@yhbt.net>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -14,9 +11,14 @@ ...@@ -14,9 +11,14 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef MPD_FLAC_COMMON_H
...@@ -168,11 +170,22 @@ void flac_error_common_cb(const char *plugin, ...@@ -168,11 +170,22 @@ void flac_error_common_cb(const char *plugin,
struct flac_data *data); struct flac_data *data);
void 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); const FLAC__StreamMetadata *block);
FLAC__StreamDecoderWriteStatus FLAC__StreamDecoderWriteStatus
flac_common_write(struct flac_data *data, const FLAC__Frame * frame, flac_common_write(struct flac_data *data, const FLAC__Frame * frame,
const FLAC__int32 *const buf[]); 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 */ #endif /* _FLAC_COMMON_H */
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
*
* Common functions used for Ogg data streams (Ogg-Vorbis and OggFLAC)
* (c) 2005 by Eric Wong <normalperson@yhbt.net>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -14,9 +11,14 @@ ...@@ -14,9 +11,14 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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" #include "_ogg_common.h"
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
*
* Common functions used for Ogg data streams (Ogg-Vorbis and OggFLAC)
* (c) 2005 by Eric Wong <normalperson@yhbt.net>
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -14,9 +11,14 @@ ...@@ -14,9 +11,14 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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 #ifndef MPD_OGG_COMMON_H
......
/* the Music Player Daemon (MPD) /*
* Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com) * Copyright (C) 2003-2009 The Music Player Daemon Project
* This project's homepage is: http://www.musicpd.org * http://www.musicpd.org
* *
* libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net>
*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
...@@ -13,9 +11,10 @@ ...@@ -13,9 +11,10 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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 * You should have received a copy of the GNU General Public License along
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 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" #include "../decoder_api.h"
...@@ -31,7 +30,7 @@ ...@@ -31,7 +30,7 @@
/* pick 1020 since its devisible for 8,16,24, and 32-bit audio */ /* pick 1020 since its devisible for 8,16,24, and 32-bit audio */
#define CHUNK_SIZE 1020 #define CHUNK_SIZE 1020
static int getAudiofileTotalTime(const char *file) static int audiofile_get_duration(const char *file)
{ {
int total_time; int total_time;
AFfilehandle af_fp = afOpenFile(file, "r", NULL); AFfilehandle af_fp = afOpenFile(file, "r", NULL);
...@@ -79,7 +78,7 @@ audiofile_file_seek(AFvirtualfile *vfile, long offset, int is_relative) ...@@ -79,7 +78,7 @@ audiofile_file_seek(AFvirtualfile *vfile, long offset, int is_relative)
{ {
struct input_stream *is = (struct input_stream *) vfile->closure; struct input_stream *is = (struct input_stream *) vfile->closure;
int whence = (is_relative ? SEEK_CUR : SEEK_SET); 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; return is->offset;
} else { } else {
return -1; return -1;
...@@ -101,7 +100,7 @@ setup_virtual_fops(struct input_stream *stream) ...@@ -101,7 +100,7 @@ setup_virtual_fops(struct input_stream *stream)
} }
static void static void
audiofile_streamdecode(struct decoder * decoder, struct input_stream *inStream) audiofile_stream_decode(struct decoder *decoder, struct input_stream *is)
{ {
AFvirtualfile *vf; AFvirtualfile *vf;
int fs, frame_count; int fs, frame_count;
...@@ -109,11 +108,17 @@ audiofile_streamdecode(struct decoder * decoder, struct input_stream *inStream) ...@@ -109,11 +108,17 @@ audiofile_streamdecode(struct decoder * decoder, struct input_stream *inStream)
int bits; int bits;
struct audio_format audio_format; struct audio_format audio_format;
float total_time; float total_time;
uint16_t bitRate; uint16_t bit_rate;
int ret, current = 0; int ret, current = 0;
char chunk[CHUNK_SIZE]; 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); af_fp = afOpenVirtualFile(vf, "r", NULL);
if (af_fp == AF_NULL_FILEHANDLE) { if (af_fp == AF_NULL_FILEHANDLE) {
...@@ -121,8 +126,15 @@ audiofile_streamdecode(struct decoder * decoder, struct input_stream *inStream) ...@@ -121,8 +126,15 @@ audiofile_streamdecode(struct decoder * decoder, struct input_stream *inStream)
return; 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, afSetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK,
AF_SAMPFMT_TWOSCOMP, 16); AF_SAMPFMT_TWOSCOMP, bits);
afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits); afGetVirtualSampleFormat(af_fp, AF_DEFAULT_TRACK, &fs, &bits);
audio_format.bits = (uint8_t)bits; audio_format.bits = (uint8_t)bits;
audio_format.sample_rate = audio_format.sample_rate =
...@@ -142,31 +154,34 @@ audiofile_streamdecode(struct decoder * decoder, struct input_stream *inStream) ...@@ -142,31 +154,34 @@ audiofile_streamdecode(struct decoder * decoder, struct input_stream *inStream)
total_time = ((float)frame_count / (float)audio_format.sample_rate); 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); fs = (int)afGetVirtualFrameSize(af_fp, AF_DEFAULT_TRACK, 1);
decoder_initialized(decoder, &audio_format, true, total_time); decoder_initialized(decoder, &audio_format, true, total_time);
do { 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, ret = afReadFrames(af_fp, AF_DEFAULT_TRACK, chunk,
CHUNK_SIZE / fs); CHUNK_SIZE / fs);
if (ret <= 0) if (ret <= 0)
break; break;
current += ret; current += ret;
decoder_data(decoder, NULL, cmd = decoder_data(decoder, NULL,
chunk, ret * fs, chunk, ret * fs,
(float)current / (float)audio_format.sample_rate, (float)current /
bitRate, NULL); (float)audio_format.sample_rate,
} while (decoder_get_command(decoder) != DECODE_COMMAND_STOP); 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); afCloseFile(af_fp);
} }
...@@ -174,7 +189,7 @@ audiofile_streamdecode(struct decoder * decoder, struct input_stream *inStream) ...@@ -174,7 +189,7 @@ audiofile_streamdecode(struct decoder * decoder, struct input_stream *inStream)
static struct tag *audiofile_tag_dup(const char *file) static struct tag *audiofile_tag_dup(const char *file)
{ {
struct tag *ret = NULL; struct tag *ret = NULL;
int total_time = getAudiofileTotalTime(file); int total_time = audiofile_get_duration(file);
if (total_time >= 0) { if (total_time >= 0) {
ret = tag_new(); ret = tag_new();
...@@ -197,9 +212,9 @@ static const char *const audiofile_mime_types[] = { ...@@ -197,9 +212,9 @@ static const char *const audiofile_mime_types[] = {
NULL NULL
}; };
const struct decoder_plugin audiofilePlugin = { const struct decoder_plugin audiofile_decoder_plugin = {
.name = "audiofile", .name = "audiofile",
.stream_decode = audiofile_streamdecode, .stream_decode = audiofile_stream_decode,
.tag_dup = audiofile_tag_dup, .tag_dup = audiofile_tag_dup,
.suffixes = audiofile_suffixes, .suffixes = audiofile_suffixes,
.mime_types = audiofile_mime_types, .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