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.
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().
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.
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.
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.
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>
The cue sheet embedded in a flac file doen't contain any information
about track titles and similar. There are three possibilities: Use an
external cue sheet that includes these information, use a tag CUESHEET
with a cue sheet including these information or use tags. I think the
latter is the best option and is already used by other projects.
Let's get rid of the "shout" plugin, and the awfully complicated
icecast daemon setup! MPD can do better if it's doing the HTTP server
stuff on its own. This new plugin has several advantages:
- easier to set up - only one daemon, no password settings, no mount
settings
- MPD controls the encoder and thus already knows the packet
boundaries - icecast has to parse them
- MPD doesn't bother to encode data while nobody is listening
This implementation is very experimental (no header parsing, ignores
request URI, no icy-metadata, ...). It should be able to suport
several encoders in parallel in the future (with different bit rates,
different codec, ...), to make MPD the perfect streaming server. Once
MPD gets multi-player support, we can even mount several different
radio stations on one server.
Converted the ogg_page attribute from the vorbis_encoder struct to a
local function of vorbis_encoder_read(). This simplifies some code,
because we don't need to check the page anymore before using it.
Add the "flush" flag, and defer the ogg_stream_flush() call. Call
ogg_stream_pageout() or ogg_stream_flush() (depending on the "flush"
flag) in vorbis_encoder_read(). This prevents the ogg_page from
getting overwritten by consecutive ogg_stream_pageout() calls.