Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
7fe0a63d
Commit
7fe0a63d
authored
Sep 03, 2009
by
Alexey Rusakov
Browse files
Options
Browse Files
Download
Plain Diff
Merge commit 'release-0.15.3' into alt-git
parents
55ebbbcd
7a690c6b
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
439 additions
and
109 deletions
+439
-109
Makefile.am
Makefile.am
+3
-1
NEWS
NEWS
+35
-0
configure.ac
configure.ac
+7
-10
mpd.conf.5
doc/mpd.conf.5
+2
-2
protocol.xml
doc/protocol.xml
+19
-1
user.xml
doc/user.xml
+212
-3
database.c
src/database.c
+5
-4
_flac_common.c
src/decoder/_flac_common.c
+63
-55
flac_plugin.c
src/decoder/flac_plugin.c
+1
-2
mad_plugin.c
src/decoder/mad_plugin.c
+28
-6
vorbis_plugin.c
src/decoder/vorbis_plugin.c
+1
-1
directory.c
src/directory.c
+8
-3
log.c
src/log.c
+2
-6
httpd_output_plugin.c
src/output/httpd_output_plugin.c
+1
-4
shout_plugin.c
src/output/shout_plugin.c
+7
-0
output_all.c
src/output_all.c
+0
-2
output_control.c
src/output_control.c
+11
-0
output_init.c
src/output_init.c
+1
-0
output_internal.h
src/output_internal.h
+6
-0
output_thread.c
src/output_thread.c
+8
-1
song.c
src/song.c
+1
-0
tag_ape.c
src/tag_ape.c
+8
-4
update.c
src/update.c
+10
-4
No files found.
Makefile.am
View file @
7fe0a63d
...
@@ -599,7 +599,6 @@ noinst_PROGRAMS = \
...
@@ -599,7 +599,6 @@ noinst_PROGRAMS = \
test
/run_input
\
test
/run_input
\
test
/run_decoder
\
test
/run_decoder
\
test
/read_tags
\
test
/read_tags
\
test
/run_encoder
\
test
/run_output
\
test
/run_output
\
test
/read_mixer
\
test
/read_mixer
\
test
/software_volume
test
/software_volume
...
@@ -662,6 +661,8 @@ test_read_tags_SOURCES = test/read_tags.c \
...
@@ -662,6 +661,8 @@ test_read_tags_SOURCES = test/read_tags.c \
$(TAG_SRC)
\
$(TAG_SRC)
\
$(DECODER_SRC)
$(DECODER_SRC)
if
ENABLE_ENCODER
noinst_PROGRAMS
+=
test
/run_encoder
test_run_encoder_SOURCES
=
test
/run_encoder.c
\
test_run_encoder_SOURCES
=
test
/run_encoder.c
\
src/conf.c src/buffer2array.c
\
src/conf.c src/buffer2array.c
\
src/utils.c
\
src/utils.c
\
...
@@ -671,6 +672,7 @@ test_run_encoder_SOURCES = test/run_encoder.c \
...
@@ -671,6 +672,7 @@ test_run_encoder_SOURCES = test/run_encoder.c \
test_run_encoder_LDADD
=
$(MPD_LIBS)
\
test_run_encoder_LDADD
=
$(MPD_LIBS)
\
$(ENCODER_LIBS)
\
$(ENCODER_LIBS)
\
$(GLIB_LIBS)
$(GLIB_LIBS)
endif
test_software_volume_SOURCES
=
test
/software_volume.c
\
test_software_volume_SOURCES
=
test
/software_volume.c
\
src/audio_parser.c
\
src/audio_parser.c
\
...
...
NEWS
View file @
7fe0a63d
ver 0.15.3 (2009/08/29)
* decoders:
- vorbis: faster tag scanning with ov_test_callback()
* output:
- fix stuttering due to uninitialized variable
* update: don't re-read unchanged container files
ver 0.15.2 (2009/08/15)
* tags:
- ape: check the tag size (fixes integer underflow)
- ape: added protection against large memory allocations
* decoders:
- mad: skip ID3 frames when libid3tag is disabled
- flac: parse all replaygain tags
- flac: don't allocate cuesheet twice (memleak)
* output:
- shout: fixed stuck pause bug
- shout: minimize the unpause latency
* update: free empty path string (memleak)
* update: free temporary string in container scan (memleak)
* directory: free empty directories after removing them (memleak)
ver 0.15.1 (2009/07/15)
* decoders:
- flac: fix assertion failure in tag_free() call
* output:
- httpd: include sys/types.h (fixes Mac OS X)
* commands:
- don't resume playback when stopping during pause
* database: fixed NULL pointer dereference after charset change
* log: fix double free() bug during shutdown
ver 0.15 (2009/06/23)
ver 0.15 (2009/06/23)
* input:
* input:
- parse Icy-Metadata
- parse Icy-Metadata
...
...
configure.ac
View file @
7fe0a63d
AC_PREREQ(2.60)
AC_PREREQ(2.60)
AC_INIT(mpd, 0.15, musicpd-dev-team@lists.sourceforge.net)
AC_INIT(mpd, 0.15
.3
, musicpd-dev-team@lists.sourceforge.net)
AC_CONFIG_SRCDIR([src/main.c])
AC_CONFIG_SRCDIR([src/main.c])
AM_INIT_AUTOMAKE([foreign 1.9 dist-bzip2])
AM_INIT_AUTOMAKE([foreign 1.9 dist-bzip2])
AM_CONFIG_HEADER(config.h)
AM_CONFIG_HEADER(config.h)
...
@@ -397,9 +397,9 @@ AC_ARG_ENABLE(audiofile,
...
@@ -397,9 +397,9 @@ AC_ARG_ENABLE(audiofile,
enable_audiofile=yes)
enable_audiofile=yes)
AC_ARG_ENABLE(ffmpeg,
AC_ARG_ENABLE(ffmpeg,
AS_HELP_STRING([--
dis
able-ffmpeg],
AS_HELP_STRING([--
en
able-ffmpeg],
[enable FFMPEG support
(default: enable)
]),,
[enable FFMPEG support]),,
enable_ffmpeg=
yes
)
enable_ffmpeg=
auto
)
AC_ARG_ENABLE(flac,
AC_ARG_ENABLE(flac,
AS_HELP_STRING([--disable-flac],
AS_HELP_STRING([--disable-flac],
...
@@ -591,8 +591,7 @@ dnl audio output plugins
...
@@ -591,8 +591,7 @@ dnl audio output plugins
dnl
dnl
AC_ARG_ENABLE(alsa,
AC_ARG_ENABLE(alsa,
AS_HELP_STRING([--enable-alsa],
AS_HELP_STRING([--enable-alsa], [enable ALSA support]),,
[disable ALSA support]),,
enable_alsa=auto)
enable_alsa=auto)
AC_ARG_ENABLE(ao,
AC_ARG_ENABLE(ao,
...
@@ -914,10 +913,8 @@ fi
...
@@ -914,10 +913,8 @@ fi
AM_CONDITIONAL(HAVE_AUDIOFILE, test x$enable_audiofile = xyes)
AM_CONDITIONAL(HAVE_AUDIOFILE, test x$enable_audiofile = xyes)
if test x$enable_ffmpeg = xyes; then
MPD_AUTO_PKG(ffmpeg, FFMPEG, [libavformat libavcodec libavutil],
PKG_CHECK_MODULES(FFMPEG, [libavformat libavcodec libavutil],,
[ffmpeg decoder library], [libavformat+libavcodec+libavutil not found])
enable_ffmpeg=no)
fi
if test x$enable_ffmpeg = xyes; then
if test x$enable_ffmpeg = xyes; then
old_LIBS=$LIBS
old_LIBS=$LIBS
...
...
doc/mpd.conf.5
View file @
7fe0a63d
...
@@ -35,8 +35,8 @@ You must recreate the database after changing this option.
...
@@ -35,8 +35,8 @@ You must recreate the database after changing this option.
The default is "yes".
The default is "yes".
.TP
.TP
.B follow_inside_symlinks <yes or no>
.B follow_inside_symlinks <yes or no>
Control if MPD will follow symbolic links pointing
outside the music dir, potentially
Control if MPD will follow symbolic links pointing
inside the music dir,
adding duplicates to the database.
potentially
adding duplicates to the database.
You must recreate the database after changing this option.
You must recreate the database after changing this option.
The default is "yes".
The default is "yes".
.TP
.TP
...
...
doc/protocol.xml
View file @
7fe0a63d
...
@@ -134,7 +134,7 @@
...
@@ -134,7 +134,7 @@
<listitem>
<listitem>
<para>
<para>
<returnvalue>
database
</returnvalue>
: the song database
<returnvalue>
database
</returnvalue>
: the song database
has been
updated
has been
modified after
<command>
update
</command>
.
</para>
</para>
</listitem>
</listitem>
<listitem>
<listitem>
...
@@ -272,6 +272,24 @@
...
@@ -272,6 +272,24 @@
</listitem>
</listitem>
<listitem>
<listitem>
<para>
<para>
<varname>
nextsong
</varname>
:
<footnoteref
linkend=
"since_0_15"
/>
<returnvalue>
playlist song number of the next
song to be played
</returnvalue>
</para>
</listitem>
<listitem>
<para>
<varname>
nextsongid
</varname>
:
<footnoteref
linkend=
"since_0_15"
/>
<returnvalue>
playlist songid of the next song
to be played
</returnvalue>
</para>
</listitem>
<listitem>
<para>
<varname>
time
</varname>
:
<varname>
time
</varname>
:
<returnvalue>
total time elapsed (of current
<returnvalue>
total time elapsed (of current
playing/paused song)
</returnvalue>
playing/paused song)
</returnvalue>
...
...
doc/user.xml
View file @
7fe0a63d
...
@@ -11,6 +11,30 @@
...
@@ -11,6 +11,30 @@
This document is work in progress. Most of it may be incomplete
This document is work in progress. Most of it may be incomplete
yet. Please help!
yet. Please help!
</para>
</para>
<para>
MPD (Music Player Daemon) is, as the name suggests, a server
software allowing you to remotely play your music, handle
playlists, deliver music (HTTP STREAMS with various
sub-protocols) and organizze playlists.
</para>
<para>
It has been written with minimal resource usage and stability in
mind! Infact, it runs fine on a Pentium 75, allowing you to use
your cheap old PC to create a stereo system!
</para>
<para>
MPD supports also Gapless playback, buffered audio output, and
crossfading!
</para>
<para>
The separate client and server design allows users to choose a
user interface that best suites their tastes independently of
the underlying daemon, which actually plays music!
</para>
</chapter>
</chapter>
<chapter>
<chapter>
...
@@ -26,10 +50,16 @@
...
@@ -26,10 +50,16 @@
<title>
Installing on Debian/Ubuntu
</title>
<title>
Installing on Debian/Ubuntu
</title>
<para>
<para>
Install the package
<filename>
mpd
</filename>
:
Install the package
<filename>
mpd
</filename>
via APT
:
</para>
</para>
<programlisting>
apt-get install mpd
</programlisting>
<programlisting>
apt-get install mpd
</programlisting>
<para>
When installed this way, MPD by default looks for music in
/var/lib/mpd/music/; this may not be correct. Look at your
/etc/mpd.conf file...
</para>
</section>
</section>
<section>
<section>
...
@@ -41,8 +71,8 @@
...
@@ -41,8 +71,8 @@
page
</ulink>
and unpack it:
page
</ulink>
and unpack it:
</para>
</para>
<programlisting>
tar xjf mpd-
0.14.2
.tar.bz
<programlisting>
tar xjf mpd-
version
.tar.bz
cd mpd-
0.14.2
</programlisting>
cd mpd-
version
</programlisting>
<para>
<para>
Make sure that all the required libraries and build tools are
Make sure that all the required libraries and build tools are
...
@@ -678,6 +708,28 @@ cd mpd-0.14.2</programlisting>
...
@@ -678,6 +708,28 @@ cd mpd-0.14.2</programlisting>
The
<varname>
pipe
</varname>
plugin starts a program and
The
<varname>
pipe
</varname>
plugin starts a program and
writes raw PCM data into its standard input.
writes raw PCM data into its standard input.
</para>
</para>
<informaltable>
<tgroup
cols=
"2"
>
<thead>
<row>
<entry>
Setting
</entry>
<entry>
Description
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<varname>
command
</varname>
<parameter>
CMD
</parameter>
</entry>
<entry>
This command is invoked with the shell.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
</section>
<section>
<section>
...
@@ -687,6 +739,40 @@ cd mpd-0.14.2</programlisting>
...
@@ -687,6 +739,40 @@ cd mpd-0.14.2</programlisting>
The
<varname>
pulse
</varname>
plugin connects to a PulseAudio
The
<varname>
pulse
</varname>
plugin connects to a PulseAudio
server.
server.
</para>
</para>
<informaltable>
<tgroup
cols=
"2"
>
<thead>
<row>
<entry>
Setting
</entry>
<entry>
Description
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<varname>
server
</varname>
<parameter>
HOSTNAME
</parameter>
</entry>
<entry>
Sets the host name of the PulseAudio server. By
default, MPD connects to the local PulseAudio
server.
</entry>
</row>
<row>
<entry>
<varname>
sink
</varname>
<parameter>
NAME
</parameter>
</entry>
<entry>
Specifies the name of the PulseAudio sink MPD should
play on.
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
</section>
<section>
<section>
...
@@ -696,6 +782,129 @@ cd mpd-0.14.2</programlisting>
...
@@ -696,6 +782,129 @@ cd mpd-0.14.2</programlisting>
The
<varname>
shout
</varname>
plugin connects to a ShoutCast
The
<varname>
shout
</varname>
plugin connects to a ShoutCast
or IceCast server. It forwards tags to this server.
or IceCast server. It forwards tags to this server.
</para>
</para>
<para>
You must set a
<varname>
format
</varname>
.
</para>
<informaltable>
<tgroup
cols=
"2"
>
<thead>
<row>
<entry>
Setting
</entry>
<entry>
Description
</entry>
</row>
</thead>
<tbody>
<row>
<entry>
<varname>
host
</varname>
<parameter>
HOSTNAME
</parameter>
</entry>
<entry>
Sets the host name of the Shoutcast/Icecast server.
</entry>
</row>
<row>
<entry>
<varname>
port
</varname>
<parameter>
PORTNUMBER
</parameter>
</entry>
<entry>
Connect to this port number on the specified host.
</entry>
</row>
<row>
<entry>
<varname>
timeout
</varname>
<parameter>
SECONDS
</parameter>
</entry>
<entry>
Set the timeout for the shout connection in seconds.
Defaults to 2 seconds.
</entry>
</row>
<row>
<entry>
<varname>
mount
</varname>
<parameter>
URI
</parameter>
</entry>
<entry>
Mounts the MPD stream in the specified URI.
</entry>
</row>
<row>
<entry>
<varname>
user
</varname>
<parameter>
USERNAME
</parameter>
</entry>
<entry>
Sets the user name for submitting the stream to the
server. Default is "source".
</entry>
</row>
<row>
<entry>
<varname>
password
</varname>
<parameter>
PWD
</parameter>
</entry>
<entry>
Sets the password for submitting the stream to the
server.
</entry>
</row>
<row>
<entry>
<varname>
name
</varname>
<parameter>
NAME
</parameter>
</entry>
<entry>
Sets the name of the stream.
</entry>
</row>
<row>
<entry>
<varname>
genre
</varname>
<parameter>
GENRE
</parameter>
</entry>
<entry>
Sets the genre of the stream (optional).
</entry>
</row>
<row>
<entry>
<varname>
description
</varname>
<parameter>
DESCRIPTION
</parameter>
</entry>
<entry>
Sets a short description of the stream (optional).
</entry>
</row>
<row>
<entry>
<varname>
public
</varname>
<parameter>
yes|no
</parameter>
</entry>
<entry>
Specifies whether the stream should be "public".
Default is "no".
</entry>
</row>
<row>
<entry>
<varname>
encoder
</varname>
<parameter>
PLUGIN
</parameter>
</entry>
<entry>
Sets the name of the encoder plugin. Default is
"vorbis". "vorbis" and "lame" are valid encoder
plugins (provided that you enabled them at compile
time).
</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</section>
</section>
<section>
<section>
...
...
src/database.c
View file @
7fe0a63d
...
@@ -318,10 +318,11 @@ db_load(GError **error)
...
@@ -318,10 +318,11 @@ db_load(GError **error)
if
(
old_charset
!=
NULL
if
(
old_charset
!=
NULL
&&
strcmp
(
new_charset
,
old_charset
))
{
&&
strcmp
(
new_charset
,
old_charset
))
{
fclose
(
fp
);
fclose
(
fp
);
g_message
(
"Existing database has charset
\"
%s
\"
"
g_set_error
(
error
,
db_quark
(),
0
,
"instead of
\"
%s
\"
; "
"Existing database has charset "
"discarding database file"
,
"
\"
%s
\"
instead of
\"
%s
\"
; "
new_charset
,
old_charset
);
"discarding database file"
,
new_charset
,
old_charset
);
return
false
;
return
false
;
}
}
}
else
{
}
else
{
...
...
src/decoder/_flac_common.c
View file @
7fe0a63d
...
@@ -40,53 +40,57 @@ flac_data_init(struct flac_data *data, struct decoder * decoder,
...
@@ -40,53 +40,57 @@ flac_data_init(struct flac_data *data, struct decoder * decoder,
data
->
tag
=
NULL
;
data
->
tag
=
NULL
;
}
}
static
bool
static
void
flac_find_float_comment
(
const
FLAC__StreamMetadata
*
block
,
flac_find_float_comment
(
const
FLAC__StreamMetadata
*
block
,
const
char
*
cmnt
,
float
*
fl
)
const
char
*
cmnt
,
float
*
fl
,
bool
*
found_r
)
{
{
int
offset
=
int
offset
;
FLAC__metadata_object_vorbiscomment_find_entry_from
(
block
,
0
,
cmnt
);
size_t
pos
;
int
len
;
if
(
offset
>=
0
)
{
unsigned
char
tmp
,
*
p
;
size_t
pos
=
strlen
(
cmnt
)
+
1
;
/* 1 is for '=' */
int
len
=
block
->
data
.
vorbis_comment
.
comments
[
offset
].
length
offset
=
FLAC__metadata_object_vorbiscomment_find_entry_from
(
block
,
0
,
-
pos
;
cmnt
);
if
(
len
>
0
)
{
if
(
offset
<
0
)
unsigned
char
tmp
;
return
;
unsigned
char
*
p
=
&
(
block
->
data
.
vorbis_comment
.
comments
[
offset
].
entry
[
pos
]);
tmp
=
p
[
len
];
p
[
len
]
=
'\0'
;
*
fl
=
(
float
)
atof
((
char
*
)
p
);
p
[
len
]
=
tmp
;
return
true
;
}
}
return
false
;
pos
=
strlen
(
cmnt
)
+
1
;
/* 1 is for '=' */
len
=
block
->
data
.
vorbis_comment
.
comments
[
offset
].
length
-
pos
;
if
(
len
<=
0
)
return
;
p
=
&
block
->
data
.
vorbis_comment
.
comments
[
offset
].
entry
[
pos
];
tmp
=
p
[
len
];
p
[
len
]
=
'\0'
;
*
fl
=
(
float
)
atof
((
char
*
)
p
);
p
[
len
]
=
tmp
;
*
found_r
=
true
;
}
}
/* replaygain stuff by AliasMrJones */
static
void
static
void
flac_parse_replay_gain
(
const
FLAC__StreamMetadata
*
block
,
flac_parse_replay_gain
(
const
FLAC__StreamMetadata
*
block
,
struct
flac_data
*
data
)
struct
flac_data
*
data
)
{
{
bool
found
;
bool
found
=
false
;
if
(
data
->
replay_gain_info
)
if
(
data
->
replay_gain_info
)
replay_gain_info_free
(
data
->
replay_gain_info
);
replay_gain_info_free
(
data
->
replay_gain_info
);
data
->
replay_gain_info
=
replay_gain_info_new
();
data
->
replay_gain_info
=
replay_gain_info_new
();
found
=
flac_find_float_comment
(
block
,
"replaygain_album_gain"
,
flac_find_float_comment
(
block
,
"replaygain_album_gain"
,
&
data
->
replay_gain_info
->
tuples
[
REPLAY_GAIN_ALBUM
].
gain
)
||
&
data
->
replay_gain_info
->
tuples
[
REPLAY_GAIN_ALBUM
].
gain
,
flac_find_float_comment
(
block
,
"replaygain_album_peak"
,
&
found
);
&
data
->
replay_gain_info
->
tuples
[
REPLAY_GAIN_ALBUM
].
peak
)
||
flac_find_float_comment
(
block
,
"replaygain_album_peak"
,
flac_find_float_comment
(
block
,
"replaygain_track_gain"
,
&
data
->
replay_gain_info
->
tuples
[
REPLAY_GAIN_ALBUM
].
peak
,
&
data
->
replay_gain_info
->
tuples
[
REPLAY_GAIN_TRACK
].
gain
)
||
&
found
);
flac_find_float_comment
(
block
,
"replaygain_track_peak"
,
flac_find_float_comment
(
block
,
"replaygain_track_gain"
,
&
data
->
replay_gain_info
->
tuples
[
REPLAY_GAIN_TRACK
].
peak
);
&
data
->
replay_gain_info
->
tuples
[
REPLAY_GAIN_TRACK
].
gain
,
&
found
);
flac_find_float_comment
(
block
,
"replaygain_track_peak"
,
&
data
->
replay_gain_info
->
tuples
[
REPLAY_GAIN_TRACK
].
peak
,
&
found
);
if
(
!
found
)
{
if
(
!
found
)
{
replay_gain_info_free
(
data
->
replay_gain_info
);
replay_gain_info_free
(
data
->
replay_gain_info
);
...
@@ -106,25 +110,27 @@ flac_comment_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry,
...
@@ -106,25 +110,27 @@ flac_comment_value(const FLAC__StreamMetadata_VorbisComment_Entry *entry,
size_t
char_tnum_length
=
0
;
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
)
if
(
char_tnum
!=
NULL
)
{
return
NULL
;
char_tnum_length
=
strlen
(
char_tnum
);
if
(
entry
->
length
>
name_length
+
char_tnum_length
+
2
&&
if
(
char_tnum
!=
NULL
)
{
comment
[
name_length
]
==
'['
&&
char_tnum_length
=
strlen
(
char_tnum
);
g_ascii_strncasecmp
(
comment
+
name_length
+
1
,
if
(
entry
->
length
>
name_length
+
char_tnum_length
+
2
&&
char_tnum
,
char_tnum_length
)
==
0
&&
comment
[
name_length
]
==
'['
&&
comment
[
name_length
+
char_tnum_length
+
1
]
==
']'
)
g_ascii_strncasecmp
(
comment
+
name_length
+
1
,
name_length
=
name_length
+
char_tnum_length
+
2
;
char_tnum
,
char_tnum_length
)
==
0
&&
else
if
(
entry
->
length
>
name_length
+
char_tnum_length
&&
comment
[
name_length
+
char_tnum_length
+
1
]
==
']'
)
g_ascii_strncasecmp
(
comment
+
name_length
,
name_length
=
name_length
+
char_tnum_length
+
2
;
char_tnum
,
char_tnum_length
)
==
0
)
else
if
(
entry
->
length
>
name_length
+
char_tnum_length
&&
name_length
=
name_length
+
char_tnum_length
;
g_ascii_strncasecmp
(
comment
+
name_length
,
}
char_tnum
,
char_tnum_length
)
==
0
)
if
(
comment
[
name_length
]
==
'='
)
{
name_length
=
name_length
+
char_tnum_length
;
*
length_r
=
entry
->
length
-
name_length
-
1
;
}
return
comment
+
name_length
+
1
;
}
if
(
comment
[
name_length
]
==
'='
)
{
*
length_r
=
entry
->
length
-
name_length
-
1
;
return
comment
+
name_length
+
1
;
}
}
return
NULL
;
return
NULL
;
...
@@ -371,13 +377,15 @@ char*
...
@@ -371,13 +377,15 @@ char*
flac_cue_track
(
const
char
*
pathname
,
flac_cue_track
(
const
char
*
pathname
,
const
unsigned
int
tnum
)
const
unsigned
int
tnum
)
{
{
FLAC__StreamMetadata
*
cs
=
FLAC__metadata_object_new
(
FLAC__METADATA_TYPE_CUESHEET
);
FLAC__bool
success
;
FLAC__StreamMetadata
*
cs
;
FLAC__metadata_get_cuesheet
(
pathname
,
&
cs
);
success
=
FLAC__metadata_get_cuesheet
(
pathname
,
&
cs
);
if
(
!
success
)
if
(
cs
==
NULL
)
return
NULL
;
return
NULL
;
assert
(
cs
!=
NULL
);
if
(
cs
->
data
.
cue_sheet
.
num_tracks
<=
1
)
if
(
cs
->
data
.
cue_sheet
.
num_tracks
<=
1
)
{
{
FLAC__metadata_object_delete
(
cs
);
FLAC__metadata_object_delete
(
cs
);
...
...
src/decoder/flac_plugin.c
View file @
7fe0a63d
...
@@ -394,6 +394,7 @@ flac_decode_internal(struct decoder * decoder,
...
@@ -394,6 +394,7 @@ flac_decode_internal(struct decoder * decoder,
if
(
!
(
flac_dec
=
flac_new
()))
if
(
!
(
flac_dec
=
flac_new
()))
return
;
return
;
flac_data_init
(
&
data
,
decoder
,
input_stream
);
flac_data_init
(
&
data
,
decoder
,
input_stream
);
data
.
tag
=
tag_new
();
#if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7
#if defined(FLAC_API_VERSION_CURRENT) && FLAC_API_VERSION_CURRENT > 7
if
(
!
FLAC__stream_decoder_set_metadata_respond
(
flac_dec
,
FLAC__METADATA_TYPE_VORBIS_COMMENT
))
if
(
!
FLAC__stream_decoder_set_metadata_respond
(
flac_dec
,
FLAC__METADATA_TYPE_VORBIS_COMMENT
))
...
@@ -422,8 +423,6 @@ flac_decode_internal(struct decoder * decoder,
...
@@ -422,8 +423,6 @@ flac_decode_internal(struct decoder * decoder,
}
}
}
}
data
.
tag
=
tag_new
();
if
(
!
flac_process_metadata
(
flac_dec
))
{
if
(
!
flac_process_metadata
(
flac_dec
))
{
err
=
"problem reading metadata"
;
err
=
"problem reading metadata"
;
goto
fail
;
goto
fail
;
...
...
src/decoder/mad_plugin.c
View file @
7fe0a63d
...
@@ -350,11 +350,11 @@ parse_id3_replay_gain_info(struct id3_tag *tag)
...
@@ -350,11 +350,11 @@ parse_id3_replay_gain_info(struct id3_tag *tag)
}
}
#endif
#endif
#ifdef HAVE_ID3TAG
static
void
mp3_parse_id3
(
struct
mp3_data
*
data
,
size_t
tagsize
,
static
void
mp3_parse_id3
(
struct
mp3_data
*
data
,
size_t
tagsize
,
struct
tag
**
mpd_tag
,
struct
tag
**
mpd_tag
,
struct
replay_gain_info
**
replay_gain_info_r
)
struct
replay_gain_info
**
replay_gain_info_r
)
{
{
#ifdef HAVE_ID3TAG
struct
id3_tag
*
id3_tag
=
NULL
;
struct
id3_tag
*
id3_tag
=
NULL
;
id3_length_t
count
;
id3_length_t
count
;
id3_byte_t
const
*
id3_data
;
id3_byte_t
const
*
id3_data
;
...
@@ -418,8 +418,34 @@ static void mp3_parse_id3(struct mp3_data *data, size_t tagsize,
...
@@ -418,8 +418,34 @@ static void mp3_parse_id3(struct mp3_data *data, size_t tagsize,
id3_tag_delete
(
id3_tag
);
id3_tag_delete
(
id3_tag
);
g_free
(
allocated
);
g_free
(
allocated
);
}
#else
/* !HAVE_ID3TAG */
(
void
)
mpd_tag
;
(
void
)
replay_gain_info_r
;
/* This code is enabled when libid3tag is disabled. Instead
of parsing the ID3 frame, it just skips it. */
mad_stream_skip
(
&
data
->
stream
,
tagsize
);
#endif
#endif
}
#ifndef HAVE_ID3TAG
/**
* This function emulates libid3tag when it is disabled. Instead of
* doing a real analyzation of the frame, it just checks whether the
* frame begins with the string "ID3". If so, it returns the full
* length.
*/
static
signed
long
id3_tag_query
(
const
void
*
p0
,
size_t
length
)
{
const
char
*
p
=
p0
;
return
length
>
3
&&
memcmp
(
p
,
"ID3"
,
3
)
==
0
?
length
:
0
;
}
#endif
/* !HAVE_ID3TAG */
static
enum
mp3_action
static
enum
mp3_action
decode_next_frame_header
(
struct
mp3_data
*
data
,
G_GNUC_UNUSED
struct
tag
**
tag
,
decode_next_frame_header
(
struct
mp3_data
*
data
,
G_GNUC_UNUSED
struct
tag
**
tag
,
...
@@ -433,7 +459,6 @@ decode_next_frame_header(struct mp3_data *data, G_GNUC_UNUSED struct tag **tag,
...
@@ -433,7 +459,6 @@ decode_next_frame_header(struct mp3_data *data, G_GNUC_UNUSED struct tag **tag,
return
DECODE_BREAK
;
return
DECODE_BREAK
;
}
}
if
(
mad_header_decode
(
&
data
->
frame
.
header
,
&
data
->
stream
))
{
if
(
mad_header_decode
(
&
data
->
frame
.
header
,
&
data
->
stream
))
{
#ifdef HAVE_ID3TAG
if
((
data
->
stream
).
error
==
MAD_ERROR_LOSTSYNC
&&
if
((
data
->
stream
).
error
==
MAD_ERROR_LOSTSYNC
&&
(
data
->
stream
).
this_frame
)
{
(
data
->
stream
).
this_frame
)
{
signed
long
tagsize
=
id3_tag_query
((
data
->
stream
).
signed
long
tagsize
=
id3_tag_query
((
data
->
stream
).
...
@@ -454,7 +479,6 @@ decode_next_frame_header(struct mp3_data *data, G_GNUC_UNUSED struct tag **tag,
...
@@ -454,7 +479,6 @@ decode_next_frame_header(struct mp3_data *data, G_GNUC_UNUSED struct tag **tag,
return
DECODE_CONT
;
return
DECODE_CONT
;
}
}
}
}
#endif
if
(
MAD_RECOVERABLE
((
data
->
stream
).
error
))
{
if
(
MAD_RECOVERABLE
((
data
->
stream
).
error
))
{
return
DECODE_SKIP
;
return
DECODE_SKIP
;
}
else
{
}
else
{
...
@@ -493,7 +517,6 @@ decodeNextFrame(struct mp3_data *data)
...
@@ -493,7 +517,6 @@ decodeNextFrame(struct mp3_data *data)
return
DECODE_BREAK
;
return
DECODE_BREAK
;
}
}
if
(
mad_frame_decode
(
&
data
->
frame
,
&
data
->
stream
))
{
if
(
mad_frame_decode
(
&
data
->
frame
,
&
data
->
stream
))
{
#ifdef HAVE_ID3TAG
if
((
data
->
stream
).
error
==
MAD_ERROR_LOSTSYNC
)
{
if
((
data
->
stream
).
error
==
MAD_ERROR_LOSTSYNC
)
{
signed
long
tagsize
=
id3_tag_query
((
data
->
stream
).
signed
long
tagsize
=
id3_tag_query
((
data
->
stream
).
this_frame
,
this_frame
,
...
@@ -506,7 +529,6 @@ decodeNextFrame(struct mp3_data *data)
...
@@ -506,7 +529,6 @@ decodeNextFrame(struct mp3_data *data)
return
DECODE_CONT
;
return
DECODE_CONT
;
}
}
}
}
#endif
if
(
MAD_RECOVERABLE
((
data
->
stream
).
error
))
{
if
(
MAD_RECOVERABLE
((
data
->
stream
).
error
))
{
return
DECODE_SKIP
;
return
DECODE_SKIP
;
}
else
{
}
else
{
...
...
src/decoder/vorbis_plugin.c
View file @
7fe0a63d
...
@@ -383,7 +383,7 @@ vorbis_tag_dup(const char *file)
...
@@ -383,7 +383,7 @@ vorbis_tag_dup(const char *file)
return
NULL
;
return
NULL
;
}
}
if
(
ov_
open
(
fp
,
&
vf
,
NULL
,
0
)
<
0
)
{
if
(
ov_
test_callbacks
(
fp
,
&
vf
,
NULL
,
0
,
OV_CALLBACKS_STREAMONLY
)
<
0
)
{
fclose
(
fp
);
fclose
(
fp
);
return
NULL
;
return
NULL
;
}
}
...
...
src/directory.c
View file @
7fe0a63d
...
@@ -73,9 +73,14 @@ directory_prune_empty(struct directory *directory)
...
@@ -73,9 +73,14 @@ directory_prune_empty(struct directory *directory)
struct
dirvec
*
dv
=
&
directory
->
children
;
struct
dirvec
*
dv
=
&
directory
->
children
;
for
(
i
=
dv
->
nr
;
--
i
>=
0
;
)
{
for
(
i
=
dv
->
nr
;
--
i
>=
0
;
)
{
directory_prune_empty
(
dv
->
base
[
i
]);
struct
directory
*
child
=
dv
->
base
[
i
];
if
(
directory_is_empty
(
dv
->
base
[
i
]))
dirvec_delete
(
dv
,
dv
->
base
[
i
]);
directory_prune_empty
(
child
);
if
(
directory_is_empty
(
child
))
{
dirvec_delete
(
dv
,
child
);
directory_free
(
child
);
}
}
}
if
(
!
dv
->
nr
)
if
(
!
dv
->
nr
)
dirvec_destroy
(
dv
);
dirvec_destroy
(
dv
);
...
...
src/log.c
View file @
7fe0a63d
...
@@ -259,12 +259,8 @@ void log_init(bool verbose, bool use_stdout)
...
@@ -259,12 +259,8 @@ void log_init(bool verbose, bool use_stdout)
log_init_syslog
();
log_init_syslog
();
#endif
#endif
}
else
{
}
else
{
char
*
path
=
parsePath
(
param
->
value
);
const
char
*
path
=
config_get_path
(
CONF_LOG_FILE
);
g_free
(
param
->
value
);
assert
(
path
!=
NULL
);
if
(
path
==
NULL
)
g_error
(
"error parsing
\"
%s
\"
at line %i
\n
"
,
CONF_LOG_FILE
,
param
->
line
);
log_init_file
(
path
,
param
->
line
);
log_init_file
(
path
,
param
->
line
);
}
}
...
...
src/output/httpd_output_plugin.c
View file @
7fe0a63d
...
@@ -28,15 +28,12 @@
...
@@ -28,15 +28,12 @@
#include <assert.h>
#include <assert.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/in.h>
#include <netdb.h>
#include <netdb.h>
#include <unistd.h>
#include <unistd.h>
#include <errno.h>
#include <errno.h>
#ifdef HAVE_OSX
#include <sys/types.h>
#endif
#undef G_LOG_DOMAIN
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "httpd_output"
#define G_LOG_DOMAIN "httpd_output"
...
...
src/output/shout_plugin.c
View file @
7fe0a63d
...
@@ -448,8 +448,15 @@ my_shout_play(void *data, const void *chunk, size_t size, GError **error)
...
@@ -448,8 +448,15 @@ my_shout_play(void *data, const void *chunk, size_t size, GError **error)
static
bool
static
bool
my_shout_pause
(
void
*
data
)
my_shout_pause
(
void
*
data
)
{
{
struct
shout_data
*
sd
=
(
struct
shout_data
*
)
data
;
static
const
char
silence
[
1020
];
static
const
char
silence
[
1020
];
if
(
shout_delay
(
sd
->
shout_conn
)
>
500
)
{
/* cap the latency for unpause */
g_usleep
(
500000
);
return
true
;
}
return
my_shout_play
(
data
,
silence
,
sizeof
(
silence
),
NULL
);
return
my_shout_play
(
data
,
silence
,
sizeof
(
silence
),
NULL
);
}
}
...
...
src/output_all.c
View file @
7fe0a63d
...
@@ -439,8 +439,6 @@ audio_output_all_cancel(void)
...
@@ -439,8 +439,6 @@ audio_output_all_cancel(void)
{
{
unsigned
int
i
;
unsigned
int
i
;
audio_output_all_update
();
/* send the cancel() command to all audio outputs */
/* send the cancel() command to all audio outputs */
for
(
i
=
0
;
i
<
num_audio_outputs
;
++
i
)
{
for
(
i
=
0
;
i
<
num_audio_outputs
;
++
i
)
{
...
...
src/output_control.c
View file @
7fe0a63d
...
@@ -76,6 +76,17 @@ audio_output_open(struct audio_output *ao,
...
@@ -76,6 +76,17 @@ audio_output_open(struct audio_output *ao,
audio_format_equals
(
audio_format
,
&
ao
->
in_audio_format
))
{
audio_format_equals
(
audio_format
,
&
ao
->
in_audio_format
))
{
assert
(
ao
->
pipe
==
mp
);
assert
(
ao
->
pipe
==
mp
);
if
(
ao
->
pause
)
{
/* unpause with the CANCEL command; this is a
hack, but suits well for forcing the thread
to leave the ao_pause() thread, and we need
to flush the device buffer anyway */
/* we're not using audio_output_cancel() here,
because that function is asynchronous */
ao_command
(
ao
,
AO_COMMAND_CANCEL
);
}
return
true
;
return
true
;
}
}
...
...
src/output_init.c
View file @
7fe0a63d
...
@@ -109,6 +109,7 @@ audio_output_init(struct audio_output *ao, const struct config_param *param,
...
@@ -109,6 +109,7 @@ audio_output_init(struct audio_output *ao, const struct config_param *param,
ao
->
plugin
=
plugin
;
ao
->
plugin
=
plugin
;
ao
->
enabled
=
config_get_block_bool
(
param
,
"enabled"
,
true
);
ao
->
enabled
=
config_get_block_bool
(
param
,
"enabled"
,
true
);
ao
->
open
=
false
;
ao
->
open
=
false
;
ao
->
pause
=
false
;
ao
->
fail_timer
=
NULL
;
ao
->
fail_timer
=
NULL
;
pcm_convert_init
(
&
ao
->
convert_state
);
pcm_convert_init
(
&
ao
->
convert_state
);
...
...
src/output_internal.h
View file @
7fe0a63d
...
@@ -81,6 +81,12 @@ struct audio_output {
...
@@ -81,6 +81,12 @@ struct audio_output {
bool
open
;
bool
open
;
/**
/**
* Is the device paused? i.e. the output thread is in the
* ao_pause() loop.
*/
bool
pause
;
/**
* If not NULL, the device has failed, and this timer is used
* If not NULL, the device has failed, and this timer is used
* to estimate how long it should stay disabled (unless
* to estimate how long it should stay disabled (unless
* explicitly reopened with "play").
* explicitly reopened with "play").
...
...
src/output_thread.c
View file @
7fe0a63d
...
@@ -165,6 +165,7 @@ static void ao_pause(struct audio_output *ao)
...
@@ -165,6 +165,7 @@ static void ao_pause(struct audio_output *ao)
bool
ret
;
bool
ret
;
ao_plugin_cancel
(
ao
->
plugin
,
ao
->
data
);
ao_plugin_cancel
(
ao
->
plugin
,
ao
->
data
);
ao
->
pause
=
true
;
ao_command_finished
(
ao
);
ao_command_finished
(
ao
);
do
{
do
{
...
@@ -174,6 +175,8 @@ static void ao_pause(struct audio_output *ao)
...
@@ -174,6 +175,8 @@ static void ao_pause(struct audio_output *ao)
break
;
break
;
}
}
}
while
(
ao
->
command
==
AO_COMMAND_NONE
);
}
while
(
ao
->
command
==
AO_COMMAND_NONE
);
ao
->
pause
=
false
;
}
}
static
gpointer
audio_output_task
(
gpointer
arg
)
static
gpointer
audio_output_task
(
gpointer
arg
)
...
@@ -246,7 +249,11 @@ static gpointer audio_output_task(gpointer arg)
...
@@ -246,7 +249,11 @@ static gpointer audio_output_task(gpointer arg)
case
AO_COMMAND_PAUSE
:
case
AO_COMMAND_PAUSE
:
ao_pause
(
ao
);
ao_pause
(
ao
);
break
;
/* don't "break" here: this might cause
ao_play() to be called when command==CLOSE
ends the paused state - "continue" checks
the new command first */
continue
;
case
AO_COMMAND_CANCEL
:
case
AO_COMMAND_CANCEL
:
ao
->
chunk
=
NULL
;
ao
->
chunk
=
NULL
;
...
...
src/song.c
View file @
7fe0a63d
...
@@ -49,6 +49,7 @@ song_alloc(const char *url, struct directory *parent)
...
@@ -49,6 +49,7 @@ song_alloc(const char *url, struct directory *parent)
song
->
tag
=
NULL
;
song
->
tag
=
NULL
;
memcpy
(
song
->
url
,
url
,
urllen
+
1
);
memcpy
(
song
->
url
,
url
,
urllen
+
1
);
song
->
parent
=
parent
;
song
->
parent
=
parent
;
song
->
mtime
=
0
;
return
song
;
return
song
;
}
}
...
...
src/tag_ape.c
View file @
7fe0a63d
...
@@ -22,6 +22,7 @@
...
@@ -22,6 +22,7 @@
#include <glib.h>
#include <glib.h>
#include <assert.h>
#include <stdio.h>
#include <stdio.h>
struct
tag
*
struct
tag
*
...
@@ -86,15 +87,18 @@ tag_ape_load(const char *file)
...
@@ -86,15 +87,18 @@ tag_ape_load(const char *file)
/* find beginning of ape tag */
/* find beginning of ape tag */
tagLen
=
GUINT32_FROM_LE
(
footer
.
length
);
tagLen
=
GUINT32_FROM_LE
(
footer
.
length
);
if
(
tagLen
<
sizeof
(
footer
))
if
(
tagLen
<=
sizeof
(
footer
)
+
10
)
goto
fail
;
if
(
tagLen
>
1024
*
1024
)
/* refuse to load more than one megabyte of tag data */
goto
fail
;
goto
fail
;
if
(
fseek
(
fp
,
size
-
tagLen
,
SEEK_SET
))
if
(
fseek
(
fp
,
size
-
tagLen
,
SEEK_SET
))
goto
fail
;
goto
fail
;
/* read tag into buffer */
/* read tag into buffer */
tagLen
-=
sizeof
(
footer
);
tagLen
-=
sizeof
(
footer
);
if
(
tagLen
<=
0
)
assert
(
tagLen
>
10
);
goto
fail
;
buffer
=
g_malloc
(
tagLen
);
buffer
=
g_malloc
(
tagLen
);
if
(
fread
(
buffer
,
1
,
tagLen
,
fp
)
!=
tagLen
)
if
(
fread
(
buffer
,
1
,
tagLen
,
fp
)
!=
tagLen
)
goto
fail
;
goto
fail
;
...
@@ -112,7 +116,7 @@ tag_ape_load(const char *file)
...
@@ -112,7 +116,7 @@ tag_ape_load(const char *file)
/* get the key */
/* get the key */
key
=
p
;
key
=
p
;
while
(
tagLen
-
size
>
0
&&
*
p
!=
'\0'
)
{
while
(
tagLen
>
size
&&
*
p
!=
'\0'
)
{
p
++
;
p
++
;
tagLen
--
;
tagLen
--
;
}
}
...
...
src/update.c
View file @
7fe0a63d
...
@@ -430,7 +430,7 @@ update_container_file( struct directory* directory,
...
@@ -430,7 +430,7 @@ update_container_file( struct directory* directory,
{
{
char
*
vtrack
=
NULL
;
char
*
vtrack
=
NULL
;
unsigned
int
tnum
=
0
;
unsigned
int
tnum
=
0
;
c
onst
c
har
*
pathname
=
map_directory_child_fs
(
directory
,
name
);
char
*
pathname
=
map_directory_child_fs
(
directory
,
name
);
struct
directory
*
contdir
=
dirvec_find
(
&
directory
->
children
,
name
);
struct
directory
*
contdir
=
dirvec_find
(
&
directory
->
children
,
name
);
// directory exists already
// directory exists already
...
@@ -446,8 +446,10 @@ update_container_file( struct directory* directory,
...
@@ -446,8 +446,10 @@ update_container_file( struct directory* directory,
modified
=
true
;
modified
=
true
;
}
}
else
else
{
g_free
(
pathname
);
return
true
;
return
true
;
}
}
}
contdir
=
make_subdir
(
directory
,
name
);
contdir
=
make_subdir
(
directory
,
name
);
...
@@ -473,6 +475,8 @@ update_container_file( struct directory* directory,
...
@@ -473,6 +475,8 @@ update_container_file( struct directory* directory,
g_free
(
vtrack
);
g_free
(
vtrack
);
}
}
g_free
(
pathname
);
if
(
tnum
==
1
)
if
(
tnum
==
1
)
{
{
delete_directory
(
contdir
);
delete_directory
(
contdir
);
...
@@ -498,7 +502,8 @@ update_regular_file(struct directory *directory,
...
@@ -498,7 +502,8 @@ update_regular_file(struct directory *directory,
{
{
struct
song
*
song
=
songvec_find
(
&
directory
->
songs
,
name
);
struct
song
*
song
=
songvec_find
(
&
directory
->
songs
,
name
);
if
(
plugin
->
container_scan
!=
NULL
)
if
(
!
(
song
!=
NULL
&&
st
->
st_mtime
==
song
->
mtime
)
&&
plugin
->
container_scan
!=
NULL
)
{
{
if
(
update_container_file
(
directory
,
name
,
st
,
plugin
))
if
(
update_container_file
(
directory
,
name
,
st
,
plugin
))
{
{
...
@@ -767,7 +772,6 @@ static void * update_task(void *_path)
...
@@ -767,7 +772,6 @@ static void * update_task(void *_path)
{
{
if
(
_path
!=
NULL
&&
!
isRootDirectory
(
_path
))
{
if
(
_path
!=
NULL
&&
!
isRootDirectory
(
_path
))
{
updatePath
((
char
*
)
_path
);
updatePath
((
char
*
)
_path
);
g_free
(
_path
);
}
else
{
}
else
{
struct
directory
*
directory
=
db_get_root
();
struct
directory
*
directory
=
db_get_root
();
struct
stat
st
;
struct
stat
st
;
...
@@ -776,6 +780,8 @@ static void * update_task(void *_path)
...
@@ -776,6 +780,8 @@ static void * update_task(void *_path)
updateDirectory
(
directory
,
&
st
);
updateDirectory
(
directory
,
&
st
);
}
}
g_free
(
_path
);
if
(
modified
||
!
db_exists
())
if
(
modified
||
!
db_exists
())
db_save
();
db_save
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment