The log file is duped to STDOUT_FILENO and STDERR_FILENO. No need to
keep another copy of it in out_fd all the time. We only need it once
once in setup_log_output().
The logging library currently has 3 constructor functions: initLog(),
open_log_files(), setup_log_output(), called in this order. Merged
the first two.
If the user wants the log files with a specific mode, he has to start
MPD with the correct umask. Don't hard-code that.
This fixes a bug: when log cycling failed, MPD would not restore the
old umask.
This patch adds RVA2 (relative volume adjustment) tag
support to mpd, as a fallback if no replaygain tags are
found. The code is almost directly from madplay (GPL).
RVA2 tags are generated for example by the "normalize" utility.
Updated by: Avuton Olrich <avuton@gmail.com>
The input_stream object should only be closed by the MPD core
(i.e. decoder_thread.c / decoder_run()). A decoder plugin which
attempts to close it will result in a segmentation fault.
When save_absolute_paths_in_playlists was enabled in mpd.conf, MPD
broke all playlists when manipulated using the "playlistdelete"
command. The reason was that map_directory_child_fs() was used, which
doesn't accept slashes in the file name. Use the new map_uri_fs()
function instead.
With a large maximum playlist length, the integer multiplication
"playlist_max_length * MPD_PATH_MAX" may overflow. Change that to a
division. This was not a dangerous bug, since it was only used for
a quick estimate.
It is illegal to pass an empty audio buffer around. pcm_resample()
sometimes seems to result in 0 samples, maybe related to
libsamplerate. To work around that problem, add special checks after
both pcm_convert() invocations. Removed the pcm_resample()==0 checks
from pcm_convert().
When a response is very long (e.g. a large playlist > 100k songs),
most of it will end up in the deferred buffers. Filling the deferred
queue is very expensive currently, because a new buffer is allocated
for every client_write() operation. This may lead to long delays, and
the client might give up and disconnect meanwhile. This patch makes
MPD attempt to flush the deferred queue as often as possible, to work
around this problem. Due to the MPD 0.14 code freeze, we should not
optimize the buffering code now.
Make "secure" a log level different from "default". "secure" should be
right between "default" and "verbose". Map "default" to Glib's
"MESSAGE" log level.
There have been bug reports on MPD regarding 24 bit output via
libao/esd. The "ao" plugin does not attempt fall back to 16 bit
currently, and thus fails to play 24 bit audio (i.e. all mp3 files).
Make it always use 16 bit samples for now, until more bits are
well-tested.
The OS X output does not seem to support 24 bit audio in the way MPD
implements it currently. Fall back to 16 bit for now, and schedule
24 bit support on OS X for MPD 0.15.
MPD 0.13 and older followed all symbolic links. Although this can be
a security problem (as it has always been), 0.14 should offer the same
default behaviour as 0.13.
libsamplerate produces cracks in the sound output when the destination
buffer is too small. This is the case when pcm_convert_size() rounds
down. Use ceil(x) instead of floor(0.5+x) there to prevent a buffer
overrun.
Commit dd7711d8 removed MPD's default ALSA buffer_time. The result
was a buffer size which was way too small for playing streams on some
sound hardware, and caused skips and distorted sound. Revert the
default to 500 ms.
"float (*lamebuf)[2] = g_malloc()" does NOT allocate two float*
buffers. The formula is even wrong: it should be applied to LAME's
output buffer, not its input buffer.
Converted "lamebuf" to the two variables "left" and "right", and
allocate them independently with the exact buffer size. Set
right=left if mono output is configured.
The configuration options "follow_outside_symlinks" and
"follow_inside_symlinks" let the user control whether MPD should
follow symbolic links in the music directory.
[mk: converted variables to "bool"; moved configuration to
update_global_init()]
Those two functions are called when MPD starts and exits. It allows
the update library to perform global initialization and
deinitialization. The implementations are currently empty.
In contrast to, getBoolConfigParam(), config_get_bool() properly
returns a "bool" value. In case of "unset", it returns the default
value provided by the caller.
I have found something that looks like a bug in MPD:
- When a song is finished, the next one is played and the 'player'
event is emitted.
- When the client sends the status command just after this event, the
songid is the new one but the 'elapsed' time is not reseted to 0.
This is problem because I have implemented the solution using a timer
on client side to compute the elapsed time but with this bug the
elapsed time continues to be incremented on a new song.
assert_static() will help us to find false asserts in compile time. Of
course it only works in case of expressions which can be evaluated
compile time. It cannot be used in global scope.
When MPD quits in a non-clean way, the state file isn't written, and
on the next start, MPD time warps to the previous clean shutdown.
Save the state file every 5 minutes; this will probably be
configurable at a later time.
Note that we don't set a wakeup timer for that: when there is no MPD
traffic, MPD won't wake up to save the state file. This minor bug is
tolerated, because usually there is no change in MPD's state when the
main thread is idle.
If the caller attempts to seek only a few bytes forward, chances are
good that the offset is already in the buffer. In this case, simply
fast-forward the buffer.
If someone calls seek() with an invalid (negative) offset, the curl
implementation of that method returned false, but left this invalid
offset in input_stream.offset. Move the calculation to a temporary
variable.
While waiting for the input stream to become ready, ignore all
commands except STOP. This fixes seeking errors with (remote) songs
which the decoder has already finished.
skip_symlinks() expects an UTF-8 encoded file name, but
updateDirectory() passed ent->d_name (in file system encoding) to it.
Convert it to UTF-8 first.
HTTP servers respond with "416 Requested Range Not Satisfiable" when a
client attempts to seek to the end of the file. Catch this special
case in input_curl_seek(). This fixes a glitch in the ogg vorbis
decoder plugin.
Since we are using curl_multi_info_read() / CURLMSG_DONE for detecting
end-of-response, we can remove all running_handles==0 checks. For
some reason, that has never worked correctly.
curl_multi_info_read() is the authoritative source of the
"end-of-response" information. Always set c->eof when a CURLMSG_DONE
message is received, and check the result (success/failure) after
that.
When a global audio format is configured (setting
"audio_output_format"), decoder_data() overwrote the "length"
parameter with the size of the output buffer (result of
pcm_convert_size()). Declare a separate variable for the output
buffer length.
neaacdec.h declares all arguments as "unsigned long", but internally
expects uint32_t pointers. This triggers gcc warnings on 64 bit
architectures. To avoid that, make configure.ac detect whether we're
using Debian's corrected headers or the original libfaad headers. In
any case, pass a pointer to an uint32_t, conditionally casted to
"unsigned long*".
alloca() is not a portable function. Don't use it. Using
strncasecmp() is much more efficient anyway, because no memory needs
to be allocated and copied.
Don't send a "next song" request to the main thread when the current
song hasn't started playing yet, i.e. there are already two different
songs in the music pipe. This would erase information about the song
boundary within the music pipe, and thus triggered an assertion
failure. The bug could occur when playing very short songs which fit
into the pipe as a whole.
Fix a deadlock: when the decoder waited for buffer space, the player
could enter a deadlock situation because it waits for more chunks for
crossfading chunks. Signal the decoder before entering notify_wait().
The wavpack open function gives us an option called OPEN_STREAMING. This
provides more robust and error tolerant playback, but it automatically
disables seeking. (More exactly the wavpack lib will not return the
length information.) So, if the stream is already not seekable we can
use this option safely.
Seeking was somewhat broken in some decoder plugins because they sent
empty chunks, and never got a command. Check the decoder command
before doing anything else in decoder_data().
According to the documentation, mpc_decoder_decode() returns an
mpc_uint32_t. Since the special return value (mpc_uint32_t)-1
translates to a very large long integer, this may cause segmentation
faults if not interpreted properly.
Don't split the buffer conversion loop. When libmpcdec returns a
chunk, convert and send the whole chunk at a time. This moves several
checks out of the loop, and greatly improves performance.
Parse ID3 tags, even when they are in the middle of the stream. Very
few streams provide embedded ID3 tags. Most of them send only
Shoutcast "icy" tags, which limits the practical usefulness of this
patch.
When a command is received, decode_next_frame_header() and
decodeNextFrame() return DECODE_BREAK. This is already checked by
both callers, which means that we can eliminate lots of
decoder_get_command() checks.
When a tag is updated, the old tag was freed before the new one was
created. Reverse the order to be sure that other threads always see a
valid pointer.
This still leaves a possible race condition, but it will be addressed
later.
The stream_decode() and file_decode() methods returned a boolean,
indicating whether they were able to decode the song. This is
redundant, since we already know that: if decoder_initialized() has
been called (and dc.state==DECODE), the plugin succeeded. Change both
methods to return void.
The currently replay_gain_apply() implementation duplicates code from
pcm_volume(), except that it uses a floating point scale. Eliminate
all duplicated code from and make it utilize the pcm_volume() library
function. This introduces replay gain support for 24 bit audio.
It may be desirable to change the range of integer volume levels
(e.g. to 1024, which may utilize shifts instead of expensive integer
divisions). Introduce the constant PCM_VOLUME_1 which describes the
integer value for "100% volume". This is currently 1000.
The function simplifies wavpack_replaygain(), because it already
contains the float parser, and it works with a fixed buffer instead of
doing expensive heap allocations.
The assertion on dc.state in decoder_read() was too strict: when a
decoder tried to call decoder_read() from tag_dup(), the decoder state
was NONE. Allow this special case.
The flac plugin wasn't initialized properly when an OGG file was being
decoded. For some reason, flac_process_metadata() was explicitly not
called for OGG files. Since that seems to fix the issue, make it
always call flac_process_metadata().
Since decoder_list.c does not include the libflac headers, it cannot
know whether to add the oggflac plugin to the decoder list. Solve
this by always enabling the oggflac sub-plugin, even with older
libflac versions. When the libflac API cannot support oggflac,
disable the plugin at runtime by returning "false" from its init()
method.
The "oggflac" plugin was enabled only if HAVE_FLAC_COMMON was
defined. HAVE_FLAC_COMMON however is only an automake variable, and
is never available in decoder_list.c. Make decoder_list.c depend on
HAVE_FLAC||HAVE_OGGFLAC instead.
The player did not care about the exact error value, it only checked
whether an error has occured. This could fit well into
decoder_control.state - introduce a new state "DECODE_STATE_ERROR".
At this moment the wavpack lib doesn't use the return value of the
push_back function, which has an equivalent meaning of the return
value of ungetc(). This is a lucky situation, because so far it
simply returned with 1 as a hard coded value. From now on the
function will return EOF on error. (This function makes exactly one
byte pushable back.)
There are some functions in the wavpack-mpd input streams wrapper
which had too commonly used names (especially can_seek). I prefixed
these with "wavpack_input_".
The listen.c module breaks the build because the variable name used
("sun") for the Unix domain socket part collides with something else
on an OpenSolaris system, likely Sun specific. Renaming it to _sun
(or something else of choice) fixes the build.
[mk: renamed to "s_un"]
I had this option enabled during development, but at some point, it
must have gotten lost. FAILONERROR makes the curl stream fail when
the server returns a status code 400 or higher. We are not interested
in the server's error document.
Initialize libc's locale functions. Currently, we are only interested
in LC_CTYPE (character classification), because this is what is used
by GLib's g_get_charset().
GLib provides the function g_get_filename_charsets() which determines
the file system character set. This changes MPD's fallback: GLib
prefers UTF-8 as a fallback. MPD used to fall back to ISO Latin 1.
libwavpack expects the read_bytes() stream method to fill the whole
buffer, and fails badly when we return a partial read (i.e. not enough
data available yet). This caused wavpack streams to break.
Re-implement the buffer filling loop.
Instead of manually waiting for the input stream to become ready (to
catch server errors), just read the first byte. Since the
wavpack_input has the capability to push back one byte, we can simply
re-feed it. Advantage is: decoder_read() handles everything for us,
i.e. waiting for the stream, polling for decoder commands and error
handling.
The API of mp4_load_tag() was strange: it always returned a tag
object, no matter if a tag was found in the file; the existence of a
tag was indicated with the tag_found integer reference. This flag is
superfluous, since we can simply check whether the tag is empty or
not.
Allocate the mp4ff_callback_t object on the stack. This is easier to
handle, since we don't have to free it. Incidentally, this fixes a
memory leak in mp4_load_tag().
The function decoder_read() already cares about the decoder command,
and loops until data is available. Reduced mpd_ffmpeg_read() to no
more than the decoder_read() call.
The variable "next_song" is already protected by a memory barrier.
"total_time" is not important for synchronization, and we don't need
"volatile" here.
If an input stream provides tags (e.g. from an icecast server), send
them in the decoder_data() and decoder_tag() methods. Removed the
according code from the mp3 and oggvorbis plugins - decoders shouldn't
have to care about stream tags.
This patch also adds the missing decoder_tag() invocation to the mp3
plugin.
MPD used to have a copy of the mp4ff library. Since that has been
removed, AAC suport was disabled when there was no libmp4ff. Separate
the libmp4ff test, and enable AAC support no matter if libmp4ff is
available.
The "mod" decoder plugin was being initialized lazily, but was
deinitialized unconditionally. That led to segmentation faults.
Convert mod_initMikMod() to be the global module initialization
method. The MPD core should care about lazy initialization.
Non-local songs used to have no tags. If the decoder sends us a tag,
we should incorporate it into the song struct. This way, clients can
always show the correct song name (if provided by the server).
The try_decode() method may have read some data from the stream, which
is now lost. To make this data available to other methods, get it
back by rewinding the input stream after each try_decode() invocation.
The ogg and wavpack plugins did this manually and inconsistently; this
code can now be removed.
If the source chunk has a tag, merge it into the destination chunk.
The source chunk gets deleted after that, and this is our last chance
to grab the tag.
Ogg and ffmpeg detection was disabled when the stream was not
seekable, because the detection was too expensive. Since the curl
input stream can now rewind the stream cheaply, we can re-enable
detection on streams.
During codec detection, the beginning of the stream is consumed. This
is a common operation, which takes a lot of time when handling remote
resources. To optimize this, remember the first 64 kB of a stream.
This way, we can rewind the stream without actually fetching the start
of the stream again.
Since the aac and mod plugins have told MPD that they cannot seek, MPD
will never send a SEEK command to them. Removed the SEEK comand
checks from both plugins.
Don't pass the "seekable" flag with every decoder_data() invocation.
Since that flag won't change within the file, it is enough to pass it
to decoder_initialized() once per file.
Replace all direct music_pipe struct accesses with wrapper functions.
The compiled machine code is the same, but this way, we can change
struct internals more easily.
.. and rename dc.audioFormat to dc.in_audio_format. The music pipe
does not need to know the audio format, and its former "audioFormat"
property indicated the format of the most recently added chunk, which
might be confusing when you are reading the oldest chunks.
No CamelCase in the file name. The output_buffer struct is going to
be renamed to music_pipe. There are so many buffer levels in MPD, and
calling this one "output buffer" is wrong, because it's not the last
buffer before the music reaches the output devices.
Commit 1a4a3e1f moved decoders into a static array, but failed to
enable those plugins who did not have an init() method at all.
This patch corrects the "enabled" check.
Make map_directory_child_fs() refuse the names "." and "..". This is
currently the interface where an attacker may inject a manipulated
path (through the "update" command).
"LOG_H" is a macro which is also used by ffmpeg/log.h. This is
ffmpeg's fault, because short macros should be reserved for
applications, but since it's always a good idea to choose prefixed
macro names, even for applications, we are going to do that in MPD.
Depending on MPD's umask, the file permissions of the unix socket were
too restrictive, and many clients were not able to connect. Do a
chmod(0666) on the socket, to allow everybody to connect.
Similar to libmad, libmpcdec provides samples with higher quality than
16 bit. Send 24 bit samples to MPD, which allows MPD to apply
dithering just in case the output devices are only 16 bit capable.
The conversion of integer samples was completely broken, which
presumably didn't annoy anybody because libmpcdec provides float
samples on most installations.
Its only caller in mp3_decode() just compared its value with
DECODE_BREAK. Convert that to bool, and return false if the loop
should be ended. Also eliminate some superfluous command checking
code, which was already done in the preceding while loop.
When one of several output devices failed, MPD tried to reopen it
quite often, wasting a lot of resources. This patch adds a delay:
wait 10 seconds before retrying. This might be changed to exponential
delays later, but for now, it makes the problem go away.
When the decoder exited before the buffer has grown big enough
("buffer_before_play"), the player thread waited forever. Add an
additional check which disables buffering as soon as the decoder
exits.
The local variable "play_audio_format" is updated every time the
player starts playing a new song. This way, we always know exactly
which audio format is current. The old code broke when a new song had
a different format: ob.audio_format is the format of the next song,
not of the current one - using this caused breakage for the software
volume control.
A decoder_flush() invocation was missing in the FLAC plugin, resulting
in casual assertion failures due to a wrong assumption about the last
chunk's audio format. It's much easier to remove that decoder_flush()
function and make the decoder thread call ob_flush().
Request the next song from the playlist (by clearing pc.next_song)
only if the player command is empty. If it is not, the player may be
clearing the song that has already been queued, leading to an
assertion failure.
Remember the seek_where argument and call decoder_command_finished()
immediately. This way, the player thread can continue working, and we
can receive more commands.
This also fixes several issues which resulted in broken frames,
leading to erroneos "elapsed" values: frames weren't parsed properly,
since the code was checking for command!=NONE.
size_t and long aren't 64 bit safe (i.e. files larger than 2 GB on a
32 bit OS). Use off_t instead, which is a 64 bit integer if compiled
with large file support.
When the decoder failed to start, the function do_play() returned,
still having pc.command==PLAY. This is because pc.command was reset
only when the decoder started up successfully. Add another
player_command_finished() call in the error handler.
Replaced the local variable "colon" (which had only temporary meaning)
with the variable "value". It is a pointer to the first byte of the
header value.
Instead of managing a set of method pointers in each input_stream
struct, move these into the new input_plugin struct. Each
input_stream has only a pointer to the plugin struct. Pointers to all
implementations are kept in the array "input_plugins".
MPD's HTTP client code has always been broken, no matter how effort
was put into fixing it. Replace it with libcurl, which is known to be
quite stable. This adds a fat library dependency, but only for people
who need streaming.
MPD shouldn't integrate sources of other libraries. Since libmp4ff is
part of libfaad, we should remove the old copy from src/mp4ff and link
with the current version from libfaad instead.
PA_SAMPLE_S16NE is the only sample format which is suported by both
MPD and pulseaudio. Unfortunately, pulse does not accept 24 bit
samples.
Instead of bailing out with an error message, we should tell the MPD
core to convert all samples to 16 bit for pulse.
This bug caused the audio output devices to stay open, although MPD
wasn't playing: quitDecode() resetted player_control.command, assuming
that the command was STOP. This way, player_task() didn't see the
CLOSE_AUDIO command, and the device was kept open.
Don't clear player_control.command in quitDecode().
When the audio source provides 24 bit samples, don't bother to convert
(lossily) them to 16 bit before jack's floating point conversion - go
directly from 24 bit to float.
The JACK documentation postulates that the process() callback must not
block, therefore locking is forbidden. Anyway, the old code was racy.
Remove all locks, and don't wait for more data to become available -
just send to the port what is already in the buffer.
Another partial frame fix: the silence buffer was 1020 bytes, which
had room for 127.5 24 bit stereo frames. Don't send the partial last
frame in this case.
24 bit output is as important as 16 bit output. Provide a
pcm_convert() implementation which can convert to 24 bit with as
little quality loss as possible.
The old pcm_convert_size() ignored most of the destination format,
e.g. it did not check its sample size, and assumed it is 16 bit.
Simplify and universalize it by using audio_format_frame_size().
Similar to pcm_resample_16(), implement pcm_resample_24(). The 24 bit
implementation is very similar, but it uses src_int_to_float_array()
instead of src_short_to_float_array() before sending data to
libsamplerate.
Use sizeof(sample) instead of hard-coding "2". Although we're in 16
bit right now, this will make code sharing easier when we support
other sample sizes.
libmad produces samples of more than 24 bit. Rounding that down to 16
bits using dithering makes those people lose quality who have a 24 bit
capable sound device. Send 24 bit PCM data, and let the receiver
decide whether to apply 16 bit dithering.
I added 24 bit support a while ago, but it wasn't possible to force 24
bit output. Add 24 and 8 bit to the list of allowed sample sizes.
Although 8 bit audio isn't as widely used as 24 bit, there is no
reason to exclude it.
Splitting a frame between two buffer chunks causes distortion in the
output. MPD used to assume that the chunk size 1020 would never cause
splitted frames, but that isn't the case for 24 bit stereo (127.5
frames), and even less for files with even more channels.
Many command arguments must not be negative; add a separate
parser/checker function for that. For the same reason, add
check_bool(). This eliminates two strange special cases handlers from
check_int().
Pass index arguments as unsigned integers. They must not be negative,
and even if some caller accidently passes -1, it won't pass the bound
checks (since it's now 2**32-1).
There are some integers which have a "magic" -1 value which means
"undefined" or "nothing". All others can be converted to unsigned,
since they must not contain a negative number.
Also add names for "error" and "ok". I don't like passing anonymous
integer codes around.
This is not yet complete: lots of functions (e.g. in playlist.c)
follow the same convention of -1/0, and these have to be adapted, too.
spl_list() provides an interface for enumerating all stored playlists.
This separates the internal playlist logic from the protocol specific
function lsPlaylists().
The two functions clearStoredPlaylist() and addToStoredPlaylist()
don't belong into playlist.c. clearStoredPlaylist() was a wrapper for
spl_clear(), and is converted into a CPP macro for now.
The list of commands is known at compile time. Instead of creating a
linked list on startup, we can just register all commands in a static
sorted array.
The command pointers which are passed around aren't being modified -
in fact, no command pointer must be modified once it has been added to
the commandList.
Instead of manually calling memset(0) on the pcm_convert_state struct,
client code should use a library function from pcm_utils.c. This way,
we can change the semantics of the struct easily.
Casting a pointer to some sort of integer and formatting it into a
string isn't valid. A pointer derived from this hex string won't work
reliably. Since ffmpeg doesn't provide a nice API for passing our
pointer, we have to think of a different hack: ffmpeg passes the exact
URL pointer to mpdurl_open(), and we can make this string part of a
struct. This reduces the problem to casting the string back to the
struct.
This is still a workaround, but this is "sort of portable", unless the
ffmpeg people start messing with the URL pointer (which would be valid
according to the API definition).
Since ffmpeg svn r12865, you have to include libavcodec/avcodec.h
instead of avcodec.h. This cannot be checked at compile time, instead
we have to add a check to configure.ac. Viliam's original ffmpeg
plugin was based on the newer ffmpeg library, while my Debian
installation had the older version. My attempt to correct his include
statements wasn't correct after all.
{song,dir}vec_for_each each failed to gracefully handle deleted
files when iterating through. While we were thread-safe, we
were not safe within the calling thread. If a callback we
passed caused sv->nr to shring, our index would still increment;
causing files to stay in the database.
A way to test this is to remove 10 or so contiguous songs from a
>10 song directory.
Like the songvec nr_lock, only one lock is used for all
traversals since they're rarely changed. This only
projects traversals, but not the individual structures
themselves.
Use a literal in the struct declaration, and sizeof(client->buffer)
everywhere else. Also shrink the buffer from 40 kB to 4 kB. The
buffer must only be large enough to hold one line of input, and 4 kB
is still more than enough.
When adding a local file, clients have to use the "file" URI schema
described in RFC 1738 3.10. By adding this schema to "urlhandlers", a
client can detect whether this feature is available.
By default, glibc 2.8 hides struct ucred behind the _GNU_SOURCE
macro. I don't want to enable that globally, because it may encourage
the use of non-portable functions. Test if "struct ucred" is
available, and enable _GNU_SOURCE if required.
For details about that issue, see glib's bug database:
http://sources.redhat.com/bugzilla/show_bug.cgi?id=6545
Some functions assume that a song is not in the database when it is a
remote song. Based on that, they decide whether they are responsible
for freeing the song struct. Add a special function which checks
whether a song is in the database (currently equal to song_is_file()).
GLib provides an easier API for character set conversion than iconv().
Use g_convert() / g_convert_with_fallback() for all character
conversions. We should optimize the path.h API later to return a
newly allocated buffer, so we can just pass GLib's return value.
GLib is a nice and portable utility library. We are going to use it
from now on, and eliminate a lot of duplicated code from MPD. Why
invent the wheel again and again?
Use memchr() instead of manually traversing the input buffer. Update
the client's properties after all commands have been processed. Check
for buffer overflow once.
The caller already knows the protocol family, and we can eliminate the
complicated switch statement in establishListen() if we just pass this
information. This seems more robust.
"idle" waits until something noteworthy happens on the server,
e.g. song change, playlist modified, database updated. This allows
clients to keep up to date without polling.
Added mpd.conf options for disabling automatic resamling, sample
format and channel conversion. This way, users may choose to override
ALSA's automatic resampling, and use libsamplerate instead.
This git branch has become a real MPD fork now. Time to change the
package name to the code name "mpd-mk". Set the version number to
"0.14~git" to mark this as a non-released version.
Don't follow relative symlinks which point into the music directory.
This allows you to organize music with symbolic links, without MPD
managing separate copies of each song.
The mapper library maps directory and song objects to file system
paths. With this central library, the code mixture in path.c should
be cleaned up, and we will be able to add neat features like aliasing.
isMusic() used to be a very inefficient function: with every
invocation, it did another stat() on the specified file. There is
only one caller, do the stat() there manually and use hasMusicSuffix()
instead of isMusic().
By always creating the parent directory, we can use delete_name_in()
without further lookups. The parents which may non exist will be
pruned later. An update request for a non-existing or empty directory
should be quite unusual, so this doesn't add any measurable overhead.
In order to optimize buffer usage, pass only the base file name to
updateInDirectory(). This way, updateInDirectory() may choose when to
allocate a larger buffer for the full path.
It is invalid to pass a path with the wrong dirname to dirvec_find().
To be able to find a subdirectory only by its basename, compare only
the basename of both paths.
The only caller of deletePlaylist() appends PLAYLIST_FILE_SUFFIX, so
we can be sure it's already there. We don't need to stat the file,
since unlink() does all the checking.
Commit 80a2c937 broke resume after pause: it cleared the
input_audio_format when it attempted to simplify a complicated
expression. Don't clear it, just assign input_audio_format if a new
format was specified.
We only need to lock sv->nr changes to prevent traversals ( why
it's called "nr_lock"). free(3) is a "slow" function on my
system; so we can avoid unnecessarily holding a lock long for
longer than needed.
If the sample format isn't supported by the device (i.e. 24 bit on
low-end sound chips), fall back to 16 bit output. There is code in
pcm_utils.c which converts PCM data to 16 bit.
Convert any number of channels to stereo. In fact, this isn't really
stereo, it's rater mono blown up to stereo. This patch should only
make it possible to play 5.1 files at all; "real" conversion to stereo
should be implemented, but for now, this is better than nothing.
In order to be able to deal with non-trivial conversions,
pcm_convertChannels() needs to know both the input and the output
channel count. Simplify buffer allocation in that function.
Moved code from pcm_convertChannels() to pcm_convert_channels_1_to_2()
and pcm_convert_channels_2_to_1(). Improved the quality of
pcm_convert_channels_2_to_1() by calculating the arithmetic mean value
of both samples.
buffered_before_play was copied to struct player because it was used
to disable buffering when seeking. Instead of mainaining a copy of
this number, move just the flag to the player struct.
Renamed audio_configFormat to configured_audio_format. Renamed
audio_buffer.format to input_audio_format. Simplified its
initialization in openAudioDevice().
audio.c maintained one of MPD's many layers of audio buffers. It was
without any benefit, since playAudio() can simply send the source
buffer directly to the audio output plugin.
QUEUE adds a new song to the player's queue. CANCEL clears the queue.
These two commands replace the old and complex queueState and
queueLockState code.
Simplify and merge several if clauses before the clearPlayerQueue()
invocation. Call clearPlayerQueue() only if a song is actually
queued; add an assertion for that in clearPlayerQueue().
This variable is superfluous, it is only used to copy its value to
player_control.totalTime. Since the original source of this value
(song->tag->time) will still be available at this point, we can safely
remove fileTime.
Revert e4f5d6bd "re-enable-nonblocking, but sleep if busy".
Non-blocking mode with manual sleeping doesn't help at all (by the
way, the patch should have used snd_pcm_wait() instead of
my_usleep()). ALSA knows much more about the hardware quirks, so we
just let it do the job.
Leftover from the output API changes: oss_open_default() was changed
to return a void*, but it still returned "0" to report success.
Report the OssData pointer instead.
The decoder was woken up after each chunk which had been played. That
caused a lot of superfluous context switches. Wake up the decoder
only when a certain amount of the buffer has been consumed. This
formula is somewhat arbitrary, and has to be proven experimentally.
The mp3 plugin did not use the MAD_NCHANNELS() value correctly: when a
stream was not stereo, it was assumed to be mono, although the correct
number was passed to MPD. libmad doesn't support more than 2
channels, but this change allows gcc to optimize its inlining
strategy.
The dithering function audio_linear_dither() worked for signed 16 bits
only anyway, having a variable "bits" just disables important gcc
optimizations.
A frame contains one sample per channel, thus it is sample_size *
channels. This patch includes some cleanup for various locations
where the sample size for 24 bit audio was still 3 bytes (instead of
4).
There is only once update thread at a time. Make the "modified" flag
global and remove the return values of most functions. Propagating an
error is only useful for updateDirectory(), since updateInDirectory()
will delete failed subdirectories.