Even if libsamplerate support is enabled, compile the fallback
resampler. When the user specifies the option
"samplerate_converter=internal", it is chosen in favor of
libsamplerate. This may help users with a weak FPU who don't want to
compile a custom MPD from source, because the fallback resampler does
not use floating point operations.
Added diversion functions to pcm_resample.c. These check which
resampler is enabled at compile time (libsamplerate or fallback).
This prepares the following patch.
In some rare cases, there was a race condition between the output
thread and the main thread: when you disable/enable an output device
in the main thread, this caused a crash in the output thread. Protect
the whole mixer struct with a GMutex to prevent that.
This updates the copyright header to all be the same, which is
pretty much an update of where to mail request for a copy of the GPL
and the years of the MPD project. This also puts all committers under
'The Music Player Project' umbrella. These entries should go
individually in the AUTHORS file, for consistancy.
When the destination chunk was empty in cross_fade_apply(), it had no
audio_format attached (an attribute which is only used for assertion
in the debug build). cross_fade_apply() should assign it the
audio_format of the second chunk (if available), otherwise MPD will
crash.
When there are chunks which are not yet finished,
audio_output_all_check() returned the size of its music pipe minus
one. I can't remember exactly why I subtracted 1 from the return
value, it must have had something to do with a former meaning of this
function. Now it induces assertion failures.
After adding the container_scan() method the update_regular_file() method was quite hard to read.
Now there's update_container_file() which deals with container files.
That way normal container files (i.e. without embedded tracks) are handled by the old code like a regular file.
This will fix some of the odd behaviour observed.
If the PCM handle gets disconnected, don't close and clear it in
alsa_recover(). The MPD core will call alsa_close() anyway. This
way, we can always assume that alsa_data.pcm is always valid.
After a seek, wait until enough new chunks are decoded before starting
playback. If this takes too long, send silence chunks to the audio
outputs meanwhile.
When the audio outputs are closed, also clear the audio format. If we
don't do this, every call to audio_output_all_update() will open the
device, even if it's meant to be paused.
When playback is unpaused, pass the audio_format to
audio_output_all_open(). Don't assume that output_all.c remembers the
previous audio format. Also check if there has been an audio format
yet.
Check audio_output.command after each sub-chunk has been played. It
discards the rest of the chunk, but since all commands make the device
stop anyway, this is not a problem, but part of the improvement. This
improves the latency of audio output commands.
A larger chunk size means less overhead for managing them. 4 kB seems
to be a reasonable choice: it contains 23 ms of 44.1 kHz 16 bit stereo
data, or 3 ms of 192 kHz 24 bit stereo data. The original value of
1020 seemed to be too small, there were quite a lot of system calls
and context switches.
Instead of passing individual buffers to audio_output_all_play(), pass
music_chunk objects. Append all those chunks asynchronously to a
music_pipe instance. All output threads may then read chunks from
this pipe. This reduces MPD's internal latency by an order of
magnitude.
When a PAUSE command is received while the decoder starts, don't open
the audio device when the decoder becomes ready. It's pointless,
because MPD will close if after that.
If the header valgrind/memcheck.h is available, add
VALGRIND_MAKE_MEM_NOACCESS() and VALGRIND_MAKE_MEM_UNDEFINED()
support, which enables nice warnings in the valgrind memory checker.
This is similar to the MPD 0.14 patch "wait 10 seconds before
reopening a failed device", which only covered open() failures. This
patch adds the same feature for play().
Until now every flac file got removed unconditionally (and then re-added)
whenever the update command was issued. Now there is a check if we need
to that, so the file will only be removed if there is a embedded cuesheet
in that file
So far only seekpoints are supported, so no proper tagging yet
except for track number and track length.
Tagging should be done by parsing the cue sheet which
is often embedded as vorbis comment in flac files.
Furthermore the pathname should be configurable like "%A - %t - %T",
where %A means Artist, %t track number and %T Title or so.
In !NDEBUG, remember which audio_format is stored in every chunk and
every pipe. Check the audio_format of every new data block appended
to the music_chunk, and the format of every new chunk appended to the
music_pipe.
This patch fixes a theoretical (but practically impossible) flaw: the
variable "buffer_time" may be uninitialized when it is used.
Initialize the variable with snd_pcm_hw_params_get_buffer_time().
The default values for buffer_time and period_time were both capped by
the hardware limits on practically all chips. The result was a
period_time which was half as big as the buffer_time. On some chips,
this led to lots of underruns when using a high sample rate (192 kHz),
because MPD had very little time to send new samples to ALSA.
A period time which is one fourth of the buffer time turned out to be
much better. If no period_time is configured, see how much
buffer_time the hardware accepts, and try to configure one fourth of
it as period_time, instead of hard-coding the default period_time
value.
This is yet another attempt to provide a solution which is valid for
all sound chips. Using the SND_PCM_NONBLOCK flag also seemed to solve
the underruns, but put a lot more CPU load to MPD.
Sometimes, audio_output_update() isn't called for the second device
when the first one has succeeded. The patch
"audio_output_all_update() returns bool" broke it, because the boolean
evaluation ended after the first "true".
When the decoder chunk is empty in decoder_flush_chunk(), don't push
it into the music pipe - return it to the music buffer instead. An
empty chunk in the pipe wastes resources for no advantage.
The value of music_chunk.next is undefined for a chunk returned by
music_pipe_shift(). For more pedantic debugging, poison the reference
before returning the chunk.
This patch follows the commit 21bb10f4b.
>From Max Kellermann:
> I removed the daemonization changes in main.c. Please explain why you
> changed that. If you need it for some reason, make that a separate
> patch with a good description of your rationale.
> That's the biggest flaw of your code: it opens the mixer device in the
> init() method, while the open() method is empty. When the pulse
> daemon is not available (either during MPD startup or when it dies
> while MPD runs), the plugin will not even attempt to reconnect to
> pulse. Please move the code to the open() method, to make that work.
I changed the daemonize call as the fork losts the connection to the
pulse server. According to your remark, the init() method should be
moved to the open() ones.
With the modification, mpd is able to reconnect the pulse mixer after
restarting the pulseaudio daemon.
Signed-off-by: David Guibert <david.guibert@gmail.com>
Signed-off-by: Max Kellermann <max@duempel.org>
This patch introduces the mixer for the pulse output.
Technically speaking, the pulse index is needed to get or set
the volume. You must define callback fonctions to get this index since
the pulse output in mpd is done using the simpe api. The pulse simple api
does not provide the index of the newly defined output.
So callback fonctions are associated to the pulse context.
The list of all the sink input is then retreived.
Then we select the name of the mpd pulse output and control
its volume by its associated index number.
Signed-off-by: Patrice Linel <patnathanael@gmail.com>
Signed-off-by: David Guibert <david.guibert@gmail.com>
[mk: fixed whitespace errors and broke long lines; removed
daemonization changes from main.c]
Turn the music_pipe into a simple music_chunk queue. The music_chunk
allocation code is moved to music_buffer, and is now managed with a
linked list instead of a ring buffer. Two separate music_pipe objects
are used by the decoder for the "current" and the "next" song, which
greatly simplifies the cross-fading code.
Added music_pipe_allocate(), music_pipe_push() and
music_pipe_cancel(). Those functions allow the caller (decoder thread
in this case) to do its own chunk management. The functions
music_pipe_flush() and music_pipe_tag() can now be removed.
After the decoder command was obtained, don't wait until libflac
detects EOF (as a side effect), quit the decoder immediately. This
check was missing completely.
When the MPD core sends the decoder a command while
flac_process_single() is executed, this function fails. Abort the
decoder only if not seeking. This fixes a seeking bug.
Log the real period and buffer size. This might be useful when
debugging xruns. Note that the same information is available in
/proc/asound/card*/pcm*p/sub*/hw_params
The lastfm input plugin enables MPD to play lastfm:// URLs. This
plugin is not complete yet: it plays only the first song in the
last.fm playlist, and the playlist parser isn't even implemented
properly.
Some sound chips/drivers (e.g. Intel HDA) don't support 24 bit
samples, they want to get 32 bit instead. Now that MPD's PCM library
supports 32 bit, add a 32 bit fallback when 24 bit is not supported.
There is nothing 24 bit specific in the pcm_dither_24 struct. Since
we want to reuse the struct for 32 bit dithering, let's drop the "_24"
suffix from the struct name.
Some 24 bit code can be reused. The 32 bit variant has to use 64 bit
integers, because 32 bit integers could overflow. This may be a
performance hit on 32 bit CPUs.
This is the first patch in a series to enable 32 bit audio samples in
MPD. 32 bit samples are more tricky than 24 bit samples, because the
integer may overflow when you operate on a sample.
audio_valid_sample_format() verifies the number of channels. Let's
just say up to 8 channels is allowed (which is possible with some
consumer sound chips). I don't know if there are bigger cards, and
since I cannot test it, I'll limit it to 8 for now.
On some hardware, reading the mixer value from hardware is an
expensive operation, and MPD has to do it for every client. Throttle
access to the hardware, cache the result for one second.
time() is not a monotonic timer, and MPD might get confused by clock
skews. clock_gettime() provides a monotonic clock, but is not
portable to non-POSIX systems (i.e. Windows). This patch uses GLib's
GTimer API, which aims to be portable.
If an input_stream is not seekable, libaudiofile fails to play at all:
Audio File Library: unrecognized audio file format [error 0]
Since we know in advance whether the input_stream is seekable, just
refuse to play on a non-seekable stream.
The generic sockaddr struct is too small for some addresses. For
accept(), we have to allocate a sockaddr_storage struct on the stack,
which is large enough for all addresses.
Create the socket_util.c library, the first function is
sockaddr_to_string(): it converts a sockaddr struct to a string
containing the IP address in a human-readable form.
When checking whether database entries have been deleted, don't check
if an archive file is a directory (G_FILE_TEST_IS_DIR), use
G_FILE_TEST_IS_REGULAR for this case instead. To determine if a
"struct directory" is an archive, check for device==DEVICE_INARCHIVE.
This is always false after loading the database, so this patch is not
complete yet.
Remember the modification time of each directory. This is important
for archives (which are virtual directories right now), but may also
be useful for an automatic update mechanism.
Added the uri_remove_auth() library function which strips username
and password from a HTTP URI, and use it in song_print_url(). This
allows you to add HTTP URIs to the playlist including secret username
and password, without disclosing it to all MPD clients.
Since we introduced a GLib logging domain, the "client" string appears
twice in the log lines:
client: client 0: command returned 0
Removed the second one, now it looks like this:
client: [0] command returned 0
Still not quite good, but better than before.
MPD used to be silent when it could stat() a directory, but could not
opendir() it to read its contents. This caused a lot of support
headache with users who have wrong file permissions. Add another
warning message.
There's no point in declaring num_items as a uint8_t, it doesn't save
any space, due to padding. This allows us to lift the articial "255
items" limitation.
The warning message "problems opening audio device while playing ..."
does not help at all, and should be removed. At this point, the real
error message has already been logged by the output thread.
Use GLib's GError library for reporting output device failures.
Note that some init() methods don't clean up properly after a failure,
but that's ok for now, because the MPD core will abort anyway.
Don't call AudioOutputUnitStart() in the play() method, do it after
the device has been opened. We can eliminate the "started" property
now, because the device is always started when it's open.
ao_play() gets PCM data in the in_audio_format, and converts it to
out_audio_format. Comparing the input data with out_audio_format is
wrong.
prefixed with "STG:" will be automatically removed. STG: Trailing
empty lines will be automatically removed. STG: vi: set textwidth=75
filetype=diff nobackup:
The MPD core guarantees that the audio_output object is always
consistent, and our pa_simple!=NULL checks are superfluous. Also
don't manually close the device on error in pulse_play(), since the
MPD core does this automatically when the play() method returns 0.
The MPD core guarantees that the audio_output object is always in a
consistent state: either open or closed. When open, it will not call
the open() method again, and when closed, it will not call play().
Removed several checks and the NULL initialization.
audio_output_get_name() has been removed, which was the only function
left in output_api.h. The output plugin doesn't need the audio_output
object at all, remove the parameter from the init() method.
After much research[1][2][3] this should be the majority of currently
supported file extensions and mime-types for the currently supported
ffmpeg formats. This list maybe incomplete, but it's more complete
than anything else out there that I've been able to find. This list
needs to be updated every now and again as the ffmpeg sources support
more formats.
1. Sources
2. wiki.multimedia.cx
3. filext.com
Recursive Makefiles are inefficient and error prone (no proper way to
declare dependencies). Since there's no disadvantage in having one
single Makefile, let's do it.
The old API required an output plugin to not return until all data
passed to the play() method is consumed. Some output plugins have to
loop to fulfill that requirement, and may block during that. Simplify
these, by letting them consume only part of the buffer: make play()
return the length of the consumed data.
Now that I've found this nice function in the GLib docs, we can
finally remove our custom sleep function. Still all those callers of
g_usleep() have to be migrated one day to use events, instead of
regular polling.
Hi,
upon trying to play an MMS stream added to the play list, I got this:
mpd: /tmp/mpd/./src/input_stream.c:85: input_stream_open: Assertion `is->plugin->open == ((void *)0) || is->plugin == plugin' failed.
With the following patch applied, it works perfectly.
Thanks for having implemented MMS support :-).
Best regards,
Peter
Added an inline assembly function for the 64 bit multiplication.
Benchmark results on a Pentium II 266 MHz, 512 MB of 24 bit PCM data:
dd if=/dev/zero bs=64k count=8k |
time ./test/software_volume 48000:24:2 >/dev/null
Before this patch 22.94s, after this patch 7.24s.
Use faacDecInit2() instead of AudioSpecificConfig() to detect the AAC
track in the MP4 file. This has a great advantage: it initializes the
libfaad decoder, which the caller would normally do anyway - but now
we can go without the AudioSpecificConfig() call. When decoder==NULL
(called from mp4_tag_dup()), fall back to a mp4ff_get_track_type()==1
check, like other audio players do.
Moved the libfaad decoder initialization to mp4_faad_new(), and also
fill the audio_format struct there. This eliminates a little bit of
complexity in mp4_decode().
When a file is not seekable, MPD dropped the audio buffers before even
attempting to seek. This caused noticable sound corruption. Fix:
first attempt to seek, and only if that succeeds, call
audio_output_all_cancel().
All callers of adts_find_frame() use faad_buffer_fill() before that.
Move that faad_buffer_fill() call into adts_find_frame() instead.
adts_find_frame() will get its own logic for on-demand filling.
When I implemented the pcm_buffer library, I forgot to set the new
buffer size. This caused a new allocation in each pcm_buffer_get(),
fortunately no memory was leaked.
The decoder_plugin struct is used by both the MPD core and the decoder
plugin implementations. Move it to a shared header file, to minimize
header dependencies.
If mpd.conf specifies a user, and MPD is invoked by exactly this user,
ignore the "user" setting. Don't bother to look up its groups and
don't attempt to change uid, it won't work anyway.
Use delete_directory() for removing sub directories instead of
dirvec_clear(). This ensures that all memory occupied by
subdirectories of deleted directories is freed.
When a directory is deleted, MPD deleted only the directory from the
database; it did not bother to walk the full tree to free all memory
and to remove deleted songs from the playlist. Replace a
dirvec_delete() with delete_directory().
When you change the filesystem charset, discard the old database file
and create a new one. The old database file will most likely contain
stale or invalid information.
There are a few problems left in this plugin:
- fluidsynth decodes in real time, while MPD prefers to buffer as
quickly as possible; as a workaround, this plugin uses a timer
object to synchronize with real-time playback
- I don't know yet how fluidsynth tells me when the song has ended
- the "soundfont" configuration setting is not yet documented, and it
will likely change soon (in favor of a per-decoder configuration
block)
When MPD is not playing, it may still remember which is the "current"
song. When you switch to "random" mode, MPD will always start playing
exactly this song. This defies the goal of "random" mode a little.
Clear the "current" song when MPD is not playing during the "random"
mode switch.
The output_command library provides a command interface to the audio
outputs. It assumes the input comes from an untrusted source
(i.e. the client) and verifies all parameters.
In addition to audio_format_valid(), provide functions which validate
only one attribute of an audio_format. These functions are reused by
audio_format_parse().
Added audio_format_parse() in a separate library, with a modern
interface: return a GError instead of logging errors. This allows the
caller to deal with the error.
When MPD explicitly starts playing, ignore the "REOPEN_AFTER" timeout.
This timeout was useful when MPD attempted to reopen a failed device
over and over, but it confuses users when they explicitly tell MPD to
start playing, while MPD insists to wait for the 10 seconds to pass.
Fix a memory leak: it was not guaranteed that pcm_convert_deinit() was
called for each pcm_convert_init(). This patch always (de)initializes
the pcm_convert library when the audio_output.open flag is flipped.
Pass the music chunk as a "const void *" to the encoder, instead of a
"const char *". Actually, both encoders currently expect 16 bit
samples, passing a 8-bit character is rather pointless.
The crossfading code shouldn't depend on the audio output code. Pass
the current audio format to cross_fade_calc() and let it compare
directly, instead of using isCurrentAudioFormat().
When MPD is stopped, but the last song is still the "current song",
and you delete it, playlist->current is not updated, and becomes an
invalid value. Fix this by catching "!playlist->playing &&
playlist->current == (int)songOrder".
audio_output_config_count() returns the number of audio outputs in the
configuration file. It is only used by initAudioDriver(). The public
function audio_output_count() now returns audioOutputArraySize.
When we reset pc.next_song if there is no song queued, this might
cause a race condition: the next song to be played is cleared, while
pc.command was already set. Clear the "next_song" only if there is a
song queued for the current do_play() invocation.
If a new song is queued before calling playerSeek(), then the player
and the playlist enter an inconsistent state, because the player
discards the playlist's "queued" song in favor of the seeked song.
Call playlist_update_queued_song() after playerSeek().
After a player command (successful or not), reset pc.next_song,
because the queue is supposed to be empty then. Otherwise,
playlist.queued and pc.next_song may disagree, which triggers an
assertion failure.
Commit f78cddb4 introduced a regression: after a song was moved, the
order array was not updated (in random mode). This caused MPD to
think the "current" song has changed when you moved something to the
position of the current song.
Always assume the buffer is empty before calling the encoder. Always
flush the buffer immediately after there has been added something.
This reduces the risk of buffer overruns, because there will never be
a "rest" in the current buffer.
The non-blocking mode of libshout is sparsely documented, and MPD's
implementation had several bugs. Also removed connect throttling
code, that is done by the MPD core since 0.14.
After the state file has been loaded, the playlist version is still
"1", and "plchanges 1" returns the whole playlist. Fix this by
increasing the playlist version after the state file has been loaded.
Don't call syncPlaylistWithQueue() in nextSongInPlaylist() and
previousSongInPlaylist(). This is a relic from the time when there
was no event, and was a workaround to the timing problem.
Export the "g_playlist" variable, and pass it to all playlist
functions. This way, we can split playlist.c easier into separate
parts. The code which initializes the singleton variable is moved to
playlist_global.c.
Before every operation which modifies the playlist, remember a pointer
to the song struct. After the modification, determine the "next song"
again, and if it differs, dequeue and queue the new song.
This removes a lot of complexity from the playlist update code, and
makes it more robust.
The "current" variable is used for calculating the seek destination,
and was declared as "int". With very long song files, the 32 bit
integer can overflow. ffmpeg expects an int64_t, which is very
unlikely to overflow. Switch to int64_t.
If avcodec_decode_audio2() returns no output for an AVPacket,
libavcodec may buffer some data, and return a larger chunk of output
later. This patch disables a lot of bogus warnings.
Output the name of the codec as a debug message. During my tests,
ffmpeg never filled this struct member, but it may do so in the past,
and this debug message might become helpful.
The shout_mp3 encoder had two bugs: when no song was ever played, MPD
segfaulted during cleanup. Second bug: memory leak, each time the
shout device was opened, lame_init() was called again, and
lame_close() is only called once during shutdown.
Fix this by shutting down LAME each time the clear_encoder() method is
called.
When the update thread is started before MPD has forked (for
daemonization), it is killed, because threads do not survive a fork().
This induces an inconsistent state where MPD won't start any update
thread at all, because it thinks the thread is already running.
Move the "while" loop which checks for commands to the caller
ao_pause(). This simplifies the pause() method, and lets us remove
audio_output_is_pending().
If no ports are configured, don't overwrite the (NULL) configuration
with the port names of the first JACK server. If the server changes
after a JACK reconnect, MPD won't attempt to auto-detect again.
Currently, the JACK plugin manipulates the audio_format struct which
was passed to the open() method. This is very likely to break,
because the plugin must not permanently store this pointer. After
this patch, MPD ignores sample rate changes. It looks like other
software is doing the same, and I guess this is a non-issue.
This patch converts the audio_format pointer within jack_data into a
static audio_format struct.
Hi -
independently of libmikmod's other problems - there seems
to be a problem in mpd's wrapper: MikMod_Exit() is called
after the first file is decoded, which frees some ressources
within the mikmod library. An attempt to play a second file
leads to a crash. The appended patch fixes this for me.
(I don't know what the "dup" entry is good for - someone
who knows should review that too.)
best regards
Matthias
[mk: removed 3 more MikMod_Exit() invocations]
When there are duplicate slashes in the song paths, eliminate them;
example:
/var/lib/mpd/music//foo.mp3
becomes:
/var/lib/mpd/music/foo.mp3
The slash is only detected at the border between the music_directory
and the local part.
When the user configures a music_directory with a trailing slash, it
may break playlist loading, because MPD expects a double slash. Chop
off the trailing slash.
ffmpeg_tag_internal() does not look for a few tags that mpd
supports. Most noteably:
comment -> TAG_ITEM_COMMENT -> Description
genre -> TAG_ITEM_GENRE -> WM/Genre (not WM/GenreID)
year -> TAG_ITEM_DATE -> WM/Year
I *think* that this is the last of the tags that AVFormatContext() in
ffmpeg supports that mpd also uses.
Make those two methods optional to implement, and let input_stream.c
provide fallbacks. The buffer() method will be removed one day, and
there is now only one implementation left (input_curl.c).
The open_stream() method opens the input_stream. This allows the
archive plugin to do its own initialization, and it also allows it to
use input_stream.data. We can remove input_stream.archive now, which
was unnatural to have in the first place.
Preparation for supporting other channel numbers than stereo: use
loops instead of duplicating code for the second channel. Most
likely, gcc will unroll these loops, so the binary won't be any
different.
This patch implements the MMS protocol, by using libmms. It is quite
experimental: it does not support seeking yet, and it is currently
using synchronous I/O, which causes MPD to hang while waiting for the
server.
When the playlist is cleared, pc.errored_song is also cleared. This
causes pc_errored_song_uri() to crash, because it assumes that
pc.errored_song is set. Reset pc.error to fix that assumption.
When waiting for free space in the ring buffer, the JACK plugin
sleeped 10ms until there is enough space. This delay was too large
for low-latency setups (<10ms), and created a lot of xruns. Work
around that by reducing the sleep time to 1ms.
A proper solution for this would be to use an event based approach,
and we will do it, just not now.
When the connection failed once, you had to restart MPD, because it
never cleared the jack_data.shutdown flag. Instead, it refused to
play anything "because there is no client thread" (which is wrong at
that point).
GIOChannel is more portable than raw read()/write() calls. We're
using GIOChannel anyway, because we need it for plugging the client
into the GLib main loop.
Configure the GIOChannel to the bare minimum: no character set, no
buffering.
On some platforms, g_free() must be used for memory allocated by
GLib. This patch intends to correct a lot of occurrences, but is
probably not complete.
Both methods are always called together. There is no point in having
them separate. This simplifies the code, because the old configure()
method could be called more than once, and had to free old
allocations.
Reimplemented the legacy mixer configuration: copy the deprecated
configuration values into the audio_output section. Don't configure
the mixers twice (once for the audio_output, and a second time for the
legacy values).
This requires volume_init() to be called before initAudioDriver().
Return the default value in the conf_get_block_*() functions when
param==NULL was passed.
This simplifies a lot of code, because all initialization can be done
in one code path, regardless whether configuration is present.
Two bugs here led to a large number of interrupts being generated on the
sound card when ALSA output is being used. Because we specify no default
period_time, the sound card gives us 3000 interrupts/sec rather than a more
sane 20 or 30. This completes the revert of dd7711 already started by
4ca24f.
The larger bug was in the change to config_get_block_unsigned() and using 0
as the default value for both 'buffer_time' and 'period_time'. This means
any pre-setting of these options in newAlsaData() gets wiped out. Add a new
default for period_time, and ensure default values for buffer_time and
period_time are used if none are provided by the user.
Signed-off-by: Dan McGee <dan@archlinux.org>
[mk: set defaults in newAlsaData() to fix auto-configuration; renamed
"_MS" back to "_US" because ALSA expects microseconds, not milliseconds]
Signed-off-by: Max Kellermann <max@duempel.org>
Added all important id tags from the MusicBrainz wiki:
http://musicbrainz.org/doc/MusicBrainzTag
This should automatically enable its suport in the vorbis and flac
decoder plugins.
The input_stream API sets size to -1 when the size of the resource is
not known. The modplug decoder checked for size==0, which would be an
empty file.
You are allowed to call decoder_read() with decoder==NULL. It is a
convenience function provided by the decoder API. Don't manually fall
back to input_stream_read().
When the playlist was loaded from the state file, the order numbers
were the same as the positions. In random mode, we need to shuffle
the queue order. To accomplish that, call setPlaylistRandomStatus()
at the end of readPlaylistState(), and do a fresh shuffle.
When MPD is not playing while in random mode, and the client issues
the "clear" command, MPD crashes in stopPlaylist(), or more exactly,
in queue_order_to_position(-1). Exit from stopPlaylist() if MPD isn't
playing.
PlaylistInfo() (notice the capital 'P') sends a stored playlist to the
client. Move it to a separate library, where all the code which glues
the playlist and the MPD protocol together will live.
The playlist.c source is currently quite hard to understand. I have
managed to wrap my head around it, and this patch attempts to explain
it to the next guy.
The function playPlaylistIfPlayerStopped() is only called when the
player thread is stopped. Converted that runtime check into an
assertion, and remove one indent level.
One of the previous patches removed the "random" mode check from
nextSongInPlaylist(), which caused a shuffle whenever MPD wrapped to
the first song in "repeat" mode. Re-add that "random" check.
In playPlaylist(), the second "song==-1 && playing" check can never be
reached, because at this point, the function has already returned
(after unpausing).
When a song is deleted, start playing the next song immediately,
within deleteFromPlaylist(). This allows us to remove the ugly
playlist_noGoToNext flag, and the currentSongInPlaylist() function.
By calling queue_next_order() before playlist.current is invalidated
(by the deletion of a song), we get more robust results, and the code
becomes a little bit easier. incrPlaylistCurrent() is unused now, and
can be removed.
The function shuffles the virtual order of songs, but does not move
them physically. This is used in random mode.
The new function replaces playlist.c's randomizeOrder() function,
which was aware of playlist.current and playlist.queued. The latter
is always -1 anyway, and the former as preserved by the caller, by
converting playlist.current to a position, and then back to an order
number.
Add a "changed" check to setPlaylistRepeatStatus(): when the new
repeat mode is the same as the old one, don't do anything at all. No
more checks, no "idle" event.
When the random mode is toggled, MPD did not clear the queue. Because
of this, MPD continued with the next (random or non-random) song
according to the previous mode. Clear the queued song to fix that.
The function moveSongInPlaylist() attempted to read the position of
the current song, even if it was -1. Check that first. The same bug
was in shufflePlaylist().
The null plugin synchronizes the playback so it will happen in real
time. This patch adds a configuration option which disables this: the
playback will then be as fast as possible. This can be useful to
profile MPD.
It is possible that playlist.current is reset before the TAG event
handler playlist_tag_event() is called. Convert the assertion into a
run-time check.
Break from the loop instead of returning the function. This calls
player_stop_decoder(), which in turn emits the PLAYLIST event. This
allows the playlist to re-start the player.
Don't attempt to restart the player if it was stopped, but there were
still songs left on the playlist. This looks like it has been a
workaround for a bug which has been fixed long time ago.
The player_thread loop requests the next song from the playlist as
soon as the decoder finishes the song which is currently being played.
This is superfluous, and can lead to synchronization errors and wrong
results. The playlist already knows when the player starts playing
the next song (player_wait_for_decoder() triggers the PLAYLIST event),
and will then trigger the scheduler to provide the next song.
The "TAG" event is emitted by the player thread when the current
song's tag has changed. Split this event from "PLAYLIST" and make it
a separate callback, which is more efficient.
The "sticker" command allows clients to query or manipulate the
sticker database. This patch implements the sub-commands "get" and
"set"; more will follow soon (enumeration), as well as extended
"lsinfo" / "playlistinfo" versions.
When a song is deleted from the database, remove its sticker, too.
What's still missing is some sort of garbage collector after a fresh
database create (--create-db).
"Stickers" are pieces of information attached to existing MPD objects
(e.g. song files, directories, albums). Clients can create arbitrary
name/value pairs. MPD itself does not assume any special meaning in
them.
If a song is not within the music directory ("file:///..."), it has no
"parent directory". The archive code nonetheless dereferences the
parent pointer, causing a segmentation fault. Check parent!=NULL.
One of the previous patches made MPD consume 100% CPU in a busy wait:
when the music_pipe was full, it did not wait (with notify_wait()) for
free chunks, because a variable has a different meaning now. Always
pass "true" as the "wait" parameter.
Some plugins used the APE or ID3 tag loader as a fallback when their
own methods of loading tags did not work. Move this code out of all
decoder plugins, into song_file_update().
This new API gives the caller a writable buffer to the music pipe
chunk. This may allow the caller to eliminate several buffer copies,
because it may manipulate the returned buffer, until it calls
music_pipe_expand().
When libvorbis knows that a song is seekable, it seeks around like
crazy in the file before starting to decode it. This is very
expensive on remote HTTP resources, and delays MPD for 10 or 20
seconds.
This patch disables seeking on remote songs, because the advantages of
quickly playing a song seem to weigh more than the theoretical ability
of seeking for most MPD users. If users feel this feature is needed,
we will make a configuration option for that.
getBoolConfigParam() returns an int. It is not possible to check for
CONF_BOOL_UNSET after it has been assigned to a bool; use a temporary
int value for that.
Calling input_curl_select() after EOF has been reached causes an
assertion failure. This can happen if the HTTP response is empty.
Check c->eof before calling input_curl_select().
Path names in the directory and song structs are always encoded in
UTF-8. Don't use strcmp(), it cannot handle UTF-8 characters
properly. Use GLib's UTF-8 aware g_utf8_collate() function for that.
I was having problems with shoutcast stream outputs before applying
the attached patch, which enlarges the shoutcast output
buffer. Ideally, this should be configurable, but this resolves the
issue for my needs.
vorbis_parse_comment() should be a function which converts one comment
to a tag item. It should do everything required to do the conversion,
including looping over all possible tag types.
mpd uses some additional files to work, such as pid_file, state_file,
db_file, etc. when running mpd as non-root user, it is often that those
files end in ~/.mpd
in that case, we end up with 2 entries in a user's home, .mpdconf and
.mpd - which clutters homedirs.
this patch allows ~/.mpd/mpd.conf as an alternative to ~/.mpdconf,
allowing for a cleaner homedir
If a tag value is an empty string, the space after the colon was
removed by g_strchomp(). Fix this by removing the space check and
using g_strchug() on the return value.
The matchesAnMpdTagItemKey() API becomes more powerful and flexible if
the return value is the value pointer instead of a boolean. It also
removes (invalid and dangerous) assumptions about the string from its
caller.
When a song file is deleted during database update, all pointers to it
must be removed from the playlist. The "for" loop in
deleteASongFromPlaylist() did not deal with multiple copies of the
deleted song properly, and left instances of the (to-be-invalidated)
pointer in. Fix this by reversing the loop.
Added TAG_ITEM_ALBUM_ARTIST.
With this patch, MPD should be able to read the (inofficial)
"ALBUMARTIST" Vorbis comment. Implementations in other decoder
plugins will follow soon.
matchesAnMpdTagItemKey() broke when two tag items had the same prefix,
because it did not check if the tag name ended after the prefix. Add
a check for the colon and the space after the tag name.
If http_proxy_{host, port, user, password} are provided in mpd.conf
they are not passed on to libcurl. As a result mpd cannot stream from
behind an http proxy.
The attached patch `http_proxy.patch` makes the relevant calls to
curl_easy_setopt(...) for all proxy configuration parameters, but is
only tested for host and port.
MPD's shuffling algorithm was not implemented well: it considers songs
which were already swapped, making it somewhat non-random.
Fix the Fisher-Yates shuffle algorithm by passing the proper bounds to
the PRNG.
When decoder_run_song() (decoder_thread.c) waits for the input stream
to become ready, it did that in a busy loop. Add a select() call to
input_curl_buffer() during connect/handshake (i.e. before the first
chunk of body data was received), to let the CPU relax.
MPD will (optionall) use sqlite databases in the future. Add a
configure option to enable that. There is no code yet to really use
sqlite, so the practical use of this patch is limited.
This patch tryes to introduce pluggable mixer (struct mixer_plugin) along with some basic infrastructure (mixer_* functions). Instance of mixer (struct mixer) is used in
alsa and oss output plugin
Loosely based on a patch provided by lesion in bug #1766. The playlistinfo
command can now retrieve ranges of the playlist. The new argument indicates
which entry is the last one that will be displayed. The number of displayed
entries may be smaller than expected if the end of the playlist is reached.
Previous usage:
playlistinfo [start]
New usage:
playlistinfo [start[:end]]
This library allocates temporary buffers for storing PCM conversion
results. It should replace all those "static" buffer variables which
are racy and never freed.
Handle the DELETE and UPDATE events in separate callbacks:
song_delete_event() safely deletes a song, and update_finished_event()
is called when database update is complete.
Don't call command_error() if loading a song from the playlist fails.
This may result in assertion failures, since command_error() may be
called more than once.
Determine the suffix manually, and use decoder_plugin_from_suffix()
and archive_plugin_from_suffix() instead.
This way, song_file_update_inarchive() can be optimized: it does not
have to translate its path.
For internal checks (i.e. not in command.c), we need to check whether
an URI is in the databse, in the local file system or a remote URI
with a scheme.
When the decoder of the new song is not fast enough, the player thread
has to wait for it for a moment. However the variable "nextChunk" was
reset to -1 during that, making the next loop iteration assume that
cross-fading has not begun yet. This patch overwrites it with "0"
while waiting.
This patch fixes a minor memory leak: when decoder_tag() attempted to
send a merged tag object (created by tag_add_stream_tags()), and was
interrupted by a decoder command, it did not free the temporary merged
tag object.
Don't use g_strescape(), because it escapes all non-ASCII characters.
Add a new function which clears all non-printable characters, not just
"newline".
Commit b3e2635a introduced a regression: when a stream tag was
changed, the playlist version had to be updated. This was done in
syncCurrentPlayerDecodeMetadata(), called by syncPlayerAndPlaylist().
After b3e2635a, this was not called anymore. Fix this by emitting
PIPE_EVENT_PLAYLIST.
JACK documentation states: "The caller is responsible for calling
free(3) any non-NULL returned value."
This does not seem to include the array elements. Duplicate them
after jack_get_ports(), and free only the array. Convert
JackData.output_ports to non-const.
There is only one location using PIPE_EVENT_SIGNAL: to synchronize
player_command() with player_command_finished(). Use the "notify"
library instead of the event_pipe here.
event_pipe_emit_fast() is aimed for use in signal handlers: it doesn't
lock the mutex, and doesn't log on error. That makes it potentially
lossy, but for its intended use, that does not matter.
Make the event_pipe (formerly main_notify) send/receive a set of
events, with a callback for each one.
The default event PIPE_EVENT_SIGNAL does not have a callback. It
is still there for waking up the main thread, when it is waiting for
the player thread.
We are going to migrate away from the concept of notifying the main
thread. There should be events sent to it instead. This patch starts
a series to implement that.
With the GLib main loop, the client manager can install its own event
in case a client is expired. No need for main.c to call
client_manager_expire() manually.
The SIGHUP handler was used by the update process to make the main
process re-read the database. We don't need this anymore, since the
update takes place in a thread now.
This is a rather huge patch, which unfortunately cannot be splitted.
Instead of using our custom ioops.h library, convert everything to use
the GLib main loop.
Currently, both sides of the pipe are blocking, although we do not
need blocking read(). Convert it back to blocking. Eliminate the
select() from wait_main_task().
To wake up the main thread, don't attempt to use a GCond/GMutex
(struct notify). This kind of mixed wakeup method has known race
conditions.
The idea behind this patch is: for wakeups which happen while the main
thread is sleeping, use only a pipe. For wakeups which happen while
the main thread is waiting for the player thread, we can later change
to GCond. For now, accept the overhead of using a pipe for the
latter.
In the long run, the main thread will never wait for the player
thread, but will do everything asynchronously.
The new WIN32 version of set_nonblocking() can only deal with sockets,
i.e. it will fail on main_notify.c. On WIN32, we have to reimplement
main_notify.c anyway, so this is not a big deal.
There are no unix sockets on WIN32, and therefore no authentication.
WIN32 might have similar capabilities, but until we implement them,
disable that MPD feature.
On WIN32, parsePath() now simply duplicates the input string. There
is currently nothing special we can do here. The old code was not
portable on WIN32.
I tried to search for a certain composer in my collection, but only
non-mp4 files showed up. The source code reveals that this tag is not
read. This can be fixed by reading the 'Writer' tag field, in
mp4_plugin.c, in function mp4_load_tag.
I actually tried this, and after compiling with those lines added,
also mp4 (.m4a) files showed up when searching for a composer.