Compare commits
22 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fb34519b96 | ||
![]() |
91fed47648 | ||
![]() |
c05691b546 | ||
![]() |
6b3b8c6f2e | ||
![]() |
a191db84f2 | ||
![]() |
e4d69f38b0 | ||
![]() |
97fc001180 | ||
![]() |
42a09ff17a | ||
![]() |
c170fed6f9 | ||
![]() |
8e38b4f83c | ||
![]() |
db4ae19246 | ||
![]() |
82a89c6bfe | ||
![]() |
166c70cab3 | ||
![]() |
de78fe38c8 | ||
![]() |
96fa69ff6b | ||
![]() |
39d94bd3ea | ||
![]() |
695ca29274 | ||
![]() |
02e8da6c98 | ||
![]() |
0ea5f4ac3a | ||
![]() |
47c50c079d | ||
![]() |
3b0fea5fae | ||
![]() |
443516cdda |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -31,6 +31,7 @@ libtool
|
||||
ltmain.sh
|
||||
missing
|
||||
mkinstalldirs
|
||||
/test-driver
|
||||
mpd
|
||||
mpd.service
|
||||
stamp-h1
|
||||
|
15
NEWS
15
NEWS
@@ -1,3 +1,18 @@
|
||||
ver 0.18.6 (2013/12/24)
|
||||
* input
|
||||
- cdio_paranoia: support libcdio-paranoia 0.90
|
||||
* tags
|
||||
- riff: recognize upper-case "ID3" chunk name
|
||||
* decoder
|
||||
- ffmpeg: use relative timestamps
|
||||
* output
|
||||
- openal: fix build failure on Mac OS X
|
||||
- osx: fix build failure
|
||||
* mixer
|
||||
- alsa: fix build failure with uClibc
|
||||
* fix replay gain during cross-fade
|
||||
* accept files without metadata
|
||||
|
||||
ver 0.18.5 (2013/11/23)
|
||||
* configuration
|
||||
- fix crash when db_file is configured without music_directory
|
||||
|
@@ -1,6 +1,6 @@
|
||||
AC_PREREQ(2.60)
|
||||
|
||||
AC_INIT(mpd, 0.18.5, musicpd-dev-team@lists.sourceforge.net)
|
||||
AC_INIT(mpd, 0.18.6, musicpd-dev-team@lists.sourceforge.net)
|
||||
|
||||
VERSION_MAJOR=0
|
||||
VERSION_MINOR=18
|
||||
@@ -749,6 +749,7 @@ MPD_AUTO_PKG(cdio_paranoia, CDIO_PARANOIA, [libcdio_paranoia],
|
||||
if test x$enable_cdio_paranoia = xyes; then
|
||||
AC_DEFINE([ENABLE_CDIO_PARANOIA], 1,
|
||||
[Define to enable libcdio_paranoia support])
|
||||
AC_CHECK_HEADERS(cdio/paranoia/paranoia.h)
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(ENABLE_CDIO_PARANOIA, test x$enable_cdio_paranoia = xyes)
|
||||
|
131
doc/mpd.conf.5
131
doc/mpd.conf.5
@@ -363,137 +363,6 @@ errors on bandwidth-limited devices. Some users have reported good results
|
||||
with this set to 50000, but not all devices support values this high. Most
|
||||
users do not need to change this. The default is 256000000 / sample_rate(kHz),
|
||||
or 5804 microseconds for CD-quality audio.
|
||||
.SH OPTIONAL OSS OUTPUT PARAMETERS
|
||||
.TP
|
||||
.B device <dev>
|
||||
This specifies the device to use for audio output. The default is "/dev/dsp".
|
||||
.TP
|
||||
.B mixer_device <mixer dev>
|
||||
This specifies which mixer to use. The default is "/dev/mixer".
|
||||
.TP
|
||||
.B mixer_control <mixer ctrl>
|
||||
This specifies which mixer control to use (sometimes referred to as the
|
||||
"device"). The default is to use the main PCM mixer. An example is "Pcm".
|
||||
.SH OPTIONAL PULSE OUTPUT PARAMETERS
|
||||
.TP
|
||||
.B server <server list>
|
||||
A space separated list of servers to try to connect to. See
|
||||
<\fBhttp://www.pulseaudio.org/wiki/ServerStrings\fP> for more details. The
|
||||
default is to let PulseAudio choose a server.
|
||||
If you specify more than one server name, MPD tries to connect to one
|
||||
after another until it successfully establishes a connection.
|
||||
.TP
|
||||
.B sink <sink>
|
||||
The sink to output to. The default is to let PulseAudio choose a sink.
|
||||
.SH OPTIONAL JACK OUTPUT PARAMETERS
|
||||
.TP
|
||||
.B client_name <name>
|
||||
The client name to use when connecting to JACK. The output ports <name>:left
|
||||
and <name>:right will also be created for the left and right channels,
|
||||
respectively.
|
||||
.TP
|
||||
.B ports <left_port,right_port>
|
||||
This specifies the left and right ports to connect to for the left and right
|
||||
channels, respectively. The default is to let JACK choose a pair of ports.
|
||||
.TP
|
||||
.B ringbuffer_size <size in bytes>
|
||||
This specifies the size of the ringbuffer in bytes. The default is 32768.
|
||||
.SH OPTIONAL AO OUTPUT PARAMETERS
|
||||
.TP
|
||||
.B driver <driver>
|
||||
This specifies the libao driver to use for audio output. Possible values
|
||||
depend on what libao drivers are available. See
|
||||
<\fBhttp://www.xiph.org/ao/doc/drivers.html\fP> for information on some
|
||||
commonly used drivers. Typical values for Linux include "oss" and "alsa09".
|
||||
The default is "default", which causes libao to select an appropriate plugin.
|
||||
.TP
|
||||
.B options <opts>
|
||||
This specifies the options to use for the selected libao driver. For oss, the
|
||||
only option available is "dsp". For alsa09, the available options are: "dev",
|
||||
"buf_size", and "periods". See <\fBhttp://www.xiph.org/ao/doc/drivers.html\fP>
|
||||
for available options for some commonly used drivers. Options are assigned
|
||||
using "=", and ";" is used to separate options. An example for oss:
|
||||
"dsp=/dev/dsp". An example for alsa09: "dev=hw:0,0;buf_size=4096". The
|
||||
default is "".
|
||||
.TP
|
||||
.B write_size <size in bytes>
|
||||
This specifies how many bytes to write to the audio device at once. This
|
||||
parameter is to work around a bug in older versions of libao on sound cards
|
||||
with very small buffers. The default is 1024.
|
||||
.SH REQUIRED FIFO OUTPUT PARAMETERS
|
||||
.TP
|
||||
.B path <path>
|
||||
This specifies the path of the FIFO to output to. Must be an absolute path.
|
||||
If the path does not exist it will be created when mpd is started, and removed
|
||||
when mpd is stopped. The FIFO will be created with the same user and group as
|
||||
mpd is running as. Default permissions can be modified by using the builtin
|
||||
shell command "umask". If a FIFO already exists at the specified path it will
|
||||
be reused, and will \fBnot\fP be removed when mpd is stopped. You can use the
|
||||
"mkfifo" command to create this, and then you may modify the permissions to
|
||||
your liking.
|
||||
.SH REQUIRED SHOUT OUTPUT PARAMETERS
|
||||
.TP
|
||||
.B name <name>
|
||||
This specifies not only the unique audio output name, but also the stream
|
||||
title.
|
||||
.TP
|
||||
.B host <hostname>
|
||||
This specifies the hostname of the icecast server to connect to.
|
||||
.TP
|
||||
.B port <port>
|
||||
This specifies the port of the icecast server to connect to.
|
||||
.TP
|
||||
.B mount <mountpoint>
|
||||
This specifies the icecast mountpoint to use.
|
||||
.TP
|
||||
.B password <password>
|
||||
This specifies the password to use when logging in to the icecast server.
|
||||
.TP
|
||||
.B quality <quality>
|
||||
This specifies the encoding quality to use. The value must be between 0
|
||||
and 10. Fractional values, such as 2.5, are permitted. Either the quality or
|
||||
the bitrate parameter must be specified, but not both. For Ogg, a
|
||||
higher quality number produces higher quality output. For MP3, it's
|
||||
just the opposite, with lower numbers producing higher quality output.
|
||||
.TP
|
||||
.B bitrate <kbps>
|
||||
This specifies the bitrate to use for encoding. Either the quality or the
|
||||
bitrate parameter must be specified, but not both.
|
||||
.TP
|
||||
.B format <sample_rate:bits:channels>
|
||||
This specifies the sample rate, bits per sample, and number of channels to use
|
||||
for encoding.
|
||||
.SH OPTIONAL SHOUT OUTPUT PARAMETERS
|
||||
.TP
|
||||
.B encoding <encoding>
|
||||
This specifies which output encoding to use. Should be either "ogg"
|
||||
or "mp3", "mp3" is needed for shoutcast streaming. The default is "ogg".
|
||||
.TP
|
||||
.B protocol <protocol>
|
||||
This specifies the protocol that wil be used to connect to the
|
||||
icecast/shoutcast server. The options are "shoutcast", "icecast1" and
|
||||
"icecast2". The default is "icecast2".
|
||||
.TP
|
||||
.B user <username>
|
||||
This specifies the username to use when logging in to the icecast server. The
|
||||
default is "source".
|
||||
.TP
|
||||
.B public <yes or no>
|
||||
This specifies whether to request that the stream be listed in all public
|
||||
stream directories that the icecast server knows about. The default is no.
|
||||
.TP
|
||||
.B timeout <seconds>
|
||||
This specifies the number of seconds to wait before giving up on trying to
|
||||
connect to the icecast server. The default is 2 seconds.
|
||||
.TP
|
||||
.B description <description>
|
||||
This specifies a description of the stream.
|
||||
.TP
|
||||
.B url <url>
|
||||
This specifies a URL associated with the stream.
|
||||
.TP
|
||||
.B genre <genre>
|
||||
This specifies the genre(s) of the stream.
|
||||
.SH FILES
|
||||
.TP
|
||||
.BI ~/.mpdconf
|
||||
|
97
doc/user.xml
97
doc/user.xml
@@ -1398,6 +1398,59 @@ systemctl start mpd.socket</programlisting>
|
||||
The <varname>ao</varname> plugin uses the portable
|
||||
<filename>libao</filename> library.
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Setting</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<varname>driver</varname>
|
||||
<parameter>D</parameter>
|
||||
</entry>
|
||||
<entry>
|
||||
The <filename>libao</filename> driver to use for
|
||||
audio output. Possible values depend on what libao
|
||||
drivers are available. See <ulink
|
||||
url="http://www.xiph.org/ao/doc/drivers.html">http://www.xiph.org/ao/doc/drivers.html</ulink>
|
||||
for information on some commonly used drivers.
|
||||
Typical values for Linux include "oss" and "alsa09".
|
||||
The default is "default", which causes libao to
|
||||
select an appropriate plugin.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<varname>options</varname>
|
||||
<parameter>O</parameter>
|
||||
</entry>
|
||||
<entry>
|
||||
Options to pass to the selected
|
||||
<filename>libao</filename> driver.
|
||||
</entry>
|
||||
</row>
|
||||
|
||||
<row>
|
||||
<entry>
|
||||
<varname>write_size</varname>
|
||||
<parameter>O</parameter>
|
||||
</entry>
|
||||
<entry>
|
||||
This specifies how many bytes to write to the audio
|
||||
device at once. This parameter is to work around a
|
||||
bug in older versions of libao on sound cards with
|
||||
very small buffers. The default is 1024.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@@ -1408,6 +1461,38 @@ systemctl start mpd.socket</programlisting>
|
||||
FIFO (First In, First Out) file. The data can be read by
|
||||
another program.
|
||||
</para>
|
||||
|
||||
<informaltable>
|
||||
<tgroup cols="2">
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Setting</entry>
|
||||
<entry>Description</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>
|
||||
<varname>path</varname>
|
||||
<parameter>P</parameter>
|
||||
</entry>
|
||||
<entry>
|
||||
This specifies the path of the FIFO to write to.
|
||||
Must be an absolute path. If the path does not
|
||||
exist, it will be created when MPD is started, and
|
||||
removed when MPD is stopped. The FIFO will be
|
||||
created with the same user and group as MPD is
|
||||
running as. Default permissions can be modified by
|
||||
using the builtin shell command "umask". If a FIFO
|
||||
already exists at the specified path it will be
|
||||
reused, and will not be removed when MPD is stopped.
|
||||
You can use the "mkfifo" command to create this, and
|
||||
then you may modify the permissions to your liking.
|
||||
</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</informaltable>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@@ -1883,6 +1968,18 @@ systemctl start mpd.socket</programlisting>
|
||||
Defaults to 2 seconds.
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<varname>protocol</varname>
|
||||
<parameter>icecast2|icecast1|shoutcast</parameter>
|
||||
</entry>
|
||||
<entry>
|
||||
Specifies the protocol that wil be used to connect
|
||||
to the icecast/shoutcast server. The default
|
||||
is "<parameter>icecast2</parameter>".
|
||||
|
||||
</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>
|
||||
<varname>mount</varname>
|
||||
|
@@ -101,6 +101,8 @@ audio_output_set_replay_gain_mode(struct audio_output *ao,
|
||||
{
|
||||
if (ao->replay_gain_filter != nullptr)
|
||||
replay_gain_filter_set_mode(ao->replay_gain_filter, mode);
|
||||
if (ao->other_replay_gain_filter != nullptr)
|
||||
replay_gain_filter_set_mode(ao->other_replay_gain_filter, mode);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -1081,8 +1081,11 @@ Player::Run()
|
||||
|
||||
delete cross_fade_tag;
|
||||
|
||||
if (song != nullptr)
|
||||
if (song != nullptr) {
|
||||
const auto uri = song->GetURI();
|
||||
FormatDefault(player_domain, "played \"%s\"", uri.c_str());
|
||||
song->Free();
|
||||
}
|
||||
|
||||
pc.Lock();
|
||||
|
||||
|
@@ -95,8 +95,7 @@ Song::UpdateFile()
|
||||
|
||||
TagBuilder tag_builder;
|
||||
if (!tag_file_scan(path_fs,
|
||||
&full_tag_handler, &tag_builder) ||
|
||||
!tag_builder.IsDefined())
|
||||
&full_tag_handler, &tag_builder))
|
||||
return false;
|
||||
|
||||
if (tag_builder.IsEmpty())
|
||||
|
@@ -28,6 +28,9 @@ struct tag_handler;
|
||||
/**
|
||||
* Scan the tags of a song file. Invokes matching decoder plugins,
|
||||
* but does not invoke the special "APE" and "ID3" scanners.
|
||||
*
|
||||
* @return true if the file was recognized (even if no metadata was
|
||||
* found)
|
||||
*/
|
||||
bool
|
||||
tag_file_scan(Path path,
|
||||
|
@@ -120,8 +120,7 @@ mpd_ffmpeg_stream_seek(void *opaque, int64_t pos, int whence)
|
||||
if (whence == AVSEEK_SIZE)
|
||||
return stream->input.size;
|
||||
|
||||
Error error;
|
||||
if (!stream->input.LockSeek(pos, whence, error))
|
||||
if (!stream->input.LockSeek(pos, whence, IgnoreError()))
|
||||
return -1;
|
||||
|
||||
return stream->input.offset;
|
||||
@@ -252,13 +251,14 @@ static DecoderCommand
|
||||
ffmpeg_send_packet(Decoder &decoder, InputStream &is,
|
||||
const AVPacket *packet,
|
||||
AVCodecContext *codec_context,
|
||||
const AVRational *time_base,
|
||||
const AVStream *stream,
|
||||
AVFrame *frame,
|
||||
uint8_t **buffer, int *buffer_size)
|
||||
{
|
||||
if (packet->pts >= 0 && packet->pts != (int64_t)AV_NOPTS_VALUE)
|
||||
decoder_timestamp(decoder,
|
||||
time_from_ffmpeg(packet->pts, *time_base));
|
||||
time_from_ffmpeg(packet->pts - stream->start_time,
|
||||
stream->time_base));
|
||||
|
||||
AVPacket packet2 = *packet;
|
||||
|
||||
@@ -342,11 +342,9 @@ ffmpeg_probe(Decoder *decoder, InputStream &is)
|
||||
PADDING = 16,
|
||||
};
|
||||
|
||||
Error error;
|
||||
|
||||
unsigned char buffer[BUFFER_SIZE];
|
||||
size_t nbytes = decoder_read(decoder, is, buffer, BUFFER_SIZE);
|
||||
if (nbytes <= PADDING || !is.LockRewind(error))
|
||||
if (nbytes <= PADDING || !is.LockRewind(IgnoreError()))
|
||||
return nullptr;
|
||||
|
||||
/* some ffmpeg parsers (e.g. ac3_parser.c) read a few bytes
|
||||
@@ -473,7 +471,7 @@ ffmpeg_decode(Decoder &decoder, InputStream &input)
|
||||
if (packet.stream_index == audio_stream)
|
||||
cmd = ffmpeg_send_packet(decoder, input,
|
||||
&packet, codec_context,
|
||||
&av_stream->time_base,
|
||||
av_stream,
|
||||
frame,
|
||||
&interleaved_buffer, &interleaved_buffer_size);
|
||||
else
|
||||
@@ -484,7 +482,8 @@ ffmpeg_decode(Decoder &decoder, InputStream &input)
|
||||
if (cmd == DecoderCommand::SEEK) {
|
||||
int64_t where =
|
||||
time_to_ffmpeg(decoder_seek_where(decoder),
|
||||
av_stream->time_base);
|
||||
av_stream->time_base) +
|
||||
av_stream->start_time;
|
||||
|
||||
if (av_seek_frame(format_context, audio_stream, where,
|
||||
AV_TIME_BASE) < 0)
|
||||
|
@@ -41,7 +41,12 @@
|
||||
#include <glib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef HAVE_CDIO_PARANOIA_PARANOIA_H
|
||||
#include <cdio/paranoia/paranoia.h>
|
||||
#else
|
||||
#include <cdio/paranoia.h>
|
||||
#endif
|
||||
|
||||
#include <cdio/cd_types.h>
|
||||
|
||||
struct CdioParanoiaInputStream {
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include "Main.hxx"
|
||||
#include "event/MultiSocketMonitor.hxx"
|
||||
#include "event/Loop.hxx"
|
||||
#include "event/Call.hxx"
|
||||
#include "util/ASCII.hxx"
|
||||
#include "util/ReusableArray.hxx"
|
||||
#include "util/Error.hxx"
|
||||
@@ -46,10 +47,22 @@ class AlsaMixerMonitor final : private MultiSocketMonitor {
|
||||
public:
|
||||
AlsaMixerMonitor(EventLoop &_loop, snd_mixer_t *_mixer)
|
||||
:MultiSocketMonitor(_loop), mixer(_mixer) {
|
||||
#ifdef USE_EPOLL
|
||||
_loop.AddCall([this](){ InvalidateSockets(); });
|
||||
#else
|
||||
_loop.AddIdle(InitAlsaMixerMonitor, this);
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
#ifndef USE_EPOLL
|
||||
static gboolean InitAlsaMixerMonitor(gpointer data) {
|
||||
AlsaMixerMonitor &amm = *(AlsaMixerMonitor *)data;
|
||||
amm.InvalidateSockets();
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual int PrepareSockets() override;
|
||||
virtual void DispatchSockets() override;
|
||||
};
|
||||
|
@@ -363,9 +363,9 @@ osx_output_open(struct audio_output *ao, AudioFormat &audio_format,
|
||||
|
||||
OSStatus status = AudioUnitInitialize(od->au);
|
||||
if (status != noErr) {
|
||||
error.Set(osx_output_domain, status,
|
||||
"Unable to initialize OS X audio unit: %s",
|
||||
GetMacOSStatusCommentString(status));
|
||||
error.Format(osx_output_domain, status,
|
||||
"Unable to initialize OS X audio unit: %s",
|
||||
GetMacOSStatusCommentString(status));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#ifndef HAVE_OSX
|
||||
#ifndef __APPLE__
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#else
|
||||
|
@@ -87,7 +87,8 @@ riff_seek_id3(FILE *file)
|
||||
/* pad byte */
|
||||
++size;
|
||||
|
||||
if (memcmp(chunk.id, "id3 ", 4) == 0)
|
||||
if (memcmp(chunk.id, "id3 ", 4) == 0 ||
|
||||
memcmp(chunk.id, "ID3 ", 4) == 0)
|
||||
/* found it! */
|
||||
return size;
|
||||
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include "Compiler.h"
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
Reference in New Issue
Block a user