| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
| |
networking, select(), ntohl(), etc.
|
|
|
|
| |
Simplify initialization and finalization.
|
|
|
|
|
|
| |
There are numerous race conditions between the libpulse thread
(pulse_mixer.c callbacks) and the rest of MPD. Protect the volatile
attributes of the pulse_mixer struct with a mutex to fix that.
|
|
|
|
|
| |
Eliminate one indent level. Also remove several debug useless debug
messages.
|
|
|
|
| |
Those parameters are used after all.
|
|
|
|
|
|
| |
Don't mess with pulse_mixer.volume for setting the volume. This
variable should only be used to transfer the current volume from
sink_input_vol() to pulse_mixer_get_volume().
|
|
|
|
|
|
|
|
|
|
| |
The pa_context_get_sink_input_info() function is asynchronous, and
after it returns, libpulse does not guarantee that the operation has
completed yet; in fact, it is not likely. Explicitly wait for the
operation to complete.
The code for the new pulse_wait_for_operation() function was inspired
by mplayer and xine code.
|
|
|
|
|
|
| |
The function mixer_failed() expects the mixer mutex to be already
locked, yet it calls mixer_close(), which attempts to lock the mutex
again, deadlocking itself.
|
|
|
|
|
| |
When single mode is enabled, after current song it stops playback,
or it replay same song if repeat mode is activated.
|
|
|
|
|
|
|
|
|
| |
The smartstop feature is a way to tell mpd to stop playing after
current song.
This patche provides:
- 'state' command returns 'smartstop' state (1 or 0)
- 'smartstop' can activate or not the smartstop state
- when song is terminated, mpd stops playing and smartstop is set to 0
|
|
|
|
| |
Use the same code style as the rest of MPD.
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
The functions playPlaylist() and seekSongInPlaylist() expect a song
position, not a song order number. Don't convert the "current"
variable with queue_position_to_order().
|
|
|
|
|
|
|
|
|
|
|
| |
The move command now accepts a range for the first argument, in the same
form as other range commands, e.g. move 15:17 3. The first song in the
range is placed at the destination position. Note that as with other
range commands, the range is inclusive on the left only; this example
would move only songs 15 and 16, not 17.
[mk: fixed signed/unsigned warnings; use G_MAXUINT instead of
UINT_MAX]
|
|
|
|
|
|
| |
Don't initialize attributes which are only used in an open mixer. As
long as nobody accesses them, their values are uninitialized and
undefined.
|
|
|
|
|
|
|
| |
The pm->volume attribute was allocated in pulse_mixer_init(), but is
never freed. This leaks memory. Instead of adding the g_free() call
to pulse_mixer_finish(), let's just make "volume" a static attribute
of the pulse_mixer struct. That is easier to deal with.
|
|
|
|
|
| |
When the MPD core knows that the pulse mixer is open, pm->mainloop and
pm->context must be non-NULL.
|
|
|
|
|
| |
The attributes "online" and "index" were not properly reinitialized
after a close/open cycle.
|
|
|
|
|
|
| |
Nobody needs to modify these strings. We can make them const, and
convert config_dup_block_string() to config_get_block_string(). This
also fixes memory leaks in the pulse mixer.
|
|
|
|
|
| |
The conf.h functions deal well with config_param==NULL and will return
the specified default value then.
|
|
|
|
|
| |
When the mixer initialization fails, we have to free the libpulse
objects we have already created, to prevent resource leaks.
|
|
|
|
|
| |
It's illegal to return from pulse_mixer_setup() without unlocking the
main loop. In the error handling, that unlock() call was missing.
|
|
|
|
| |
Prepare for adding proper error handling.
|
|
|
|
|
|
| |
"volume_set" is an attribute which becomes undefined when the mixer is
closed. That means, it must be initialized each time the mixer is
opened.
|
|
|
|
|
|
| |
The MPD core guarantees that methods are always invoked in a
consistent state. This means we can remove lots of checks from the
volume methods.
|
|
|
|
|
| |
Instead of replacing NULL with the default device in the open()
method, pass the default device to config_get_block_string().
|
|
|
|
| |
Use config_get_block_string() instead of config_dup_block_string().
|
|
|
|
| |
Detect misconfiguration during MPD startup.
|
|
|
|
|
|
| |
The MPD core guarantees that methods are always invoked in a
consistent state. This means we can remove lots of checks from the
volume methods.
|
|
|
|
| |
strncasecmp() is locale dependent, but we only need ASCII here.
|
|
|
|
|
| |
Instead of replacing NULL with the default path in the open() method,
pass the default path to config_get_block_string().
|
|
|
|
| |
Use config_get_block_string() instead of config_dup_block_string().
|
|
|
|
|
|
| |
If a (global) mixer has been closed due to failure, don't reopen it
with every volume get/set. Leave it closed until it is explicitly
opened.
|
|
|
|
|
| |
When getting or setting the volume fails, the MPD core close the
mixer. Moved the duplicated code from the mixer plugins.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Remember if a mixer object is open or closed. Don't call open() again
if it is already open. This guarantees that the mixer plugin is
always called in a consistent state, and we will be able to remove
lots of checks from the implementations.
To support mixers which are automatically opened even if the audio
output is still closed (to set the volume before playback starts),
this patch also adds the "global" flag to the mixer_plugin struct.
Both ALSA and OSS set this flag, while PULSE does not.
|
|
|
|
|
|
| |
As a side effect, the previous patch added the mixer==NULL checks. It
is now illegal to call mixer functions with a NULL argument. Convert
the runtime checks to assertions.
|
|
|
|
|
|
| |
The mixer core library is now responsible for creating and managing
the mixer object. This removes duplicated code from the output
plugins.
|
|
|
|
|
|
|
| |
When the decoder initialization has not been completed yet, all calls
to dc_seek() will fail, because dc.seekable is not initialized yet.
Wait for the decoder to complete its initialization, i.e. until it has
called decoder_initialized().
|
|
|
|
|
|
|
|
|
|
|
| |
Don't start playback as soon as the "current" song is being loaded
from the state file. That is unclean, and leads to an obscure bug: in
repeat mode, when the song is started (which is yet the last song in
the list), the playlist code marked the very first song in the
playlist as "next" song, because the end of the playlist was wrapped.
It's easier to set up the playback after all songs have been loaded,
and after the random/repeat mode has been set.
|
|
|
|
|
|
| |
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().
|
|
|
|
|
|
| |
Synchronization with the output thread will be implemented in
output_all.c, not in player_thread.c. Currently, that's just a simple
g_usleep(1ms).
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
| |
To prevent a race condition, close the output thread before assigning
the new audio format.
|
|
|
|
|
|
|
| |
The config_audio_format used to contain the configured audio format,
which is copied to out_audio_format. Let's convert the former to a
boolean, which indicates whether out_audio_format was already set.
This simplifies some code and saves a few bytes.
|
| |
|
|
|
|
|
| |
If a music_chunk does not contain any PCM data, then the "times" and
"bit_rate" attributes are undefined.
|
|
|
|
|
|
|
|
|
|
|
|
| |
On 2009/03/17 Max Kellermann<max@duempel.org> wrote:
> There doesn't seem to be an "official" standard. I'd say: search for
> TITLE[1] first (the most explicit form), then TITLE1, and finally fall
> back to TITLE. This makes sure MPD supports every possible standard,
> without breaking.
I've also added some additional checks to make sure entry is long
enough.
|
|
|
|
|
|
| |
The mixer state is defined as offline only if the associated stream is removed.
Signed-off-by: David Guibert <david.guibert@gmail.com>
|
|
|
|
|
|
|
|
|
| |
when the mixer is closed,
- the mainloop is stopped.
- the context is disconnected.
- then the mainloop is freed.
Signed-off-by: David Guibert <david.guibert@gmail.com>
|