| Commit message (Collapse) | Author | Files | Lines |
|
During the whole output thread, the audio_output object is locked, and
it is only unlocked while waiting for the GCond and while running a
plugin method. The error handler in ao_play_chunk() attempted to lock
the object again, which was code from MPD 0.15.x which should have
been removed a long time ago.
|
|
|
|
This method is used to reduce the delay of commands issued to the
shout plugin.
|
|
Change the assertion on "fail_timer==NULL" in OPEN to a runtime check.
This assertion crashed when the output thread failed while the player
thread was calling audio_output_open().
|
|
|
|
Replaced all occurrences of g_error() with MPD_ERROR() located in a new header
file 'mpd_error.h'. This macro uses g_critical() to print the error message
and then exits gracefully in contrast to g_error() which would internally call
abort() to produce a core dump.
The macro name is distinctive and allows to find all places with dubious error
handling. The long-term goal is to get rid of MPD_ERROR() altogether. To
facilitate the eventual removal of this macro it was added in a new header
file rather than to an existing header file.
This fixes #2995 and #3007.
|
|
Clear the notification before finishing the CANCEL command, so the
notify_wait() after that will always wait for the right notification,
sent by audio_output_all_cancel().
|
|
Don't add it to the filter chain, because we need to apply replay gain
before cross-fading with the next song. Add a second replay_gain
filter which is used for the song being faded in (chunk->other).
|
|
Remove cross_fade_apply(), and call pcm_mix() in the output thread,
mixing the chunk and chunk->other together.
|
|
|
|
|
|
Add an option for each audio output which enables the use of the
hardware mixer, instead of the software volume code.
This is hardware specific, and assumes linear volume control. This is
not the case for hardware mixers which were tested, making this patch
somewhat useless, but we will use it to experiment with the settings,
to find a good solution.
|
|
Apply the replay gain in the output thread. This means a new setting
will be active instantly, without going through the whole music pipe.
And we might have different replay gain settings for each audio output
device.
|
|
|
|
Unified function for converting an audio_format object to a string,
for log messages and for the "status" command.
|
|
After we've been hit by Large File Support problems several times in
the past week (which only occur on 32 bit platforms, which I don't
have), this is yet another attempt to fix the issue.
|
|
This command manually drains the hardware buffer. This is useful when
the player thread want to make sure that everything has been played.
|
|
|
|
When the "next" chunk to be played is NULL, return from ao_play()
immediately, without going over the "while" loop (no-op).
|
|
After CANCEL, call g_cond_wait() only if the new command is still
NONE. Problem is that ao_command_finished() has to unlock the
audio_output object, and in the meantime, the player thread might have
submitted a new command.
|
|
Use GMutex/GCond instead of the notify library. Manually lock the
player_control object before accessing the protected attributes. Use
the GCond object to notify the player thread and the main thread.
|
|
Return false when there was no chunk in the pipe. If the function
returns true, then audio_output_task() will not wait for a notify from
the player thread. This fixes a race condition.
|
|
Always keep the audio_output object locked within the output thread,
unless a plugin method is called. This fixes several race conditions.
|
|
drain() is the opposite of cancel(): it waits until all data in the
buffer has finished playing. Instead of implicitly draining in the
close() method like the ALSA plugin has been doing it forever, let the
output thread decide whether to drain or to cancel.
|
|
Don't call filter_close() right after ao_close().
|
|
With these methods, an output plugin can allocate some global
resources only if it is actually enabled. The method enable() is
called after daemonization, which allows for more sophisticated
resource allocation during that method.
|
|
An asterisk means that this attribute should not be enforced, and
stays whatever it used to be. This way, some configuration values
work like masks.
|
|
This allows more sophisticated audio format selection.
|
|
Basically the same as the 0.15.5 patch "check again if output is open
on CANCEL". Same race condition, same fix.
|
|
When the player thread unpauses, it sends CANCEL to the output thread,
after having checked that the output is still open. Problem is when
the output thread closes the device before it can process the CANCEL
command - race condition. This patch adds another "open" check inside
the output thread.
|
|
Explicitly make the output thread leave the ao_pause() loop. This
patch is a workaround, and the "pause" flag is not managed in a
thread-safe way, but that's good enough for now.
|
|
|
|
This patch adds initial filter support for audio outputs. Each audio
output gets a "filter" attribute, which is used by ao_play_chunk().
The PCM conversion is now performed by convert_filter_plugin.
audio_output.convert_state has been removed.
|
|
REOPEN is called when the input audio format changes. The output
thread may be reconfigure the PCM converter.
|
|
|
|
When the PAUSE loop ends, re-check the next command before calling
ao_play() again.
|
|
This patch fixes a longer delay when moving around songs in the
playlist. The main thread wants to enqueue a new "next" song into the
player thread, but the player thread is waiting inside
audio_output_all_wait() for the output threads. Use
player_control.notify there, so audio_output_all_wait() gets woken up
by the main thread, too.
|
|
Use audio_output_client_notify instead of g_usleep(1ms) in
audio_output_all_wait() to synchronize with the output_thread. Signal
the audio_output_client_notify object in ao_play().
|
|
There was a deadlock between the output thread and the player thread:
when the output thread failed (and closed itself) while the player
thread worked with the audio_output object, MPD could crash.
|
|
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.
|
|
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.
|
|
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.
|
|
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().
|
|
|
|
To aid debugging, print the audio format of the output plugin in a
debug message, and print information about PCM conversion.
|
|
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.
|
|
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.
|
|
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 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.
|