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]